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
$context
object 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
bind
function 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
bind
function are placed either in a separate file with the.js
extension, which in turn is imported to the script via therequire
tag, or in the body of theinit
tag.
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
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.
/
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
onScriptError
handler. - A dialog error occurred and was not processed by any
onDialogError
handler. - 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
.