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
- 播放<artist_name>的歌<{@=music_play_artist}>
- 播放<album_name>專輯的歌<{@=music_play_album}>
- 播放<track_name><{@=music_play_track}>
- 播放<keyword>類型的歌<{@=music_play_playlist}>
artist_name, album_name, track_name, keyword
Intent
- music_play_artist
- music_play_album
- music_play_track
- 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
- 1,367