Menu Search
Jump to the content X X
Smashing Conf San Francisco

We use ad-blockers as well, you know. We gotta keep those servers running though. Did you know that we publish useful books and run friendly conferences — crafted for pros like yourself? E.g. upcoming SmashingConf San Francisco, dedicated to smart front-end techniques and design patterns.

How To Develop A Chat Bot With Node.js

In the past few months, chat bots have become very popular, thanks to Slack, Telegram and Facebook Messenger. But the chat bot idea is not new at all.

A chat bot interface is mentioned in the famous Turing test in 1950. Then there was Eliza in 1966, a simulation of a Rogerian psychotherapist and an early example of primitive natural language processing. After that came Parry in 1972, a simulation of a person with paranoid schizophrenia (and, yes, of course, Parry met Eliza1).

In 1983, there was a book named The Policeman’s Beard Is Half Constructed, which was generated by Racter, an artificial intelligence computer program that generated random English-language prose, later released as a chat bot.

Further Reading on SmashingMag: Link

One of the most famous was Alice (artificial linguistic Internet computer entity), released in 1995. It wasn’t able to pass the Turing test, but it won the Loebner Prize6 three times. In 2005 and 2006, the same prize was won by two Jabberwacky bot characters.

And in 2014, Slackbot made chat bots popular again. In 2015, Telegram and then Facebook Messenger released chat bot support; then, in 2016 Skype did the same, and Apple and some other companies announced even more chat bot platforms.

Chat bots7
(Image: The Stocks8) (Large preview9)

What Do You Need To Know To Build A Chat Bot? Link

The answer to that mostly depends on what you want to build, of course.

In most cases, you can build a chat bot without knowing much about artificial intelligence (AI), either by avoiding it completely or by using some existing libraries for basic AI.

The same goes for natural language processing (NLP); it’s more important than AI, but you can build a chat bot using an NLP library or, for some platforms, simply by using buttons and UI elements instead of word processing.

And finally, do you even need to know programming? There are a lot of visual bot builders, so probably not. But it can be useful.

How To Build A Facebook Messenger Bot Link

This is an article about building chat bots, so let’s finally dive deep into it. Let’s build a simple Facebook Messenger bot.

We’ll use Node.js, but you can build a chat bot with any programming language that allows you to create a web API.

Why Node.js? Because it’s perfect for chat bots: You can build a simple API quickly with hapi.js, Express, etc.; it supports real-time messages (RTM) for Slack RTM bots; and it’s easy to learn (at least easy enough to build a simple chat bot).

Facebook already has a sample chat bot written in Node.js, available on GitHub10. If you check the code, you’ll see that it uses the Express framework and that it has three webhooks (for verification, authentication and receiving messages). You’ll also see that it sends responses with Node.js’ Request module.

Sounds simple?

It is. But this complete sample bot has 839 lines of code. It’s not much and you probably need just half of that, but it’s still too much boilerplate code to start with.

What if I told you that we could have the same result with just five lines of JavaScript?

var botBuilder = require('claudia-bot-builder');

module.exports = botBuilder(function (request) {
  return 'Thanks for sending ' + request.text;
});

Or even fewer if you use ECMAScript 6:

const botBuilder = require('claudia-bot-builder');

module.exports = botBuilder(request => `Thanks for sending ${request.text}`);

Meet The Claudia Bot Builder Link

The Claudia Bot Builder helps developers create chat bots for Facebook Messenger, Telegram, Skype and Slack, and deploy them to Amazon Web Services’ (AWS) Lambda and API Gateway in minutes.

The key idea behind the project is to remove all of the boilerplate code and common infrastructure tasks, so that you can focus on writing the really important part of the bot — your business workflow. Everything else is handled by the Claudia Bot Builder.

Why AWS Lambda? It’s a perfect match for chat bots: Creating a simple API is easy; it responds much faster to the first request than a free Heroku instance; and it’s really cheap. The first million requests each month are free, and the next million requests are just $0.20!

Here’s how easy it is to build a Facebook Messenger bot with Claudia Bot Builder:

Let’s Build A Space Explorer Bot Link

Space Explorer is a simple Messenger chat bot that uses NASA’s API to get data and images about space.

Before we begin, create a Facebook page and app, and add Messenger integration, as described in Facebook’s “Getting Started11” guide.

Then, create a file named bot.js with the following content:

const botBuilder = require('claudia-bot-builder');

module.exports = botBuilder(request => `Hello from space explorer bot! Your request was: ${request.text}`);

Install these dependencies:

npm init;

npm install claudia-bot-builder -S;

npm install claudia -g;
Create chat-bots easily using Claudia Bot Builder
Create a Lambda function and follow the instructions in the video above to connect it with your Facebook app:

claudia create --region us-east-1 --api-module bot --configure-fb-bot

That’s it! You’ve created your first chat bot for Facebook Messenger.

If you send a message to your page, your bot will reply. But the answer is too simple. Let’s add something more interesting!

Integrate NASA’s API Link

Before we continue, visit NASA’s API portal12 and get an API key.

Then, add your API key as a nasaApiKey stage variable in API Gateway. You can do that from the UI or by running the following command:

aws apigateway create-deployment \
    --rest-api-id API_ID --stage-name latest \
    --variables nasaApiKey=YOUR_NASA_API_KEY

Here, API_ID is your API ID from the claudia.json file that was auto-generated in the previous step.

Let’s add a better answer to the text messages. Claudia Bot Builder has a simple builder for Facebook Messenger template messages (the documentation is on GitHub13).

const botBuilder = require('claudia-bot-builder');
const fbTemplate = botBuilder.fbTemplate;
const rp = require('minimal-request-promise');

module.exports = botBuilder((request, originalApiRequest) => {
  // If request is not postback
  if (!request.postback)
    // We'll get some basic info about the user
    return rp.get(`https://graph.facebook.com/v2.6/${request.sender}?fields=first_name&access_token=${originalApiRequest.env.facebookAccessToken}`)
      .then(response => {
        const user = JSON.parse(response.body)
        // Then let's send two text messages and one generic template with three elements/bubbles
        return [
          `Hello, ${user.first_name}. Welcome to Space Explorer! Ready to start a journey through space?`,
          'What can I do for you today?',
          return new fbTemplate.generic()
            .addBubble(`NASA's Astronomy Picture of the Day`, 'Satellite icon by parkjisun from the Noun Project')
              .addImage('https://raw.githubusercontent.com/stojanovic/space-explorer-bot/master/assets/images/apod.png')
              .addButton('Show', 'SHOW_APOD')
              .addButton('What is APOD?', 'ABOUT_APOD')
              .addButton('Website', 'http://apod.nasa.gov/apod/')
            .addBubble(`Photos from NASA's rovers on Mars`, 'Curiosity Rover icon by Oliviu Stoian from the Noun Project')
              .addImage('https://raw.githubusercontent.com/stojanovic/space-explorer-bot/master/assets/images/mars-rover.png')
              .addButton('Curiosity', 'CURIOSITY_IMAGES')
              .addButton('Opportunity', 'OPPORTUNITY_IMAGES')
              .addButton('Spirit', 'SPIRIT_IMAGES')
            .addBubble('Help & info', 'Monster icon by Paulo Sá Ferreira from the Noun Project')
              .addImage('https://raw.githubusercontent.com/stojanovic/space-explorer-bot/master/assets/images/about.png')
              .addButton('About the bot', 'ABOUT')
              .addButton('Credits', 'CREDITS')
              .addButton('Report an issue', 'https://github.com/stojanovic/space-explorer-bot/issues')
            .get();
        ];
      });
}

Now our bot has a nice welcome answer:

Space Explorer bot preview14
(Large preview15)

Much better!

Next, we want to handle postbacks. Let’s start with NASA’s Astronomy Picture of the Day:

// In case of the 'SHOW_APOD' postback, we'll contact NASA API and get the photo of the day.
if (request.text === 'SHOW_APOD')
  return rp(`https://api.nasa.gov/planetary/apod?api_key=${originalApiRequest.env.nasaApiKey}`)
    .then(response => {
      const APOD = JSON.parse(response.body)
      return [
        `NASA's Astronomy Picture of the Day for ${APOD.date}`,
        `"${APOD.title}", © ${APOD.copyright}`,
        new fbTemplate.image(APOD.url).get(),
        APOD.explanation,
        new fbTemplate.button('More actions:')
          .addButton('Download HD', APOD.hdurl)
          .addButton('Visit website', 'http://apod.nasa.gov/apod/')
          .addButton('Back to start', 'MAIN_MENU')
          .get()
      ]
    });

And here are the Mars rovers (Curiosity, Opportunity and Spirit):

// Common API call
function getRoverPhotos(rover, sol, nasaApiKey) {
  // If sol (Mars day) is not defined, take a random one.
  if (!sol)
    sol = (parseInt(Math.random() * 9) + 1) * 100;

  // Contact the API
  return rp(`http://api.nasa.gov/mars-photos/api/v1/rovers/${rover}/photos?sol=${sol}&api_key=${nasaApiKey}`)
    .then(response => {
      let rawBody = response.body;

      let roverInfo = JSON.parse('' + rawBody);
      // Create generic template with up to 10 photos.
      let photos = roverInfo.photos.slice(0, 10);
      let roverImages = new fbTemplate.generic();

      photos.forEach(photo => {
        return roverImages.addBubble(photo.rover.name, 'At ' + photo.earth_date + ' (sol ' + photo.sol + '), using ' + photo.camera.full_name)
          .addImage(photo.img_src)
          .addButton('Download', photo.img_src)
      });

      // Send the message.
      return [
        `${roverInfo.photos[0].rover.name} rover`,
        `Landing Date: ${roverInfo.photos[0].rover.landing_date} \nTotal photos: ${roverInfo.photos[0].rover.total_photos}`,
        roverImages.get(),
        new fbTemplate.button('More actions:')
          .addButton('Show newest photos', `PHOTOS_${rover}_${roverInfo.photos[0].rover.max_sol}`)
          .addButton('Visit Wikipedia', `https://en.wikipedia.org/wiki/${rover}_(rover)`)
          .addButton('Back to start', 'MAIN_MENU')
          .get()
      ];
    })
    .catch(err => {
      // If the selected sol doesn't have any photos, take the photos from sol 1000.
      console.log(err);
      return getRoverPhotos(rover, 1000, nasaApiKey);
    });
}

// Curiosity photos
if (request.text === 'CURIOSITY_IMAGES')
  return getRoverPhotos('curiosity', null, originalApiRequest.env.nasaApiKey);

// Opportunity photos
if (request.text === 'OPPORTUNITY_IMAGES')
  return getRoverPhotos('opportunity', null, originalApiRequest.env.nasaApiKey);

// Spirit photos
if (request.text === 'SPIRIT_IMAGES')
  return getRoverPhotos('spirit', null, originalApiRequest.env.nasaApiKey);

// Rover photos by sol (Mars day)
if (request.text.indexOf('PHOTOS_') === 0) {
  const args = request.text.split('_')
  return getRoverPhotos(args[1], args[2], originalApiRequest.env.nasaApiKey);
}

Finally, add some static content to the end:

// About Astronomy Picture of the Day
if (request.text === 'ABOUT_APOD')
  return [
    `The Astronomy Picture of the Day is one of the most popular websites at NASA. In fact, this website is one of the most popular websites across all federal agencies. It has the popular appeal of a Justin Bieber video.`,
    `Each day a different image or photograph of our fascinating universe is featured, along with a brief explanation written by a professional astronomer.`,
    new fbTemplate.button('More actions:')
      .addButton('Show photo', 'SHOW_APOD')
      .addButton('Visit website', 'http://apod.nasa.gov/apod/')
      .addButton('Back to start', 'MAIN_MENU')
      .get()
  ];

// About the bot
if (request.text === 'ABOUT')
  return [
    `Space Explorer is simple Messenger chat bot that uses NASA's API to get the data and images about the space`,
    `It's created for fun and also as a showcase for Claudia Bot Builder, node.js library for creating chat bots for various platform and deploying them on AWS Lambda`,
    new fbTemplate.button('More actions:')
      .addButton('Claudia Bot Builder', 'https://github.com/claudiajs/claudia-bot-builder')
      .addButton('Source code', 'https://github.com/stojanovic/space-explorer-bot')
      .get()
  ];

// Finally, credits
if (request.text === 'CREDITS')
  return [
    'Claudia Bot Builder was created by Gojko Adžić, Aleksandar Simović and Slobodan Stojanović',
    'Icons used for the bot are from the Noun Project',
    '- Rocket icon by misirlou, \n- Satellite icon by parkjisun, \n- Curiosity Rover icon by Oliviu Stoian, \n- Monster icon by Paulo Sá Ferreira',
    'This bot was created by Claudia Bot Builder team',
    new fbTemplate.button('More actions:')
      .addButton('Claudia Bot Builder', 'https://github.com/claudiajs/claudia-bot-builder')
      .addButton('The Noun Project', 'https://thenounproject.com')
      .addButton('Source code', 'https://github.com/stojanovic/space-explorer-bot')
      .get()
  ];

Result Link

After minor refactoring, our code should look something like the source on GitHub16.

And here’s how our bot works:

You can try it live on your page or on the Space Explorer bot page17 on Facebook Messenger.

Try it live on FB Messenger18

That’s it! You’ve successfully built your first chat bot using Claudia Bot Builder19. It was easy, wasn’t it?

Now go and build more cool chat bots.

Final Notes Link

I picked Facebook Messenger as a starting point because most of us are familiar with it. But we chose to go with Slack for our first bot because our whole team uses Slack daily. So, we decided to build a simple team vacation-tracker bot20 directly in Slack using Claudia Bot Builder, Node.js, MariaDB and AWS Lambda.

Depending on your idea, target market and the platforms you are most familiar with, you can start with any of the other platforms that support chat bots.

Visit the Claudia21 website to see how to develop and deploy AWS Lambda base microservices and APIs. And let us know if you build something cool with it.

Many thanks to Lav Crnobrnja, Marko Kažić, Goran Gajić, Bojan Matić and Vuk Nikolić for help and feedback on the article.

(rb, il, yk, al)

Footnotes Link

  1. 1 http://www.theatlantic.com/technology/archive/2014/06/when-parry-met-eliza-a-ridiculous-chatbot-conversation-from-1972/372428/
  2. 2 https://www.smashingmagazine.com/2016/12/conversational-design-essentials-tips-for-building-a-chatbot/
  3. 3 https://www.smashingmagazine.com/2016/11/does-conversation-hurt-or-help-the-chatbot-ux/
  4. 4 https://www.smashingmagazine.com/2016/07/conversational-interfaces-where-are-we-today-where-are-we-heading/
  5. 5 https://www.smashingmagazine.com/2016/06/complete-roadmap-building-delightful-onboarding-experience-mobile-app-users/
  6. 6 https://en.wikipedia.org/wiki/Loebner_Prize
  7. 7 https://www.smashingmagazine.com/wp-content/uploads/2016/09/chatbots-opt.png
  8. 8 http://thestocks.im
  9. 9 https://www.smashingmagazine.com/wp-content/uploads/2016/09/chatbots-opt.png
  10. 10 https://github.com/fbsamples/messenger-platform-samples
  11. 11 https://developers.facebook.com/docs/messenger-platform/quickstart
  12. 12 https://api.nasa.gov
  13. 13 https://github.com/claudiajs/claudia-bot-builder/blob/master/docs/FB_TEMPLATE_MESSAGE_BUILDER.md
  14. 14 https://www.smashingmagazine.com/wp-content/uploads/2016/09/space-explorer-bot-large-opt.png
  15. 15 https://www.smashingmagazine.com/wp-content/uploads/2016/09/space-explorer-bot-large-opt.png
  16. 16 https://github.com/stojanovic/space-explorer-bot
  17. 17 https://m.me/space-explorer-bot
  18. 18 https://m.me/space-explorer-bot
  19. 19 https://github.com/claudiajs/claudia-bot-builder
  20. 20 http://vacationtrackerbot.com
  21. 21 https://claudiajs.com

↑ Back to top Tweet itShare on Facebook

Slobodan Stojanović is CTO of Montréal-based software development agency Cloud Horizon and organizer of JS Belgrade meetups. He loves JavaScript and Open Source and in the past few months he is mostly experimenting with node.js, chat bots, offline web apps and apps that will eventually be able to work on Mars.

  1. 1

    Nice article, thanks for it. Bots are so cool!
    Anyway, when you say:
    “Create a Lambda function and follow the instructions in the video above to connect it with your Facebook app:”
    To what video are you pointing?

    1
  2. 6

    Very interesting article, thanks for sharing this information. Can’t wait to experiment with Claudia to build my first bot.

    1
  3. 7

    This is really fascinating! The link to your chatbot on Facebook isn’t working for me though, just opens a blank Messenger-window..

    1
  4. 9

    I recently built a game bot in Facebook Messenger. I have to say it’s a great platform to work with, even without a library. I discussed the bot here if anyone is interested: https://discuss.api.ai/t/textspaced-a-game-in-a-bot/1665

    1
  5. 10

    Nice Article, thanks! I got to know of Claudia and built some basic services. However when using your code for building a NASA bot I get the error – bot.js does not export a Claudia API builder instance.

    Can you help me resolve this error.

    1
    • 11

      Slobodan Stojanović

      October 19, 2016 9:35 am

      Did you used the latest code from the Github?
      While this article was in the review Claudia was updated to v2, there’s no change in the code, but Claudia v2.x requires bot builder v2.x too.

      I’ll update the dependencies on the Github and it would be great if you can try again and open an issue or contact me in Claudia Gitter (https://gitter.im/claudiajs/claudia) in case it doesn’t work for you.

      Thanks!

      1
  6. 12

    This is the error I get when I try to run `claudia create –region us-east-1 –api-module bot –configure-fb-bot`

    “`
    { message: ‘Could not load credentials from any providers’,
    code: ‘CredentialsError’,
    time: Fri Oct 21 2016 23:20:25 GMT-0400 (EDT),
    retryable: true,
    originalError:
    { message: ‘Connection timed out after 1000ms’,
    code: ‘TimeoutError’,
    time: Fri Oct 21 2016 23:20:25 GMT-0400 (EDT),
    retryable: true } } }
    “`

    Any ideas on how to run it? I have already created lamda function.

    0
  7. 14

    Super interesting article Slobodan!

    As an alternative if you want to build a serverless chatbot purely in Javascript (and jquery), I just created a small chat bot library in JavaScript that has access to existing conversational APIs.

    1
  8. 15

    Mohamed Sahad K P

    October 23, 2016 12:09 pm

    Please go throw the chat bot i created using slack and ibm watson conversation node js sdk

    https://github.com/mohamedsahadkp/ibm-watson-conversation

    1
  9. 16

    Also while developing a chatbot you’ll need to keep in mind feature that you will continually have new users who may also be new to chatbots. There is no menu and links, so you will need to prompt the user — have the bot introduce him/herself quickly and provide some type of CTA — “Hi, I’m your personal shopping assistant. You can ask me questions by typing them in or by tapping on the microphone and speaking them. Let’s get started. How can I help you?”
    In this article, there are also some good tips that will help build a useful chatbot  — https://www.romexsoft.com/blog/how-to-build-a-chatbot/

    2

↑ Back to top