Chatbot trên Facebook Messenger với Botkit.ai [phần 2/3]

Trong bào viết này tôi sẽ hướng dẫn các bạn tạo một Chatbot đơn giản trên facebook messenger với botkit.ai. Hiện nay có rất nhiều framework, thư viện, … và rất nhiều bài viết trên mạng hướng dẫn tạo Chatbot. Nhưng tôi đã tìm hiểu và thực hiện với botkit.ai vì nó khá đơn giản cho người mới bắt đầu làm quen với chatbot như tôi.

Botkit.ai là công cụ mã nguồn mở cho phép các lập trình viên có thể tự xây dựng chatbot, ứng dụng tích hợp các message từ nhiều nguồn như facebook, slack,…. Nó là một phần của Microsoft Bot Framework.


Bước 4: Tạo một ứng dụng nodejs với botkit.ai

Trong phần dưới đây thì tôi sử dụng Window, nếu bạn nào sử dụng Ubuntu hay một hệ điều hành khác thì cách thức tôi nghĩ cũng tương tự.

Yêu cầu máy tính phải được cài nodejs, vì ứng dụng bên dưới mình dùng nodejs. Nếu bạn chưa cài nodejs thì có thể download và cài đặt nodejs theo link bên dưới:

https://nodejs.org/en/download/

Bây giờ khởi tạo dự án bằng lệnh:

npm init

Các thông tin nào không cần thiết thì chúng ta sẽ để mặt định, sau đó chúng ta sẽ cài đặt vài thư viện:

npm install --save botkit@^0.6.7
npm install --save express@^4.16.2
npm install --save dotenv@^4.0.0
npm install --save request@^2.88.0

Sau khi khởi tạo thì chúng ta có package.json được sinh ra như bên dưới:

package.json

{
  "name": "fstack-chatbot",
  "version": "1.0.0",
  "description": "fstack.vn - build a simple chatbot with botkit.ai",
  "main": "index.js",
  "scripts": {
    "start": "nodemon index.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/prav10194/botkit-facebook-wrapper.git"
  },
  "author": "Pranav Bhatia",
  "license": "ISC",
  "bugs": {
    "url": "https://github.com/prav10194/botkit-facebook-wrapper/issues"
  },
  "homepage": "https://github.com/prav10194/botkit-facebook-wrapper#readme",
  "dependencies": {
    "botkit": "^0.6.7",
    "dotenv": "^4.0.0",
    "express": "^4.16.2",
    "request": "^2.88.0"
  }
}

Các bạn tạo thêm 2 files: index.js.env. Cấu trúc thư mục như bên dưới:

index.js

'use strict';

var express = require('express');
var app = express();

var bodyParser = require('body-parser');
var request = require('request');

require('dotenv').config()

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
  extended: true
}));

var botkit = require('botkit');

var facebookController = botkit.facebookbot({
  verify_token: process.env.fb_verify_token,
  access_token: process.env.fb_access_token,
  debug: false,
  stats_optout: true
});

process.on('uncaughtException', function(err) {
  console.log('Caught exception: ' + err);
});

facebookController.startTicking();

var facebookBot = facebookController.spawn({});

facebookController.setupWebserver(process.env.server_port,function(err,webserver) {
  facebookController.createWebhookEndpoints(facebookController.webserver, facebookBot, function() {
    console.log('Your facebook bot is connected.');
  });
});

facebookController.hears(['.*'], 'message_received', function(bot, message) {
    message.text = message.text.replace(/(\r\n|\n|\r)/gm," ");
    console.log('message_received -> ' + JSON.stringify(message));
    getSenderName(message.sender.id, function(senderName) {
        if (senderName === null) {
            senderName = 'bạn';
        }
        var attachment = {
            'type':'template',
            'payload':{
                'template_type':'generic',
                'elements':[
                    {
                        'title':'Freelancer IT Job!',
                        'image_url':'https://mm.aiircdn.com/38/595fade423e0b.png',
                        'subtitle':'Chào mừng ' + senderName + ' đến với Freelancer IT Job! Chúng tôi là nhà cung cấp nhân sự IT hàng đầu ở Việt Nam. Bạn muốn tìm nhân sự cho lĩnh vực: ',
                        'buttons':[
                            {
                                'type':'postback',
                                'title':'Software Engineer',
                                'payload':'Software Engineer'
                            },
                            {
                                'type':'postback',
                                'title':'IT Networking',
                                'payload':'IT Networking'
                            }
                        ]
                    }
                ]
            }
        };
        bot.reply(message, {
            attachment: attachment,
        });
    });

});

facebookController.hears(['IT Networking'], 'message_received,facebook_postback', function(bot, message) {
    var attachment = {
        'type':'template',
        'payload':{
            'template_type':'generic',
            'elements':[
                {
                    'title':'Freelancer IT Job!',
                    'image_url':'https://mm.aiircdn.com/38/595fade423e0b.png',
                    'subtitle':'Bạn muốn tìm nhân viên có kinh nghiêm trong lĩnh vực: ',
                    'buttons':[
                        {
                            'type':'postback',
                            'title':'IT Help Desk',
                            'payload':'IT Help Desk'
                        },
                        {
                            'type':'postback',
                            'title':'DevOps',
                            'payload':'DevOps'
                        }
                    ]
                }
            ]
        }
    };
    bot.reply(message, {
        attachment: attachment,
    });
});

facebookController.hears(['IT Help Desk','Helpdesk','Help Desk'], 'message_received,facebook_postback', function(bot, message) {
    var msgReply = 'Chúng tôi có hơn 1500 nhân sự có kinh nghiệm trong linh vực helpdesk. Vui lòng để lại thông tin liên hệ để được tư vấn tốt nhất. Cảm ơn quý khách hàng!';
    bot.reply(message, msgReply);
});

facebookController.hears(['DevOps', 'devops'], 'message_received,facebook_postback', function(bot, message) {
    var msgReply = 'Chúng tôi có hơn 100 kỹ sư có kinh nghiệm trong linh vực DevOps. Vui lòng để lại thông tin liên hệ để được tư vấn tốt nhất. Cảm ơn quý khách hàng!';
    bot.reply(message, msgReply);
});

facebookController.hears(['Software Engineer'], 'message_received,facebook_postback', function(bot, message) {
    var attachment = {
        'type':'template',
        'payload':{
            'template_type':'generic',
            'elements':[
                {
                    'title':'Freelancer IT Job!',
                    'image_url':'https://mm.aiircdn.com/38/595fade423e0b.png',
                    'subtitle':'Bạn muốn tìm lập trình viên thành thạo về ngôn ngữ: ',
                    'buttons':[
                        {
                            'type':'postback',
                            'title':'Java',
                            'payload':'Java'
                        },
                        {
                            'type':'postback',
                            'title':'PHP',
                            'payload':'PHP'
                        },
                        {
                            'type':'postback',
                            'title':'NodeJS',
                            'payload':'NodeJS'
                        }
                    ]
                }
            ]
        }
    };
    bot.reply(message, {
        attachment: attachment,
    });
});

facebookController.hears(['Java','java'], 'message_received,facebook_postback', function(bot, message) {
    var msgReply = 'Chúng tôi có hơn 1000 lập trình viên Java nhiều kinh nghiệm cho các dự án Mỹ, Úc, Pháp, Canada,...Vui lòng để lại thông tin liên hệ để được tư vấn tốt nhất. Cảm ơn quý khách hàng!';
    bot.reply(message, msgReply);
});

facebookController.hears(['PHP','php'], 'message_received,facebook_postback', function(bot, message) {
    var msgReply = 'Chúng tôi có hơn 550 lập trình viên PHP nhiều kinh nghiệm cho các dự án Mỹ, Nhật, Pháp,...Vui lòng để lại thông tin liên hệ để được tư vấn tốt nhất. Cảm ơn quý khách hàng!';
    bot.reply(message, msgReply);
});

facebookController.hears(['NodeJS','nodejs','NodeJs'], 'message_received,facebook_postback', function(bot, message) {
    var msgReply = 'Chúng tôi có hơn 260 lập trình viên NodeJS nhiều kinh nghiệm cho các dự án ở thị trường Châu Âu,...Vui lòng để lại thông tin liên hệ để được tư vấn tốt nhất. Cảm ơn quý khách hàng!';
    bot.reply(message, msgReply);
});

function getSenderName(senderId, callback) {
    request.get({
          headers: { 'content-type': 'application/x-www-form-urlencoded' },
          url: "https://graph.facebook.com/v2.6/" + senderId + "?fields=email,name&access_token=" + process.env.fb_access_token,
    }, function(err, response, body) {
          if (err) {
            logger.error(err);
            callback (null);
        } else {
            console.log(response);
            console.log(body);
            callback(JSON.parse(body).name);
        }
    });
}


facebookController.hears(['.*'], 'message_received', function(bot, message){}; 

Handler trên lắng nghe tắt cả các message từ facebook messenger (được cấu hình PRODUCTS – webhooks). Tương tự các handler khác thì lắng nghe một message cụ thể như:

facebookController.hears(['Java','java'], 'message_received,facebook_postback', function(bot, message) {
     var msgReply = 'Chúng tôi có hơn 1000 lập trình viên Java nhiều kinh nghiệm cho các dự án Mỹ, Úc, Pháp, Canada,…Vui lòng để lại thông tin liên hệ để được tư vấn tốt nhất. Cảm ơn quý khách hàng!';
     bot.reply(message, msgReply);
 });

Hanlder trên thì lắng nghe 2 message là ‘Java‘ và ‘java’, nghĩa là nếu người dùng chat từ: ‘Java’ hoặc ‘java’ thì con bot này sẽ gửi lại message: ‘Chúng tôi có hơn 1000 lập trình viên Java nhiều kinh nghiệm cho các dự án Mỹ, Úc, Pháp, Canada,…Vui lòng để lại thông tin liên hệ để được tư vấn tốt nhất. Cảm ơn quý khách hàng!’

Việc tạo facebookController, facebookBot và các hanlder như trên các bạn tham khảo tài liệu của botkit theo link: https://www.botkit.ai/docs/v4/core.html#the-botkit-controller

.env – đây là tập tin cấu hình cho ứng dụng

fb_access_token=[page access token mà các bạn đã lưu ở bài 1]
fb_verify_token=Facebook
server_port=8080

Bây giờ chúng ta sẽ start ứng dụng và cấu hình webhooks cho ứng dụng facebook đã tạo ở bài 1. Do facebook bắt buộc chúng ta phải có valid domain với SSL trong phần cấu hình webhooks (Callback URL), nên tôi dùng ngrok để tạo public url có ssl.

ngrok là công cụ đơn giản cho chúng ta tạo valid domain (public url) sử dụng cho việc test webhooks trên các ứng dụng facebook và nhiều thứ khác. Các bạn có thể download ngrok ở link: https://ngrok.com/download. Đây chỉ là giải pháp cho các developers để test. Nếu thực sự muốn build sản phẩm thương mại thì các bạn phải đăng ký 1 domain, 1 ssl và 1 host để thay thế cho việc này.

Giờ chúng ta sẽ public ứng dụng từ localhost bằng ngrok:

node index.js

Download ngrok và khởi tạo ngrok bằng cách double-click vào ngrok.exe

Giờ chạy lệnh ngrok http 8080 để tạo public url và forwading đến localhost:8080

ngrok http 8080

Giờ chúng ta đã có public url với ssl là: https://76740d7f.ngrok.io, bước tiếp theo ta sẽ cấu hình webhooks trên ứng dụng facebook.