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

Let’s look at how to set up a handler:

  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. To set up a handler using bind:

    • Specify the handler type. The type determines situations in which the handler function will be called.

    • Bind the handler to a specific path in the script state hierarchy. It is the root path / by default.

      tip

      When the bot context is in a state whose name begins with the handler path, the handler function will be called in all cases accounted for by its type.

      Binding a handler to the root path / means that it will be called from all states existing in the script.

    • Specify whether to execute the handler if the context is switched. If the dialog transitioned to a state as a result of another bot passing context to the current bot, all handler types except preMatch, are executed by default.

  3. Place the handler and the bind function call 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.

Syntax

The bind function accepts these arguments:

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

Execute the handler if the dialog transitioned to a state as a result of another bot passing context to the current bot. The argument is applied only when the handlers are called for the first time after the context switch.

The default value for preMatch is false, for all other handlers the default is true.
No

This is an example of calling the bind function:

bind(
"postProcess",
function($context) {
$context.session.lastState = $context.currentState;
},
"/Start",
"Remember last state",
false
);
  • 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.
  • The handler name is Remember last state.
  • The path to the current state will not be saved if the dialog transitions to the state as a result of another bot passing context to the current bot.

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.