How to quickly build a chatbot service

LINE Bot Demo

Key
Features

Multi skill

NLU

Template


Scenario

Line Cloud

Webhook

NLU

Intent, Slots

Third-party APIs

Intent A

Intent B

Intent C

Intent D

Intent E

By Intent fetch Data

Web Server

Line Cloud

Send Message to User

Third-party APIs

Intent A

Intent B

Intent C

Intent D

Intent E

Response Data

Web Server

Generate Message

Line Cloud

Webhook

Intent: weather

Slots: {locate: 台北, date: today}

Third-party APIs

Weather API

Intent B

Intent C

Intent D

Intent E

Fetch Weather Data

今天台北天氣如何?

NLU

Web Server

Line Cloud

Third-party APIs

Weather API

Intent B

Intent C

Intent D

Intent E

Response Data

台北今天天氣晴,室溫 28 度

Web Server

Generate Message

Send Message to User

Line Cloud

Webhook

Intent: music

Slots: {artist: 五月天,

track: 派對動物}

Third-party APIs

Weather API

KKBOX Open API

Intent C

Intent D

Intent E

Fetch Music Data

播放五月天的派對動物

NLU

Web Server

Line Cloud

Third-party APIs

Weather API

KKBOX Open API

Intent C

Intent D

Intent E

Response Data

Web Server

Generate Message

Send Message to User

Develop Chatbot

Step by Step

Step.1

Register a LINE channel

Step.2

Build a web server

Chatbot Framework

  • Node.js
  • Cross Platform

index.js

const express = require('express')
const bodyParser = require('body-parser')
const {LineBot} = require('bottender')
const {registerRoutes} = require('bottender/express')

const {lineHandler} = require('./handler')
const config = require('../config')

const server = new express()

server.use(
    bodyParser.json({
        verify: (req, res, buf) => {
            req.rawBody = buf.toString()
        }
    })
)

const bots = {
    line: new LineBot(config.line).onEvent(lineHandler)
}

registerRoutes(server, bots.line, {path: '/line'})

server.listen(process.env.PORT || 5000, () => {
    console.log('server is listening on 5000 port...')
})
const {LineHandler} = require('bottender')

exports.lineHandler = new LineHandler()
    .onText(async context => {
            const text = context.event.text
            const reply = text
            await context.replyText(reply)
        }
    )

handler.js

Setting webhook

Result

Step. 3

Add NLU feature

Nature Language Understanding

  • Rule-based
  • Default IDS module skill
  • Can add custom skill
const config = require('../../config')
const axios = require('axios')
const md5 = require('md5')

class Olami {
    constructor(appKey = config.olami.appKey, appSecret = config.olami.appSectet, inputType = 1) {
        this.URL = 'https://tw.olami.ai/cloudservice/api'
        this.appKey = appKey
        this.appSecret = appSecret
        this.inputType = inputType
    }

    nli(text, cusid = null) {
        const timestamp = Date.now()
        return axios.post(this.URL, {}, {
            params: {
                appkey: this.appKey,
                api: 'nli',
                timestamp: timestamp,
                sign: md5(`${this.appSecret}api=nliappkey=${this.appKey}timestamp=${timestamp}${this.appSecret}`),
                cusid: cusid,
                rq: JSON.stringify({'data_type': 'stt', 'data': {'input_type': this.inputType, 'text': text}})
            }
        }).then(response => {
            return response.data.data.nli[0].desc_obj.result
        })
    }
}

module.exports = new Olami()

Update handler.js

const {LineHandler} = require('bottender')
const olami = require('./nlp/Olami')

exports.lineHandler = new LineHandler()
    .onText(async context => {
            const text = context.event.text
            const reply = await olami.nli(text)
            await context.replyText(reply)
        }
    )

Result

Step. 4

Add custom skill

Add music skill

  1. 播放<artist_name>的歌<{@=music_play_artist}>
  2. 播放<album_name>專輯的歌<{@=music_play_album}>
  3. 播放<track_name><{@=music_play_track}>
  4. 播放<keyword>類型的歌<{@=music_play_playlist}>

artist_name, album_name, track_name, keyword

Intent

  1. music_play_artist
  2. music_play_album
  3. music_play_track
  4. music_play_playlist

Figure out NLI API response

{
   "nli":[
      {
         "desc_obj":{
            "status":0
         },
         "semantic":[
            {
               "app":"music_kkbox",
               "input":"播放動漫歌曲類型的歌",
               "slots":[
                  {
                     "name":"keyword",
                     "value":"動漫歌曲"
                  }
               ],
               "modifier":[
                  "music_play_playlist"
               ],
               "customer":"59e031f7e4b0a8057efdce99"
            }
         ],
         "type":"music_kkbox"
      }
   ]
}

Then use KKBOX Open API

Search API response

{
    "playlists": {
        "data": [
            {
                "id": "OtY2I4ebPHGasNyABp",
                "title": "動漫歌曲嚴選集",
                "description": "嚴選「蠟筆小新」、「火影忍者」、「刀劍神域 」、「死神BLEACH」、「進擊的巨人」等多部著名動畫歌曲。★世界首次,歡樂滿載的蠟筆小新特展,累積台北、高雄兩站的超人氣,台灣巡迴將進入最終站台中跟大家過寒假囉!馬上購票 http://avextw.kktix.cc/events/shinchan-taichung",
                "url": "https://event.kkbox.com/content/playlist/OtY2I4ebPHGasNyABp",
                "images": [
                    {
                        "height": 300,
                        "width": 300,
                        "url": "https://i.kfs.io/playlist/global/34601v1/cropresize/300x300.jpg"
                    },
                    {
                        "height": 600,
                        "width": 600,
                        "url": "https://i.kfs.io/playlist/global/34601v1/cropresize/600x600.jpg"
                    },
                    {
                        "height": 1000,
                        "width": 1000,
                        "url": "https://i.kfs.io/playlist/global/34601v1/cropresize/1000x1000.jpg"
                    }
                ],
                "updated_at": "2016-12-16T03:40:47+00:00",
                "owner": {
                    "id": "Ooerjv5-p-TJsFGLg5",
                    "url": "https://www.kkbox.com/tw/profile/Ooerjv5-p-TJsFGLg5",
                    "name": "KKBOX 日語小編",
                    "description": "",
                    "images": [
                        {
                            "height": 75,
                            "width": 75,
                            "url": "https://i.kfs.io/muser/global/94563302v1/cropresize/75x75.jpg"
                        },
                        {
                            "height": 180,
                            "width": 180,
                            "url": "https://i.kfs.io/muser/global/94563302v1/cropresize/180x180.jpg"
                        },
                        {
                            "height": 300,
                            "width": 300,
                            "url": "https://i.kfs.io/muser/global/94563302v1/cropresize/300x300.jpg"
                        }
                    ]
                }
            }...
        ],
        "paging": {
            "offset": 0,
            "limit": 50,
            "previous": null,
            "next": "https://api.kkbox.com/v1.1/search?limit=50&q=%E5%8B%95%E6%BC%AB%E6%AD%8C%E6%9B%B2&territory=TW&type=playlist&offset=50"
        },
        "summary": {
            "total": 75
        }
    },
    "paging": {
        "offset": 0,
        "limit": 50,
        "previous": null,
        "next": "https://api.kkbox.com/v1.1/search?limit=50&q=%E5%8B%95%E6%BC%AB%E6%AD%8C%E6%9B%B2&territory=TW&type=playlist&offset=50"
    },
    "summary": {
        "total": 75
    }
}

Integrate them!

Line Cloud

Webhook

Intent: music

Slots:

{keyword: 動漫歌曲}

Third-party APIs

Weather API

KKBOX Open API

Intent C

Intent D

Intent E

Fetch Music Data

播放動漫歌曲類型的歌

NLU

Web Server

Line Cloud

Third-party APIs

Weather API

KKBOX Open API

Intent C

Intent D

Intent E

Response Data

Web Server

Generate Message

Send Message to User

Result

Step. 5

Deployment

Deploy to Heroku

Well done!

More details in following resources

zaoldyeck @

Vincent Chiang @

江品陞 @

Slide @

Source Code @

Blog @

zaoldyeck @

Vincent Chiang @

江品陞 @

Slide @

Source Code @

Blog @

And LINE Bot Workshop

How to quickly build a chatbot service

By zaoldyeck

How to quickly build a chatbot service

  • 653
Loading comments...

More from zaoldyeck