The Now Platform® Washington DC release is live. Watch now!
on 11-01-2020 10:01 PM
Hi there,
If you are an admin or Virtual Agent admin, you can use variables to customize the behavior of Virtual Agent Topics. On the ServiceNow Docs only a few of these variables are described. You might already have come across some of these while exploring the out-of-the-box Virtual Agent Topics or the Community, though there are lots more!
I'll sum up, which variables and undocumented variables I've come across so far. You will also see some of these used in the Virtual Agent Topic Block articles and share downloads which I'm publishing.
Note: Some of these undocumented variables are very useful, though some might also be unsupported!
User input variables (vaInputs)
vaInputs.user | Provides the display value of the logged-in user's User record. It is possible to apply dotwalking, like "vaInputs.user.first_name". Example output: "mark.roethof" |
Script variables (vaVars)
vaVars._interaction_record_sysid | Provides the Sys ID of the Interaction which is created automatically and associated with the chat. Example output: "3127a4802f90a050b0c2d5ea2799b690" |
vaVars._liveagent_disabled_msg | Same as vaVars._liveagent_handoff_error_msg. Provides the error message which is shown when there are no agent available. Example output: "There are no agents available at the moment. Please try again later." |
vaVars._liveagent_handoff_error_msg | Same as vaVars._liveagent_disabled_msg. Provides the error message which is shown when there are no agent available. Example output: "There are no agents available at the moment. Please try again later." |
vaVars._setup_anything_else_topic | Provides the Topic name of the Anything else topic as mentioned in the "Virtual Agent > General Settings > Setup Topics". Example output: "Anything Else Topic." |
vaVars._setup_closing_topic | Provides the Topic name of the Closing topic as mentioned in the "Virtual Agent > General Settings > Setup Topics". Example output: "Closing conversation." |
vaVars._setup_error_topic | Provides the Topic name of the Error topic as mentioned in the "Virtual Agent > General Settings > Setup Topics". Example output: "Error Handling Topic." |
vaVars._setup_explore_help_topic | Provides the Topic name of the Explore help topic as mentioned in the "Virtual Agent > General Settings > Setup Topics". Example output: "Virtual Agent Capabilities." |
vaVars._setup_fallback_topic | Provides the Topic name of the Fallback topic as mentioned in the "Virtual Agent > General Settings > Setup Topics". Example output: "Fallback Topic." |
vaVars._setup_survey_topic | Provides the Topic name of the Survey topic as mentioned in the "Virtual Agent > General Settings > Setup Topics". Example output: "Virtual Agent Feedback." |
vaVars._setup_welcome_topic | Provides the Topic name of the Greeting topic as mentioned in the "Virtual Agent > General Settings > Setup Topics". Example output: "Dynamic Greeting Topic." |
vaVars._topic_choice_list_msg | Provides the value of System Property "com.glide.cs.topic_choice_list_message". My advice would be to NOT alter the value of this System Property when working on a Multi-language instance. Update the Message of the corresponding UI Message instead. Example output: "I want to be sure I got this right. What item best describes what you want to do?" |
vaVars._topic_current | Same as vaVars._topic_results. Provides details of the current Topic the conversation is in, in JSON format. Details like the Sys ID of the current Topic, Sys ID of the Conversation Task, name of the current Topic. Example output: "{"sys_id":"5e85248c2f50a050b0c2d5ea2799b6b4", "task":"f327e4802f90a050b0c2d5ea2799b63d", "entities":null, "modelId":null, "name":"Test Topic", "prediction":null, "title":"Test Topic", "type":"normal", "utterance":"test topic"}" |
vaVars._topic_not_found_msg | Provides the value of System Property "com.glide.cs.no_topic_found_message". My advice would be to NOT alter the value of this System Property when working on a Multi-language instance. Update the Message of the corresponding UI Message instead. Example output: "Please try giving me your request in a different way. I'm currently better at understanding short sentences." |
vaVars._topic_postchat_user_id | Provides the display value of the logged-in user's User record. Unlike the vaInputs.user, it is NOT possible to apply dotwalking. Example output: "mark.roethof" |
vaVars._topic_results | Same as vaVars._topic_current. Provides details of the current Topic the conversation is in, in JSON format. Details like the Sys ID of the current Topic, Sys ID of the Conversation Task, name of the current Topic. Example output: "{"sys_id":"5e85248c2f50a050b0c2d5ea2799b6b4", "task":"f327e4802f90a050b0c2d5ea2799b63d", "entities":null, "modelId":null, "name":"Test Topic", "prediction":null, "title":"Test Topic", "type":"normal", "utterance":"test topic"}" |
vaVars._topic_sorry_msg | Provides the value of System Property "com.glide.cs.no_topic_sorry_message". My advice would be to NOT alter the value of this System Property when working on a Multi-language instance. Update the Message of the corresponding UI Message instead. Example output: "I am sorry but I didn't understand your request." |
vaVars._topic_sth_else_option | Provides the value of System Property "com.glide.cs.want_something_else_option". My advice would be to NOT alter the value of this System Property when working on a Multi-language instance. Update the Message of the corresponding UI Message instead. Example output: "I want something else" |
vaVars._topic_strategy | No clue yet. Found this Script variable within one of the out-of-the-box Topics, which proves a value of "sure". |
vaVars._topic_wrong_msg | Provides the value of System Property "com.glide.cs.wrong_topic_message". My advice would be to NOT alter the value of this System Property when working on a Multi-language instance. Update the Message of the corresponding UI Message instead. Example output: "No problem, let's try again. Select one that matches what you want to do." |
vaVars.global_client_mode | No clue yet. Found this Script variable within one of the out-of-the-box Topics, which proves a value of "NORMAL". |
Context variables (vaContext)
vaContext.deviceTimeZone | Same as vaContext.getDeviceTimeZone(). Provides the timezone from the Device on which the logged-in user is working. So the timezone from the laptop or mobile phone for example. This is NOT the timezone value of the logged-in user's User record. Example output: "Europe/Amsterdam" |
vaContext.deviceType | Provides the type of Device on which the logged-in user is working. Example output: "mweb", "ios", "android" |
vaContext.getDeviceTimeZone() | Same as vaContext.deviceTimeZone. Provides the timezone from the Device on which the logged-in user is working. So the timezone from the laptop or mobile phone for example. This is NOT the timezone value of the logged-in user's User record. Example output: "Europe/Amsterdam" |
vaContext.getRequesterLang() | Provides the value of the Language field of the logged-in user's User record. Example output: "en" |
vaContext.portal | Provides the Portal suffix. This Context variables only works instantly when using Service Portal Agent Chat Configuration. If using legacy methods (like embedding the Service Portal widget to the header or footer), this would only work when adding sysparm_portal to the URL. Example output: "sp" |
Below variables can be found in one of more out-of-the-box Topics. Unfortunately, so far I did not get these variables mentioned working.
vaContext.case_sys_id
vaContext.case_number
vaContext.task_number
vaContext.task_tablename
vaContext.parent_case_sys_id
vaContext.providerAppId
vaContext.providerUserId
vaContext.providerUserName
vaContext.task_sys_id
System Variables (vaSystem)
vaSystem.attachRecordToConversation() | From the Docs: "This method attaches ServiceNow records that are updated or created during a Virtual Agent conversation to the Related Tasks list in a Virtual Agent interaction record." Example usage: "vaSystem.attachRecordToConversation('incident', 'f327e4802f90a050b0c2d5ea2788b63d')" |
vaSystem.attachToRecord() | From the Docs: "This method attaches an uploaded image to a ServiceNow record." Example usage: "vaSystem.attachToRecord(vaInputs.file_picker.getValue(), 'incident', 'f327e4802f90a050b0c2d5ea2788b63d')" |
vaSystem.connectToAgent() | From the Docs: "This method connects the customer to a live agent." |
vaSystem.getClosingMessage() | Same as vaSystem.sendSeparatorMessage(). Provides the value of System Property "com.glide.cs.general.closing_message". My advice would be to NOT alter the value of this System Property when working on a Multi-language instance. Update the Message of the corresponding UI Message instead. Example output: "Thank you for using our support chat." |
vaSystem.getConversationId() | Provides the Sys ID of the Conversation record which is created automatically. Example output: "32dbbc9a2f1ce850b0c2d5ea2799b68d" |
vaSystem.getGreetingMessage() | Same as vaSystem.sendSystemMessage(). Provides the message of UI Message with key "Hi, I'm your Virtual Agent. Let me know how I can help you today.". Example output: "Hi, I'm your Virtual Agent. Let me know how I can help you today." |
vaSystem.getSearchText() | From the Docs: "This method returns the last utterance typed by the user and is used to find the current topic." Example output: "My mouse isn't working anymore." |
vaSystem.getSurveyVerificationMessage() | Provides the value of System Property "com.glide.cs.general.chat_survey_verification_message". My advice would be to NOT alter the value of this System Property when working on a Multi-language instance. Update the Message of the corresponding UI Message instead. Example output: "Is the summary accurate?" |
vaSystem.getTopicSelectionMessage() | Provides the message of UI Message with key "What's your issue or request? Or take a look at what I can help with.". Example output: "What's your issue or request? Or take a look at what I can help with." |
vaSystem.getTranscript() | Provides the contents of the full current conversation up to that point. Example output: "[07:30] Virtual Agent: G'day Mark. [07:30] Virtual Agent: Let me know how I can help you today. What's your issue or request? Or take a look at what I can help with. [07:30] Virtual Agent: Show Me Everything [07:30] Mark Roethof (SysAdmin): Test Topic [07:30] Virtual Agent: Test Topic" |
vaSystem.getTranslation() | Provides the value of the matching Translated Text record corresponding the Language given. The first parameter concerns the GlideRecord object, the second parameter concerns the Fieldname value, the third parameter concerns the Language value for the translation to retrieve, the fourth parameter concerns the Field of the GlideRecord object which needs to be translated against the Translated Tekst. Example usage: "vaSystem.getTranslation(gr, 'question', 'nl', gr.question)" |
vaSystem.isAllowTranscriptDownload() | Provides a boolean value which corresponds with the value of checkbox Allow Transcript Download on the Chat Setup record. Example output: "true" or "false" |
vaSystem.isLiveAgentAvailable() | From the Docs: "This method checks whether a live agent is available to receive a conversation (transferred from the bot)." Example output: "true" or "false" |
vaSystem.sendSeparatorMessage() | Same as vaSystem.getClosingMessage(). Provides the value of System Property "com.glide.cs.general.closing_message". My advice would be to NOT alter the value of this System Property when working on a Multi-language instance. Update the Message of the corresponding UI Message instead. Example output: "Thank you for using our support chat." |
vaSystem.sendSystemMessage() | Same as vaSystem.getGreetingMessage(). Provides the message of UI Message with key "Hi, I'm your Virtual Agent. Let me know how I can help you today.". Example output: "Hi, I'm your Virtual Agent. Let me know how I can help you today." |
vaSystem.sendTopicPickerControl() | This Script variables provides the logged-in user with a list of available Topics. Usage of this Script variable is required if willing to work with utterances. Example usage: "var greetingMessage = vaSystem.getTopicSelectionMessage(); vaSystem.sendTopicPickerControl(greetingMessage);" |
vaSystem.switchTopic() | Can be used to switch to another Topic. After completion of the Topic switched to, the conversation returns to the Topic switched from. Example usage: "vaSystem.switchTopic('Topic Name to Switch to');" |
vaSystem.topicDiscovery() | Can be used to discover and switch to another Topic. After completion of the Topic switched to, the conversation returns to the Topic switched from. Example usage: "vaVars.global_search_text = 'Topic Name to Switch to'; vaSystem.topicDiscovery();" |
Below variables can be found in one or more out-of-the-box Topics. Unfortunately, so far I did not get these variables mentioned working.
vaSystem._topic_current
vaSystem.endConversation()
vaSystem.portal
---
And that's it actually. Hope you like it. If any questions or remarks, let me know!
If this post helped you in any way, I would appreciate it if you hit bookmark or mark it as helpful. Interested in more articles, blogs, videos, and Share projects on Virtual Agent I published? - Virtual Agent |
Kind regards,
Mark
2020 ServiceNow Community MVP
2020 ServiceNow Developer MVP
---
Nice Article. Thanks for putting all these together.
Best,
Eric
Started doing this in my own notes so has just saved me a few hours of my life.
Thank you.
Just updated the article a bit with some new found properties. It's now 50+ variables described.
Kind regards,
Mark
2020 ServiceNow Community MVP
2020 ServiceNow Developer MVP
---
Hi
vaSystem.isLiveAgentAvailable() | From the Docs: "This method checks whether a live agent is available to receive a conversation (transferred from the bot)." Example output: "true" or "false" |
Hi Eric,
Don't think this is queue specific, and don't know if you could add a parm for this. I used .isLiveAgentAvailable recently at a customer, though just for checking the Live Agent in general.
Kind regards,
Mark
2020 ServiceNow Community MVP
2020 ServiceNow Developer MVP
---
thanks - i'll test it with my team and see what the results look like
To answer your question briefly: yes, it works that way.
This is way I gather isLiveAgentAvailable() works - from some experience and some educated conjecture:
Connect Support
Remember for Connect Support, you need to effectively hardcode the queue (sys_id) in the topic
Basic schedule check: Is the current time within the queue's defined Schedule? T/F
Agent Chat
Remember Agent Chat uses Advanced Work Assignment for routing, so it follows that logic/rules: Channel (Chat) > Queues > Condition > Availability. And you do not (need to) hardcode the queue in the topic.
We haven't done any advanced AWA routing yet - we just have a few queues which are topic-specific so I have them "hardcoded" (interaction context.queue = "[friendly queue name]"), so in our case effectively replicating Connect Support, only one queue will ever match the basic condition, but if you have multiple potential queues matching conditions, it definitely should be smart enough to go through them all - that's the point of AWA.
I'll test this out at some point (low priority), but off-hand, does anybody know if vaContext.deviceType is the way to differentiate MS Teams chats (from Portal chats)?
vaContext.deviceType | Provides the type of Device on which the logged-in user is working. Example output: "mweb", "ios", "android" |
Guessing it is, just because the column in the Conversation table is also called "Device Type" and returns "Microsoft Teams", but it just wasn't in the example.
Fwiw, my use case is this: If Portal, I want to add a note to tell users to use the normal non-VA search to find catalog items because it's a stupid waste of their time to use VA to replicate a (poor) catalog search. Note: Our items are too complex to order natively via VA so that's out of the question. If Teams, well, then the OOTB Order Something topic makes sense as-is and actually saves time 😉
Chris, We tested this the other other day with some advanced AWA configure. it works pretty good to check availability within the VA before giving them the option to transfer to a live agent.
Thanks for mapping out the logic.
Anyone know if a option exists to check availability and the wait time if they are available? I would like to say something like " would you like to connect to a live agent? Current wait time is 1 min. Yes, No or be smarter about it " its looks like the agent is available but the wait time is long. would you like to create a incident instead?"
Eric
Ideally/simply/OOTB, no, I don't think so... But thinking somewhat creatively, I haven't tested this (yet), but I think something like this should work - at least for very simple use cases:
ServiceNow should definitely have a better, more native way for VA to handle wait times, but understandably, some things about it are tricky. Your last bit, "its looks like the agent is available but the wait time is long", just isn't possible I don't think. Looking at agent availability (which includes capacity) is the best this system can do. How could it know that an agent is available but not actually able to take the chat? This is why you configure the backstops like Capacity, Reassign on Timeout, multiple Assignment Eligibilities, and/or Max Wait Time.
Thanks Chris. I think the Max wait time works like you mentioned it above. i tested it awhile back. it ends up with a bad user experience. we looked into it since we wanted it return to the VA after and give them a option to create a incident once the max timeout is hit. We end up putting in a HI ticket just to make sure we didn't miss anything. no option to return to the VA
Given how complex our AWA queue setup is i'll have to live without trying to tell the customer what the current wait time is before selection to transfer to a agent.
Happy Holidays!
The best Article for VA!
We were recently advised to use vaSystem.didConnectToLiveAgent() to determine whether a conversation was directed to a live agent, but the behavior is odd - it seems to depend on whether or not you use the vertical ellipse to connect, or an actual topic flow? More to come if I figure it out 🙂
Just to confirm, finally putting this to use, and yes, as I expected, it does identify Teams users (and almost certainly Slack as well).
If you need to identify Teams users in a topic, you use:
if(vaContext.deviceType == 'teams')
Eric,
There is an OOB topic block called Agent Availability that performs this check and provides the outputs below. Below is the script in that topic block.
Thanks Travis. We noticed the new add in the Quebec release. thanks for telling everyone about it
How to use vaVars._topic_current if it is a custom variable instead of a system variable?
Thanks !
Awesome post!!
I'm not having much luck with what I'm trying to accomplish, but I think I'm close. There is a script in OOB topic Search KB that has variable vaInputs.portal. I can just change the script and hard-code the portal and the links work as expected, but I feel like this isn't the best practice. Any thoughts on the proper way to update that variable correctly without hard-coding it?
Also, just a heads up, the docs link has changed and the one in your original post re-directs to a landing page. Do you mind updating it?
https://docs.servicenow.com/bundle/paris-now-intelligence/page/administer/virtual-agent/concept/virtual-agent-scripts.html
Tnx. Updated the URL.
Can you post your question as a new Topic within the Virtual Agent, Natural Language Understanding (NLU) community? More people will spot your question that way, and you more likely to get an answer. Of course if I have time somewhere today, I will look into it also if no one else answered already.
Kind regards,
Mark
Is there any context variable that will help me to identify the channel type?
Channel type? You mean the device/app used?
vaContext.deviceType | Provides the type of Device on which the logged-in user is working. Example output: "mweb", "ios", "android" |
Somewhat of a misnomer, but I think this is what you're looking for. I've confirmed it works for identifying Teams users - so I'm confident it'd also differentiate for Slack, FB Messenger, and SMS (I think that covers pretty much them all?). mweb = Web Client (i.e. Portal in Browser), iOS/Android = iOS/Android ServiceNow App, etc.
We listened, and we've expanded our documentation to include many of the vaSystem methods mentioned here. Check it out: https://docs.servicenow.com/bundle/sandiego-servicenow-platform/page/administer/virtual-agent/concep...
vaSystem.topicDiscovery() is not the most efficient way to switch topics since it's actually doing topic discovery which is more like a search. Some customers do this because it also enables the "X" button to close the conversation. However, it would be better to use either vaSystem.switchTopicByName() or vaSystem.switchTopicById() which switch to the topic directly and also enable the "X" button.
Very true. For a short period of time, switchTopic() was the only option, then ServiceNow "broke" it, and topicDiscovery() became the go-to to topic switching - when this post was created (ah yes, it is labeled Paris) - and in Quebec they finally released the gold standard switchTopicByID() - and switchTopicByName (but why use a name when you can use a sys_id??).
Thanks to the ServiceNow VA team for picking up what Mark started here and formally documenting a lot more than before.
Does anybody know from where is system populating properties like vaContext.task_sys_id or vaContext.case_sys_id?
This Article was helpful. But can you pleas tell me on how to use VaContext.portal in a portal which is configured in the Legacy manner. I did try by puuting the script in the Topic condition but the log for VaContext.portal returns undefined. Any help would be appreciated. Please find the script below:
WOW, Best thing I read today, Thanks for sharing .
Hi all,
If the chat request is routing and no agent accepts the chat then after time out chat just closes with the closing message. In this case we would like to give create INC option to end users. I tried with multiple ways but no luck yet. Is anyone have already worked on this case or have any idea to implement this.
@Vaish3 If I were to implement this, I guess I would modify the the "Closing Conversation" setup topic. In that customized topic, you could check vaSystem.liveSupportRequestAbandoned(). If true, you could create a path that prompts to create an incident before closing the conversation.
Hi @Kristopfer ,
Thanks for your help it worked.
I need one more help:
We have two live agent queues and incidents created for these queues should route to respective assignment group. I'm just stuck here to check from which queue this closing conversation is entering in.
Is there a way? to check that.
For example, to check current topic name we can use
Can anyone please help me with above use case. That is how I will get to know from which live agent topic closing conversation has entered.
@Vaishnavi25 Unless I'm missing something, the topic name wouldn't help you decide who should receive the incident. As far as I know, we don't keep track of the queue that *would* have been assigned if connecting to an agent fails. If you have some logic that is used to determine the queue (often rules or scripts on the AWA queue), I would suggest possibly encapsulating this logic in a script include, which you could then call from the closing conversation topic to simulate that process.
@Mark Roethof Thanks for sharing, Much appreciated!
Thanks for your Response. As it needs some more Gliding to avoid any breakage client have agreed not to proceed with it. They are ready to Add assignment group manually in above case.
Recently when we went live, we saw a weird behavior. In DEV everything is working as expected but in TEST and PROD whenever no agents are active it gives options to end users to create a ticket. In this case if they create ticket, it is getting created but after that we are seeing this message "I'm having technical issues and won't be able to continue this conversation." And if they don't create then also same error and in this both the cases chat is getting "Closed Abandoned".
I make sure topics are active and also made some changes and published all the topics in DEV, captured it in update set and moved it to TEST but still no luck. I'm I missing anything here?
It shouldn't be related to my changes/implementation because in DEV everything is perfect. @Kristopfer Can you please help me here. By any chance did Flow changes don't capture in update set which cause such issues in Higher Environments?
Regards,
Vaishnavi
@Vaishnavi25 So, the "technical issues" message is sort of an indication that there are bigger problems. I would check the syslog and/or node logs as there is likely an underlying exception associated. I would search for exceptions that include the sys_id of your sys_cs_conversation record for the conversation in error. If that doesn't give you a clue as to the problem, I would open a case so someone can help you more directly.
Has anyone utilised the variable vaVars.global_notification_context.
I see this one in OOTB topics seems like it is a JSON which would contain the record that the notification is triggered by.
Looking to use this one to retrieve the notification record. For a proactive help implementation we are looking into.
Do you know which script we can use to make a topic viewable if users are in a specific sys_user_group?
@Keszia you don't need any of these VA-specific variables and functions, just the common GlideUser function isMemberOf().
You'd put this script in the Topic's Properties > Advanced > Context > Script:
(function execute() {
//using the ootb code example:
var answer=false;
if (gs.getUser().isMemberOf('[sys_id]')) {
answer = true;
}
return answer;
//or you can just simplify it with one line :)
return gs.getUser().isMemberOf('[sys_id]');
})()
Thanks @Chris D but that doesn't seem to work, when I impersonate a user in that group, the topic is hidden.
Hello,
I have a requirement where i want to trigger topic discovery i.e. to trigger NLU once user types their query. But here, requirement is when user types a query, it should trigger NLU for only specific 1 topic and if it returns true i.e. if keyword is matching with utterances for that topic, then return true or else trigger AI Search topic to give KAs and request forms.
I am aware we have "vaSystem.topicDiscovery()" to trigger NLU but it will trigger all active topics and tries to match those utterances. Can we limit it to trigger only for one intent?
Can anyone help on this pls?
Thanks