-
-
Notifications
You must be signed in to change notification settings - Fork 199
Chat Context
Node-RED has two variable context global and flow, the first is available everywhere in the app, the second just in the executed flow.
RedBot introduces the chat context where is possible to store information related to the specific user. The Receiver node store here some default information like chatId, username, authorized, firstName, lastName, etc. but it's possible to store any kind of information.
Two chat context providers are available
- Memory (default): it's a very fast and volatile storage, means that when the server is restarted all the stored data is lost. It' the default one (good for experimenting) and all the methods are synchronous
- Plain file: it stores data in a plain json file, all the methods are asynchronous.
- SQLite: it stores context in a local *.sqlite file
To get the chat context in a Function node (using the Memory context provider):
const chat = msg.chat();
console.log(chat.get('authorized')); // is the user authorized
console.log(chat.get('username')); // guidone72
chat.set('my_stuff', 'remember that');The same with Plain file on SQLitecontext provider
const chat = msg.chat();
chat.get('authorized')
.then(authorized => {
console.log(authorized); // is the user authorized
node.send(msg);
});since it's asynchronous all methods return a Promise. It's also possibile to combine multiple calls
const chat = msg.chat();
chat.get('authorized', 'username')
.then(variables => {
console.log(variables.authorized); // is the user authorized
console.log(variables.username); // guidone72
return chat.set('my_stuff', 'remember that');
})
.then(() => node.send(msg) }); // pass thru when the chat.set is overPlatform keys are pre-populated by RedBot: chatId (a unique identifier for a user in a specific platform), userId (a unique identifier of a user through different platforms) and transport.
Values in the chat context are meant to be persisted over the time and different platforms, for this reason these keys are read-only and cannot be modified.
They can be accessed by javascript msg.chat().get('chatId') or in templates {{chatId}} for retro-compatibility purposes, by they really don't belong to the chat context.
Some keys are pre-populated by RedBot: firstName, lastName, language, authorized, pending. These are specific to the flow and the used platform and can be modified or deleted by the msg.chat().* methods.
Not all the chat platforms provide such informations and/or may be different (unless a Mission Control MC Store node is used to reconcile the data): for example a user can have the Telegram client in the Italian language and the Messenger client in English language.
The {{message}} key is the current inbound message (from the user) and the {{messageId}} is the platform-dependent unique id (generally used to edit/delete already sent messages)
It's possibile to access variables in the Node-RED's global context using the handlebars-like notation, for example {{global.my_global_variable}}
Some nodes (like MC GraphQL) return data on the msg.payload key of the inbound message. Such value can be used in the handlebars-like notation, for example a payload of an inbound messag
{
total: 42,
shipping: {
address: 'Nowhere street,
city: 'Milan'
}
}can be used the configuration panel of any RedBot nodes using the dot notation, for example:
Your order of {{payload.total}} will be shipped to {{payload.shipping.address}}, {{payload.shipping.city}}
The chat context can store any kind of data (string, numbers, objects, etc), for example
const chat = msg.chat();
Promise.resolve(chat.set({
my_var: 'Guido',
another_var: {
subkey: 42
}
)).then(() => node.send(msg));can be used in the Message node
My name {{my_var}} and the answer to the universe and everything {{another_var.subkey}}
All context providers support these methods:
| Method | Type | Description |
|---|---|---|
| .get(key) | any | Return the value of the key |
| .get(key1, key2, ...keyN) | object | Return an hash with the values of the requested keys { key1: ..., key2: ... } |
| .set(key, value) | context | Set the value of the key |
| .set({key1: ..., key2: ...}) | context | Set multiple key values |
| .remove(key) | context | Remove value for the key |
| .remove(key1, key2, ...keyN) | context | Remove multiple keys |
| .clear() | context | Clear all the chat context |
| .dump() | context | Dump in console the chat context |
| .all() | context | Get all keys/values |
Plain file and SQLite context always returns a JavaScript Promise, while the Memory context has just synchronous methods.
In the examples it's used the Memory context for readability purpose, it's even easier to debug since it's cleared at every restart. In order to use both contexts in the same code, just wrap the calls in Promise.resolve(...) for example:
const chat = msg.chat();
// doesn't matter if chat context is Memory or an asynch one
Promise.resolve(chat.get('my_var'))
.then(myVar => {
// do something
});Some most of the nodes like Message node evaluates the specified text with a very simple template system (Handlebars-like syntax).
For example to say hello to the user
Hi, {{firstName}}!
There are some predefined variables in each chat context
| Method | Type | Read only | Description |
|---|---|---|---|
| chatId | string | yes | Unique identifier for a user and a specific transport. It's needed to initiate a conversation with a user |
| userId | string | yes | Unique identifier for a user, related to a userId can be multiple chatIds for each platform. |
| messageId | string | no | The message id of the last sent message, generally used to modifiy/delete a previously sent message |
| firstName | no | First name, when available (in Telegram must be specified in preferences) | |
| lastName | no | Last name, when available (in Telegram must be specified in preferences) | |
| authorized | boolean | no | Whether the user is authorized or not |
| transport | string | yes | Current message transport, could be telegram, facebook, slack, etc |
| message | string | no | the current message from the user in string format |
| language | string | no | the language of the chat client (i.e. en, it, etc). Not all chat platforms provides the user's language |
| pending | boolean | no | Tells if the chatbot has some pending requests and cannot answer (for example Dialogflow node set this flag while requesting the external API) |