はじめに
ChatOpsの手始めとして、ChatBotで会話APIを実装してみました。
・UserLocal 人工知能ボットAPI
・CotoGoto::Noby API
・Docomo 雑談会話API
ChatworkでもSlackでも手順は同じで、hubotのオプションでどちらかを選べばよいだけです。
事前準備
Chat側
- Chatwork
bot用のユーザを新規作成し、API申請をする。
APIキーとルームIDを取得 - Slack登録
Apps & IntegrationでhubotをインストールしてAPIキーを取得
会話API側
- UserLocal
無料登録してAPI Key取得 - CotoGoto
無料登録してAPI Key取得 - Docomo
色々な機能があるので、最低限の会話APIであれば即API Key発行されますが、
追加の機能によってはサイトの審査や法人登録が必要です。
サーバ設定(EC2で構築)
モジュール
// 最新のNode.jsを入れるためにNVMから
$ git clone https://github.com/creationix/nvm.git ~/.nvm
$ source ~/.nvm/nvm.sh
$ vi .bash_profile
# nvm
if [[ -s ~/.nvm/nvm.sh ]] ; then
source ~/.nvm/nvm.sh ;
fi
$ nvm ls-remote
$ nvm install 7.4.0
$ nvm use v7.4.0
$ node -v
$ sudo yum install -y npm redis
$ sudo npm install -g hubot coffee-script yo generator-hubot
$ cd /var/www/bot
$ mkdir hubot-cw
$ cd hubot-cw
$ yo hubot
全てEnterでOK
$ npm install hubot-chatwork --save
$ npm install forever request --save
./scripts以下へ新規作成
- hubot.coffee
module.exports = (robot) ->
status = {}
robot.respond /(.*)/i, (res) ->
message = res.match[1]
if message.length == 0
res.reply "What?"
lunch = ['コンビニ', '中華', 'イタリアン', '和食', 'カレー', '昨日と同じ']
robot.respond /お昼/i, (res) ->
res.reply res.random lunch
robot.respond /site (.*)/i, (msg) ->
url = msg.match[1]
options =
url: url
timeout: 2000
headers: {'user-agent': 'node title fetcher'}
request = require 'request'
cheerio = require 'cheerio'
request options, (error, response, body) ->
$ = cheerio.load body
title = $('title').text().replace(/\n/g, '')
msg.reply(title)
- api_userlocal.coffee
module.exports = (robot) ->
robot.respond /ul (.*)/i, (res) ->
url = "https://chatbot-api.userlocal.jp/api/chat"
api_key = process.env.HUBOT_UL_API_KEY
message = res.match[1]
params = {
"message": message,
"key": api_key
}
robot.http(url).query(params).get() (err, response, body) ->
return response.send "Encountered an error :( #{err}" if err
body = JSON.parse(body)
res.reply "#{body.result}"
- api_cotogoto.coffee
module.exports = (robot) ->
robot.respond /cg (.*)/i, (res) ->
url = "https://www.cotogoto.ai/webapi/noby.json"
api_key = process.env.HUBOT_CG_API_KEY
message = res.match[1]
params = {
"text": message,
"app_key": api_key
}
robot.http(url).query(params).get() (err, response, body) ->
return response.send "Encountered an error :( #{err}" if err
body = JSON.parse(body)
res.reply "#{body.text}"
- api_docomo.coffee
getTimeDiffAsMinutes = (old_msec) ->
now = new Date()
old = new Date(old_msec)
diff_msec = now.getTime() - old.getTime()
diff_minutes = parseInt( diff_msec / (60*1000), 10 )
return diff_minutes
module.exports = (robot) ->
robot.respond /d (.*)/i, (msg) ->
HUBOT_D_API_KEY = process.env.HUBOT_D_API_KEY
message = msg.match[1]
return unless HUBOT_D_API_KEY && message
## ContextIDを読み込む
KEY_DOCOMO_CONTEXT = 'docomo-talk-context'
context = robot.brain.get KEY_DOCOMO_CONTEXT || ''
## 前回会話してからの経過時間調べる
KEY_DOCOMO_CONTEXT_TTL = 'docomo-talk-context-ttl'
TTL_MINUTES = 20
old_msec = robot.brain.get KEY_DOCOMO_CONTEXT_TTL
diff_minutes = getTimeDiffAsMinutes old_msec
## 前回会話してから一定時間経っていたらコンテキストを破棄
if diff_minutes > TTL_MINUTES
context = ''
url = 'https://api.apigw.smt.docomo.ne.jp/dialogue/v1/dialogue?APIKEY=' + HUBOT_D_API_KEY
user_name = msg.message.user.name
request = require('request');
request.post
url: url
json:
utt: message
nickname: user_name if user_name
context: context if context
, (err, response, body) ->
## ContextIDの保存
robot.brain.set KEY_DOCOMO_CONTEXT, body.context
## 会話発生時間の保存
now_msec = new Date().getTime()
robot.brain.set KEY_DOCOMO_CONTEXT_TTL, now_msec
msg.send body.utt
起動設定(常駐化、環境変数設定)
- ./bin/hubotを編集
#!/bin/sh
set -e
ARG1=$1
export PATH="node_modules/.bin:node_modules/hubot/node_modules/.bin:$PATH"
export HUBOT_SLACK_TOKEN=xoxb-xxx
export HUBOT_CHATWORK_TOKEN="xxx"
export HUBOT_CHATWORK_ROOMS="xxx"
export HUBOT_CHATWORK_API_RATE="900" #時間あたりのポーリング回数(4秒に1回)
export HUBOT_UL_API_KEY=xxx
export HUBOT_CG_API_KEY=xxx
export HUBOT_D_API_KEY=xxx
#exec node_modules/.bin/hubot -a chatwork -n mohi
start() {
forever start -c coffee node_modules/.bin/hubot -a chatwork -n mohi
}
stop () {
forever stop -c coffee node_modules/.bin/hubot
}
status() {
forever list
}
restart() {
forever restartall
}
case "$ARG1" in
"stop" )
stop
;;
"restart" )
restart
;;
"start" )
start
;;
"status" )
status
;;
esac
- 起動
$ bin/hubot start
最後に
使い方
「mohi APIオプション 会話内容」
・Coto Goto APIの場合(mohi cg 会話内容)
下記を聞くと教えてくれます。
・ニュース
・おみくじ引く
・○○の天気
・○○の意味を知りたい
・User Localの場合(mohi ul 会話内容)
・Docomo雑談APIの場合(mohi d 会話内容)
今後
今後はDocomoのAPIや他社も利用して、画像認識や形態素解析も実装したあと、
独自で情報を取ってくるものを作りたいと思ってます。