Skip to main content

bind

The bind built-in function is used for setting up handlers.

tip
Handlers are special functions called at different stages of request processing or when errors occur during the script execution.

How handlers work

This is the way handlers work in general.

  1. You write a function accepting the $context object as its argument, which represents the context of the current request processing step. The function performs all the necessary actions.
  2. This function is passed to the bind function along with its type, which determines situations in which the handler function will be called.
  3. 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.
  4. The handler and the call to the bind function are placed either in a separate file with the .js extension, which in turn is imported to the script via the require tag, or in the body of the init tag.
tip
When the bot context is in a state whose name begins with the path which the handler is bound to, the handler function will be called in all cases accounted for by its type.

Syntax

The bind function accepts 4 arguments.

ArgumentTypeDescriptionRequired
typeStringThe handler typeYes
handlerFunctionThe handler functionYes
pathStringThe absolute path for binding the handlerNo
nameStringThe handler nameNo

This is an example of calling the bind function:

bind(
"postProcess",
function($context) {
$context.session.lastState = $context.currentState;
},
"/Start",
"Remember last state"
);
  • The postProcess handler 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 $session as the last visited state.
  • The handler is bound to the /Start path, so it will be called in the /Start state and all its descendant states, such as /Start/Hello, /Start/Hello/1, etc.
caution
Binding a handler to the root path / 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)";
}
});
caution
To enable this feature, set an additional property in the 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;
});
}
});
tip
It is possible to use the $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:

tip
In the body of error handler functions, the $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);
});
tip
After 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.

ErrorError 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 + '”'
);
}
});
tip
After 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:

  1. A script exception was raised and not processed by any onScriptError handler.
  2. A dialog error occurred and was not processed by any onDialogError handler.
  3. 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);
});
caution
After onAnyError, the postProcess handler will not be called. Making a transition to another state using $reactions.transition is not possible from onAnyError.