Custom Blocks

This page will help you get started on your bot with Snaps. You'll be up and running in no time.

While our Blocks tool offers a wide range of conversational elements and functionality, sometimes you'll want to be able to write custom code in order to handle a user conversation. Within our Blocks tool, you'll find the ability to mark a state as Custom which exposes a JavaScript code editor. Creating custom states is fairly straight forward and outlined below.

Create a new block and click custom. You'll see a base code snippet that looks like this:

module.exports = {
  prompt: (bot, context) => new Promise(resolve => {
    resolve();
  }),
  receive: (bot, context) => new Promise(resolve => {
    resolve(self.catchAll.id); // Catch All Group
  }),
};

This editor allows you to define a custom prompt and a custom receive function to be executed as part of a user interaction. The receive function handles user input and output's a state the user should be taken to, while the prompt function defines what messages should be sent within a state.

Both of these functions are passed bot and context.

Bot:

bot.say(message[, buttons])
  • messages [array|string] - A string of array of message objects. A single string can be passed as a convenience but is equivalent to [{ text: 'some string' }]
  • buttons [array] - Optional buttons to send with the messages. These options follow the format described in some link.
bot.setProp(name, value)
  • name [string] - The name of the user property to be set.
  • value [any] - The value of the user property to be set.
    Note: Properties will be serialized to a string representation.
bot.getProp(name)
  • name [string] - The name of the property to retrieve
  • return A promise that will resolve with the value.

Context:

  • input [string] - The user's input.
  • payload [object] - If the user clicked a button, this will contain the payload from that button.
  • user [object] - An object representing all properties known about the user.
  • intents [object] - A mapping of matched intents to confidence levels.
  • entities [object] - An object containing matched entities.

Sending messages

Most of the time you'll send messages within the prompt lifecycle function. Sending messages is done through the bot.say function mentioned above.

bot.say takes the following parameters:

  • messages:
    • description: An array containing the message objects that should be sent to the user.
    • type: array
    • example:
[{ text: 'How do you feel?' }]
  • buttons: An array of buttons to send to the user.
    • type: array
    • example:
[
  { title: '👍' },
  { title: '👎' }
]

Below is an example for asking the user a question.

bot.say(
  [{ text: 'What is your favorite color?' }], // messages
  [{ title: 'Red' }] //buttons
);

As a convenience, bot.say will also take a string as the first parameter. This is useful if you only need to send one string of text.

bot.say('Super easy!');

// Add some quickreplies
bot.say('Would you like to go to the next state?', {
  quickReplies: [{
    title: 'Yes',
    toState: '<STATE_ID>'
  },{
    title: 'No',
    toState: '<STATE_ID>'
  }]
});

Carousels and Listviews

// A Carousel with 2 cards
bot.say([{
  elements: [{
    title: 'First Product',
    subtitle: 'AKA a carousel',
    imageUrl: 'https://placeholdit.imgix.net/~text?txtsize=33&txt=250%C3%97150&w=250&h=150',
    buttons: [{
      title: 'Tell me more',
      toState: '<STATE_ID>'
    }]
  },
  {
    title: 'Second Product',
    subtitle: 'Second description',
    imageUrl: 'https://placeholdit.imgix.net/~text?txtsize=33&txt=250%C3%97150&w=250&h=150',
    buttons: [{
      title: 'Tell me more',
      toState: '<STATE_ID>'
    }]
  }]
}]);

// A listview
bot.say([{
  listView: {
    topElementSize: 'compact',
    cards: [{
      title: 'First item',
      subtitle: 'Description of that',
      imageUrl: 'https://placeholdit.imgix.net/~text?txtsize=33&txt=250%C3%97150&w=250&h=150'
    }, {
      title: 'Second Item',
      subtitle: 'Description of the second',
      imageUrl: 'https://placeholdit.imgix.net/~text?txtsize=33&txt=250%C3%97150&w=250&h=150'
    }]
  }
}]);

Receiving messages

You can check for several types of input in your state

context.input - what the user entered
context.payload - containing button selection info
context.payload.title - title of the selected button
context.payload.meta - any meta data defined on the selected button
context.payload.toState - the id


Setting User Properties

In order to customize a user's experience you'll frequently want to save user properties. User properties should be defined in the user property section beforehand.

bot.setProp('userProperty', value);
// NOTE: all user properties will be stringified when you retrieve them


// on a link click
// https://myUrl.com?setVars=var1:value1,var2:value2

What’s Next

Learn how to send different message types.