Context Variables
Disclaimer
This is legacy documentation kept in place for a very specific audience. Please do not use these docs if you don't know the ins and outs of the Scripted Chatbot.
The newest version of the documentation can be found on Guru.
Deep dive
This documentation provides all information that is needed to use the context variables functionality within the CM.com Chatbot.
What are context variables?
'Normal' variables are used as a store for information: you put a certain value in and are able to retreive it at a later time.
Context variables extend these variables with the following options on save:
Save option | Accessibility | Scope |
---|---|---|
Until the end of the conversation | Only within the session | Session |
For all future conversations | Across sessions for a particular chat | Chat |
Shared between conversations | Across all chats | Shared |
The option you choose has impact on the amount of time the information stored in that variable will be available. It's linked to the accessibility of that variable too, also denoted by the scope.
Use cases
In most cases storing a variable until the end of the conversation (session scope) will suffice. An example of this is saving an option the user has chosen in order to determine what further part of the script needs to be run. This option can differ from session to session and should therefor only exist in one session.
When you want information to be available after the session is over you'd opt to save the variable for all future conversations (chat scope). A use case for this is asking the user for their name and starting every subsequent session by personally welcoming them.
In case you want to make information available more publicly you can opt for a variable that's shared between conversations (shared scope). This means you'll be able to read from and write to that variable as long as you know its identifier. A use case for this would be a pizza company which lets a group of friends order their pizza's via the bot. By using a unique order number everyone can add their pizza of choice to the order. (See the Pizza bot deep-dive for a more in-depth explanation)
How to use context within the chatbot script
Creating context variables
Context variables can be created in the following steps:
Input step

Save input from a user
Variable step

Save a specified value under a specified name
Web request step

Save information that's extracted from the response
Entry step
Save information from the capture groups in the catch regex, as described in the Bot Script Specification

Read context
The following feature matrix shows you where context variables can be read:
Step | Read Support |
---|---|
Entry | x |
Text | √ |
Input | |
variable name | x |
timeout | √ |
Media | |
name | √ |
url | √ |
Logic | |
variable | √ |
equals tests | x |
regex tests | x |
starts with tests | x |
CDP event | √ |
Web Request | |
method | √ |
url | √ |
retry amount | x |
retry delay | x |
body | √ |
header key | x |
header value | √ |
query parameter key | x |
query parameter value | √ |
response extraction variable | x |
response extraction selector | x |
Listpicker | |
title | √ |
subtitle | √ |
media url | √ |
option label | √ |
option media url | √ |
Apple Pay | |
merchant name | √ |
order reference | √ |
description | √ |
recipient email | √ |
currency code | √ |
recipient country code | √ |
language country code | √ |
line item label | x |
line item type | x |
line item amount | x |
Text With Url | |
message | √ |
url | √ |
url label | √ |
media name | √ |
media url | √ |
Set Variable | |
key | x |
variable | √ |
Location | |
label | √ |
latitude | √ |
longitude | √ |
search query | √ |
radius | √ |
Wait | |
interval | √ |
Hand Over | |
mutation key | x |
mutation value | √ |
context key | x |
context value | √ |
Command | |
name | √ |
context value | √ |
To accomodate reading from the different save options, we use the following notation style:
- {@session.orderCode}
- {@chat.firstName}
- {@shared('test').firstName}
- {@shared(@session.orderCode).firstName}
Let's unpack this bit by bit:
First off we're greated with brackets surrounding the read definition itself, which indicate that we're injecting a variable. Inbetween them we start by denoting the type the variable is saved under using the corresponding scope definition. This definition is prepended with an @
sign so the system knows not to take this text literally. This is followed by the value you want to retrieve from that scope.
You may have noticed the deviation of the shared scope notation with it's parentheses. This is used to denote the identifier which is required when using context shared between conversations. If the identifier is between single quotes (' ') it's a literal, hardcoded text (example 3), but these variables can also be nested, which comes in handy for providing a dynamic identifier for context shared between conversations:

Here the variable orderCode
scoped to the current session is used as the identifier for the CurrentOrderItem
context shared between conversations. This CurrentOrderItem
then contains the property firstName
(example 4).
Read context fallback
If a variable doesn't exist, it gets replaced with an empty text. Currently no validation exists on the existence of context variables, so be careful and sufficiently test your script.
Pizza bot deep-dive
This case is a good example to understand most of the context functionality and uses some more advanced techniques for its implementation. It uses shared scope, a session variable to dynamically provide the shared scope with its identifier and setting a variable based on a regex match from the entry step. The flow works as follows:
The bot listens to an input in the form of "Order xxxxx", where xxxxx is a random 5 digit range of numbers. With the advanced Regex functionality, we save this code as a context variable with session scope under the name orderCode
. This scope makes the most sense here as we the variable will be parsed again at the start of the next session.

An order isn't complete without items. To get the user's order we use an input step. That value is put in the variable CurrentOrderItem
when the user eventually decides which pizza he/she wants and saved using the shared scope. To put this in the list of current orders, the session variable orderCode
that is parsed from the input step comes into play.
Since the shared identifier accepts a context definition we can make sure the pizza order is always stored in the list of the specific order code with which the chat is started.

The dynamic shared context variable works like this: the chatbot recognizes a context variable and resolves this to the orderCode, which in this case is 12345
. Now the value for currentOrderItem is saved under the shared identifier 12345
. If multiple people add their order, they're all added under that key, which will contain multiple orders from different people.
To confirm the pizza you've ordered we fetch the value of the variable currentOrderItem
. In this example it'll default to the last added order in the list. This can be accomplished by using the read notation of shared context and the nested value of orderCode
to keep everything dynamic. We make sure to reference the CurrentOrderItem
as that's been defined in the input step earlier.

Context variables technical documentation
Write context to database
When a request has been received to save context, it will first be converted to a stringified JSON object. This is then put inside a ContextWriteEnvelope
event, where:
- Context: the stringified object as converted previously
- ChatId: hash of the channel,
ConversationClientId
andConversationHostId
in the form of a Guid - SessionId: the phonenumber, appleId, some other handle in the form of a Guid
A context variable's value might look like this, including several primitive types and nesting:
{
"Firstname": "Thimo",
"Lastname": "Koolen",
"DateOfBirth": {
"Day": 22,
"Month": 12,
"Year": 1997
},
"Active": true
}
The IContextClient
(which is injected inside the ChatGrain
) handles persisting the given value in the database.
Read queries
Read queries make use of JSON path (a query language for JSON). This supports. This supports more exotic querying than just getting a single value, like querying for items between a certain index range or even filter expressions which select all elements in an object or array that match the specified filter.
Queries are constructed using a IContextQuery
object. As JSON Path doesn't allow for multiple fields within one query, the IContextQuery object has a list of queries. Each query has these properties:
- Key: The name of the result in the final JSON Object
- Value: The JSON Path query
Adding such queries to an IContextQuery
instance is made possible in two ways:
- With objectname.Selectors.Add(key, value) where key and value are explained above.
- With a stringified JSON object by calling the helper method
AddFromStringifiedJson
on it
Combining this information we'll get the following simple query by property:
{
"First": ".$Firstname",
"Last": ".$Lastname",
"BirthYear": ".$DateOfBirth.Year"
}
which results in the following JSON object after reading:
{
"First": "Thimo",
"Last": "Koolen",
"BirthYear": 1997
}
Notice that the key in the query with JSON path and the key in the result are identical.
Updated 7 months ago