Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
213 lines (139 sloc) 9.75 KB

Skills

This page is intended to serve as a guide to what skills are, how they plug into the Bot core and how they can be used.

Concept

Basics

At its core, a skill is an object that represents an action that the bot executes to respond back to the user as part of a conversation. The object is called a Skill object and the action is the JavaScript skill function that is passed in when instantiating a new skill.

At a basic level, a skill object can be created like so:

var skillName = 'my_help_skill';
var topicName = 'help';
var helpSkill = new Skill(skillName, topicName, function ApplyFn(context, request, response, next) {
	...
	return next();
});

A skill name is expected to be unique. However, please note that multiple skills (with different names, of course) can work with the same topic name at different confidence levels (see Adding Skill).

For every skill, an apply function must be defined.

The apply function

The apply function is called whenever a skill is matched against a given incoming message. It is called with four function parameters, namely: context, request, response, next. These four objects are there to help you construct a meaningful conversational response.

Context

The context object is a simple object, designed to serve as a key-value map. Every interaction with the bot requires a correspondance ID. This ID is used to create a new context if one does not already exist or to load an existing one.

The idea is to allow skills to infer values from previously saved ones if they have not been explicitly specified in a given query.

For example, a skill that extracts and resolves a ticket number can use the context to save the ticket number when a given sentene contains one. Next time, when the same skill is called as part of a different statement, the ticket number may not be present in the sentence. In this scenario, the ticket number can be retrieved from the context that was persisted previously.

Request

The request object serves to provide data about the request itself. Currently, the request object contains the following:

Attribute Data Type Description
id String Correspondance ID of the request
message Message Message object representing the incoming message
sentence Object Object containing all[] array containing all sentences in the request, current string representing the current sentence that is being processed and index number representing the index within the sentence array of the current sentence that is being processed.
skill Object Object containing all[] array containing all skills resolved as part of the request, current Skill representing the current sentence that is being processed and index number representing the index within the skill array of the current skill that is being processed.

Response

response.message

The response object can be used to respond to the query from the skill. Basic usage to respond with a message is:

response.message = new Message('SingleLine', 'Hey there!');

next()

Once you have responded to a message, you may want to do something else too. That is fine, as long as you remember to call the next() function which is passed in as the fourth parameter to the apply function.

Make sure you call next() or else the bot will never know that the skill has finished processing the request.

response.final()

All skills are resolved and executed as part of a skill resolution chain. This is true especially when the bot is processing multi-sentence requests. However, sometimes, you may want to set a final message to the response, preventing the rest of the execution chain from responding. This can be achieved by calling the final() function within the response object. Basic usage is like so:

response.message = new SingleLineMessage('Sorry I do not understand what you are trying to say.');
response.final();
response.next();

response.lockConversationForNext()

If your skill requires more information from the user, you can use the follow-up feature. This can be achieved by acquiring a lock on the conversation for the next call. You can use this feature like so:

response.lockConversationForNext();

This tells the bot to lock the conversation for the skill you are in such that the next time bot gets a message from the end-user, it sends the request straight to your skill without resolving the topic at all.

However, keep in mind that as the method name suggests, the lockConversationForNext method only reserves the lock for the next one call. The lock gets released as soon as your skill is called the next time. If you need yet more information, you will have to call that method again.

As a best practice, make sure you provide a prompt to the user before you call the lockConversationForNext by setting a message on response.message. This will help the end-user see what he/she is being asked for.

Also, as a side-note, when lockConversationForNext is called, the bot abandons execution of the rest of the skill chain for multi-sentence messages. Hence, there is no need to call response.final() after acquiring a lock.

response.send(message)

The send method is a wrapper for response.message and next() calls. It accepts a single parameter, namely message where you can pass in a Message object. Passing a Message object here has the same effect as doing response.message = message.

It is merely there for convenience, allowing you to write cleaner code. Here's how it replaces the old way of doing things:

response.message = new Message(...);
return next();

with the new way of doing things:

return response.send(new Message(...));

Pro Tip:

You can chain methods to simplify your statements. For instance, the below:

return response.lockConversationForNext().final().send(new Message(...));

has the same effect as:

response.lockConversationForNext();
response.final();
response.message = new Message(...);
return next();

Adding skill

For every topic the bot has been trained for, it must have a corresponding skill that it can call to resolve that topic. Thus, the number of skills must be at least equal to the number of topics. At a basic level, a skill can be added to the bot like so:

bot.addSkill(skillObject);

You can map more skills than the number of topics. This is because skills can be mapped at different minimum confidence levels to a topic. The confidence level can be specified as the second parameter to the addSkill method on the bot. Basic usage is like so:

bot.addSkill(skillObject, 50);

According to the above example, the bot will only resolve the above skill when its confidence in the resolved topic from the sentence is at least 50%.

Multiple topics can be added at multiple skill levels. The bot will always resolve the skill closest to its confidence level.

bot.addSkill(skillA);
bot.addSkill(skillB, 40);
bot.addSkill(skillC, 60);

In the above example, skillC gets executed when the bot is at least 60% confident in its topic resolution, skillB when it is 40% confident and skillA below 40%. Notice that we did not need to specify confidence level for skillA because when skills are added, the default minimum confidence level at which they are executed is always 0.

Pro Tip:

The addSkill method is chainable. This means that doing the following:

bot.addSkill(skill1).addSkill(skill2).addSkill(skill3);

will have the same effect as:

bot.addSkill(skill1);
bot.addSkill(skill2);
bot.addSkill(skill3);

Helpers

To make skill-making easier, some helpers are available. These are wrappers around the skill object that allow you to common tasks within a skill.

StaticResponse

The StaticResponse helper can help you create a skill that statically responds using a single message object. The constructor requires you to pass in three parameters. These are skillName as a string, topicName as a string and Message which could be a string, array or a Message object.

Here's syntax for all the ways it can be used.

var skillName = 'MyAwesomeSkill';
var topic = 'some_topic';

var singleLineSkill = new StaticResponseSkill(skillName, topic, 'My Static Response');
var multiLineSkill = new StaticResponseSkill(skillName, topic, ['Static', 'Response']);
var messageObjectSkill = new StaticResponseSkill(skillName, topic, [new Message('MultiLine', ['Multi', 'Line'])]);

StaticRandomResponse

If you ever wanted to return a random response from a list of responses, StaticRandomResponse helper is your friend. The constructor requires you to pass in three parameters. These are skillName as a string, topicName as a string and Message which could be a string[], Message[] object.

Here's a syntax for all the ways it can be used.

var skillName = 'MyAwesomeSkill';
var topic = 'some_topic';

var singleLineSkill = new StaticRandomResponseSkill(skillName, topic, ['random', 'skill']);
var messageObjectSkill = new StaticRandomResponseSkill(skillName, topic, [new SingleLineMessage('Random Response One'), new SingleLineMessage('Random Response Two')]);
You can’t perform that action at this time.