bind
The bind built-in function is used for setting up handlers.
How handlers work
This is the way handlers work in general.
- You write a function accepting the
$contextobject as its argument, which represents the context of the current request processing step. The function performs all the necessary actions. - This function is passed to the
bindfunction along with its type, which determines situations in which the handler function will be called. - Also when setting up the handler, it is bound to a specific path in the script state hierarchy. It is the root path
/by default. - The handler and the call to the
bindfunction are placed either in a separate file with the.jsextension, which in turn is imported to the script via therequiretag, or in the body of theinittag.
Syntax
The bind function accepts 4 arguments.
| Argument | Type | Description | Required |
|---|---|---|---|
type | String | The handler type | Yes |
handler | Function | The handler function | Yes |
path | String | The absolute path for binding the handler | No |
name | String | The handler name | No |
This is an example of calling the bind function:
bind(
"postProcess",
function($context) {
$context.session.lastState = $context.currentState;
},
"/Start",
"Remember last state"
);
- The
postProcesshandler type passed as the first argument means that the function will be called after the main request processing stage. - The function passed as the second argument determines the necessary action. In this case it saves the path to the current state into
$sessionas the last visited state. - The handler is bound to the
/Startpath, so it will be called in the/Startstate and all its descendant states, such as/Start/Hello,/Start/Hello/1, etc.
/ means that it will be called from all states existing in the script.Request processing stage handlers
The following handlers are called during the request processing cycle:
preMatch
The preMatch handler is called before request classification. It has the following primary use cases.
Forced change of current state
The handler from the following example will forcefully change the current state from /Hello to /Start. This can be useful when renaming states for ensuring backwards compatibility of different script versions.
bind(
"preMatch",
function($context) {
$context.temp.targetState = "/Start";
},
"/Hello"
);
Request modification
The following handler appends a suffix to requests from authorized clients, which can help process their requests in states unavailable to clients without active authorization.
bind("preMatch", function($context) {
if ($context.client.hasActiveAuthorization) {
$context.request.query += " (client authorized)";
}
});
chatbot.yaml configuration file:nlp:
modifyRequestInPreMatch: true
selectNLUResult
It is possible to use different types of activation rules together in one script. By default, they are triggered in the following order: patterns first, then intents.
If some alternative behavior is required, you can use the selectNLUResult handler to change it.
This handler is called after request classification and allows you to redefine the rule activation mechanism.
preProcess
The preProcess handler is called after the request has been classified and the target state has been determined, but before performing the actions in the state. It can be used for initializing variables or checking some preliminary conditions in order to transition to other target states.
In the following example, it is assumed that the device volume setting is stored in $session. If the volume is undefined, a default value is assigned to it.
var DEFAULT_VOLUME = 40;
bind("preProcess", function($context) {
if (!$context.session.volume) {
$context.session.volume = DEFAULT_VOLUME;
}
});
postProcess
The postProcess handler is executed after request processing has finished. For example, it can be used for extending bot replies or sending statistical data to an external analytical platform.
In the handler from the example below, all bot replies in the Telegram channel are injected with a property indicating that the replies are marked up using Markdown.
bind("postProcess", function($context) {
if ($context.response.channelType === "telegram") {
$context.response.replies = $context.response.replies.map(function(reply) {
if (reply.type === "text") {
reply.markup = "markdown";
}
return reply;
});
}
});
$reactions.transition method to make a transition back to the script and forcefully continue request processing.Error handlers
Error handlers are used for handling errors which occur during the script execution:
$context.exception.message property contains the message of the error which triggered the handler.onScriptError
The onScriptError handler is called when an unhandled exception occurs in the JavaScript code. It can also be used for configuring how to process custom exceptions raised using the throw statement.
Consider the following example of using this handler to register the exception message in the session data report using $analytics.setSessionData:
bind("onScriptError", function($context) {
$analytics.setSessionData("Error", $context.exception.message);
});
onScriptError, the postProcess handler will be called if present. Making a transition to another state using $reactions.transition is possible from onScriptError.onDialogError
The onDialogError handler is called on dialog errors not related to the JavaScript code. Examples of such errors are given below.
| Error | Error message |
|---|---|
| The request could not be processed in any state. | No target state was determined for query |
| A transition was made to a non-existent state. | State not found for path <path> |
| The bot was caught in an infinite loop of state transitions. | Infinite loop was detected for state <state> in postProcess transition |
bind("onDialogError", function($context) {
if ($context.exception.message
&& $context.exception.message === "No target state was determined for query") {
$reactions.answer(
'No state was found for request “' + $context.request.query + '”'
);
}
});
onDialogError, the postProcess handler will be called if present. Making a transition to another state using $reactions.transition is possible from onDialogError.onAnyError
The following cases can trigger the onAnyError handler:
- A script exception was raised and not processed by any
onScriptErrorhandler. - A dialog error occurred and was not processed by any
onDialogErrorhandler. - There was a server error unrelated to the bot script.
bind("onAnyError", function($context) {
var answers = [
"Something went wrong.",
"An error occurred. Please try again later.",
"I’m sorry, my script crashed."
];
var randomAnswer = answers[$reactions.random(answers.length)];
$reactions.answer(randomAnswer);
});
onAnyError, the postProcess handler will not be called. Making a transition to another state using $reactions.transition is not possible from onAnyError.