开发Hubot聊天机器人

大家所熟知的智能聊天机器人,比如:微软小冰、Apple Siri、Google Now、IBM Watson等。微信自动回复、微信服务号里的客服Bot也都算是简单的实例。聊天机器人(Dialog System)主要实现方式有:基于人工模板(比如AIML)、基于搜索技术(比如ElasticSearch)、基于深度学习。从零实现这样的系统是很复杂的。

开源的ChatOps机器人:
1.[url=https://hubot.github.com/]Hubot[/url]:CoffeeScipt编写
2.[url=https://www.lita.io/]Lita[/url]:Ruby编写
3.[url=http://errbot.io/]Errbot[/url]:Python编写
[img]http://dl2.iteye.com/upload/attachment/0120/4886/05f0cb93-289d-3fd6-9b18-b664d7fc43c6.jpg[/img]
[url=https://www.pagerduty.com/blog/what-is-chatops/]So, What is ChatOps? And How do I Get Started?[/url]
[url=http://nordicapis.com/12-frameworks-to-build-chatops-bots/]12+ Frameworks to Build ChatOps Bots[/url]

[b]Hubot是由Github开发的开源聊天机器人,基于Node.js采用CoffeeScript编写。[/b]
Hubot [url=https://hubot.github.com/]https://hubot.github.com/[/url]
Hubot Scripts [url=https://github.com/hubot-scripts]https://github.com/hubot-scripts[/url]
Hubot Control [url=https://github.com/spajus/hubot-control]https://github.com/spajus/hubot-control[/url]

可以借助Hubot开发Chatbot来自动化的完成想要一切自动化任务,比如:
-运维自动化(编译部署代码、重启机器,监控服务器运行情况,自动修复Bug等)
-外部服务交互(管理Redmine、集成Jenkins、监视Zabbix等)
-定时获取天气预报
-随机订餐
-聊天机器人等等。
[img]http://dl2.iteye.com/upload/attachment/0120/4888/2193617c-9b79-3d28-91c2-1535de15f2c3.png[/img]

官方文档里有详细的使用说明,[url=https://hubot.github.com/docs/]https://hubot.github.com/docs/[/url],这里只做一个摘要。
Hubot Scripts里有大量的现成脚本可以用,也是自己编写脚本的最好sample。

[img]http://dl2.iteye.com/upload/attachment/0120/5867/d271c6db-3753-393b-ae7c-68408fcac6ce.png[/img]

[color=blue][b](一)安装[/b][/color]
运行Hubot需要以下软件支持:
[list]
[*]Node.js
[*]Redis 默认存贮数据
[*]CoffeeScript
[*]Yeoman
[*]generator-hubot 生成Hubot骨架工程
[/list]
[quote]C:\Users\rensanning>node -v
v0.12.8
C:\Users\rensanning>npm -v
2.14.9
C:\Users\rensanning>npm install -g yo generator-hubot
C:\Users\rensanning>npm list -g generator-hubot yo[/quote]

[color=blue][b](二)创建自己的bot[/b][/color]
[quote]C:\Users\rensanning>cd d:/
D:\>mkdir hubotsample
D:\>cd hubotsample
D:\hubotsample>yo hubot
? Owner RenSanNing
? Bot name okbot
? Description A sample hubot
? Bot adapter campfire[/quote]
默认提供了campfire和shell的adapter,其他的需要通过npm下载hubot-
也可以通过参数直接生成:
[quote]yo hubot [email protected] --name=foobot --description="Foo Bot" --adapter=shell[/quote]

项目结构:
[list]
[*]bin/ 运行脚本
[*]node_modules 应用的包文件
[*]scripts 存放自定义脚本
[*]external-scripts.json 应用的外部脚本
[*]hubot-scripts.json *** 该文件已经无用,可以删除
[*]package.json 项目全局配置信息
[/list]

[color=blue][b](三)运行bot[/b][/color]

[quote]D:\hubotsample>bin\hubot -v
2.19.0
D:\hubotsample>bin\hubot -h
Usage hubot [options]

Available options:
-a, --adapter ADAPTER The Adapter to use
-c, --create PATH Create a deployable hubot
-d, --disable-httpd Disable the HTTP server
-h, --help Display the help information
-l, --alias ALIAS Enable replacing the robot's name with alias
-n, --name NAME The name of the robot in chat
-r, --require PATH Alternative scripts path
-t, --config-check Test hubot's config to make sure it won't fail at startup
-v, --version Displays the version of hubot installed[/quote]
-a 指定Adapter(默认是shell)
-d 关闭HTTP服务(默认是开启的)
-c deprecated 使用yeoman

采用默认的shell adapter
[quote]D:\hubotsample>bin\hubot[/quote]
指定adapter
[quote]D:\hubotsample>bin\hubot -a shell[/quote]

[quote]okbot> help
usage:
history
exit, \q - close shell and exit
help, \? - print this usage
clear, \c - clear the terminal screen[/quote]

[quote]okbot> okbot help
okbot> Shell: okbot adapter - Reply with the adapter
okbot animate me - The same thing as `image me`, except adds a few parameters to try to return an animated GIF instead.
okbot echo - Reply back with
okbot help - Displays all of the help commands that Hubot knows about.
okbot help - Displays all help commands that match .
okbot image me - The Original. Queries Google Images for and returns a random top result.
okbot map me - Returns a map view of the area returned by `query`.
okbot mustache me - Adds a mustache to the specified URL or query result.
okbot ping - Reply with pong
okbot pug bomb N - get N pugs
okbot pug me - Receive a pug
okbot the rules - Make sure hubot still knows the rules.
okbot time - Reply with current time
okbot translate me - Searches for a translation for the and then prints that bad boy out.
okbot translate me from into - Translates from into . Both and are optional
ship it - Display a motivation squirrel

okbot ping
okbot> PONG

okbot echo 你好!
okbot> 你好!

okbot time
okbot> Server time is: Fri Sep 30 2016 11:05:24 GMT+0800 (中国 (标准时间))[/quote]

***所有的输入都会被记录在.hubot_history文件里。

[color=blue][b](四)编写脚本[/b][/color]
编写的自定义脚本要放在scripts中,可以是.coffee或.js文件。

scripts/hello.coffee
# Description:
# This is a test.
#
# Commands:
# okbot helo - Reply with world!

module.exports = (robot) ->
robot.respond /hello/i, (msg) ->
msg.send "world!"

[quote]okbot hello
okbot> world![/quote]

因为Hubot要解析脚本文件,提供help帮助,所以脚本文件开头的注释是规范的,
第一行必须是注释“# Description:”(其他的可以没有),否则会有警告:
[quote]hello.coffee is using deprecated documentation syntax[/quote]

Hubot同时也支持js,比如:
scripts/hello2.js
// Description:
// This is a test2.
// Commands:
// okbot helo - Reply with world!

module.exports = function(robot) {
robot.respond(/hi/i, function(msg){
msg.send("world2!");
});
}

[quote]okbot hi
okbot> world2![/quote]

[b]Respond vs Hear[/b]
[list]
[*]respond只监听直接发送给机器人的消息,需要指定机器人名称
[*]hear可以监听任何消息
[/list]
[quote]MYHUBOT xxx
myhubot xxx
@myhubot xxx
myhubot: xxx[/quote]

[b]Send vs Reply[/b]
[list]
[*]send会将消息发送给所有人
[*]reply会将消息回复给指定的人
[/list]

[b]Random[/b]
msg对象有一个random方法,可以从之后的数组对象中随机提取一个元素
[quote]msg.send msg.random arrayObject[/quote]

hubot Scripts Explained
[url=http://theprogrammingbutler.com/blog/archives/2011/10/28/hubot-scripts-explained/]http://theprogrammingbutler.com/blog/archives/2011/10/28/hubot-scripts-explained/[/url]

[color=blue][b](五)安装脚本[/b][/color]
Hubot 有一大堆现成的脚本,可以集成各种服务。
[quote]D:\hubotsample>npm search hubot-scripts github
D:\hubotsample>npm install --save hubot-plusplus
[email protected] node_modules\hubot-plusplus
├── [email protected]
├── [email protected]
└── [email protected][/quote]

将package-name添加到external-scripts.json
[quote]"hubot-plusplus"[/quote]
[quote]okbot> ruby++
okbot> ruby has 1 point
okbot> java--
okbot> java has -1 points[/quote]

[color=blue][b](六)hubot-script实例[/b][/color]

[b]定时脚本[/b]
scripts/cron.coffee
cronJob = require('cron').CronJob

module.exports = (robot) ->
send = (room, msg) ->
response = new robot.Response(robot, {user : {id : -1, name : room}, text : "none", done : false}, [])
response.send msg

new cronJob('0 * * * * *', () ->
currentTime = new Date
send '#your-channel-name', "current time is #{currentTime.getHours()}:#{currentTime.getMinutes()}."
).start()

[quote]D:\hubotsample>npm install cron --save
D:\hubotsample>bin\hubot -a shell[/quote]

[b]http请求[/b]
scripts/googleGEO.coffee
module.exports = (robot) ->
robot.hear /location (.*)/, (msg) ->
request = robot.http("https://maps.googleapis.com/maps/api/geocode/json")
.query(address: msg.match[1])
.get()
request (err, res, body) ->
json = JSON.parse body
location = json['results'][0]['geometry']['location']

msg.send "#{location['lat']}, #{location['lng']}"

[quote]okbot> location Beijing
okbot> 39.904211, 116.407395[/quote]

[b]抓取数据(request, cheerio)[/b]
scripts/title.coffee
request = require 'request'
cheerio = require 'cheerio'

module.exports = (robot) ->
robot.respond /title (.*)/i, (msg) ->
url = msg.match[1]
options =
url: url
timeout: 2000
headers: {'user-agent': 'node title fetcher'}

request options, (error, response, body) ->
$ = cheerio.load body
title = $('title').text().replace(/\n/g, '')
msg.send(title)

[quote]D:\hubotsample>npm install --save request
D:\hubotsample>npm install --save cheerio
D:\hubotsample>bin\hubot -a shell

okbot> okbot title http://github.com
okbot> How people build software · GitHub
okbot> okbot title http://www.google.com
okbot> Google[/quote]

[b]http应答(httpd)[/b]
scripts/version.coffee
module.exports = (robot) ->
robot.router.get "/version", (req, res) ->
res.end robot.version


访问http://localhost:8080/version。
默认端口是8080,可以修改环境变量:export PORT=8080

Hubot大量依赖环境变量来配置脚本,所以一般都做一个启动脚本:
[quote]#!/bin/sh
export HUBOT_ENV_TEST_VAR=""
bin/hubot -a twitter -n testbot[/quote]
[quote]@echo off
SET HUBOT_ENV_TEST_VAR=""
bin\hubot.cmd -a twitter -n testbot[/quote]
脚本中的使用:
[quote]TEST_VAR = process.env.HUBOT_ENV_TEST_VAR[/quote]

[b]捕获所有未处理信息[/b]
scripts/catchAll.coffee
module.exports = (robot) ->
robot.catchAll (res) ->
res.send "Nothing Found:#{res.message.text}"


hubotスクリプトの書き方とサンプル集
[url=http://blog.fumiz.me/2012/08/05/hubot-irc-bot-script/]http://blog.fumiz.me/2012/08/05/hubot-irc-bot-script/[/url]
编写 Hubot Scripts
[url=http://scarletsky.github.io/2016/05/02/write-your-own-hubot-scripts/]http://scarletsky.github.io/2016/05/02/write-your-own-hubot-scripts/[/url]

[color=blue][b](七)自定义Adapter[/b][/color]
hubot默认提供两种adapter:shell、campfile
shell用于开发调试,campfile以外的Chat Service也都有开源的实现。

[b]Adapter基本构成[/b]

新建文件 \node_modules\hubot\src\adapters\SampleAdapter.coffee
class SampleAdapter extends Adapter

send: (envelope, strings...) ->
@robot.logger.info "Send"

run: ->
@robot.logger.info "Run"

exports.use = (robot) ->
new SampleAdapter robot


修改文件 \node_modules\hubot\src\robot.coffee
[quote]HUBOT_DEFAULT_ADAPTERS = [
'campfire'
'SampleAdapter'
'shell'
][/quote]

启动bot
[quote]D:\hubotsample>bin\hubot -a SampleAdapter[/quote]

* 所有的Adapter必须继承自Adapter
* Adapter中最重要的两个方法是send和run,其他方法比如emote、reply、topic、play等在特定场景下才需要。
* run方法是bot启动时执行
* send方法是回复信息时执行
* 父类 adapter.coffee 里有详细的方法说明 https://github.com/github/hubot/blob/master/src/adapter.coffee
* Adapter名必须是:src\adapters里的文件名 & robot.coffee的HUBOT_DEFAULT_ADAPTERS里定义的名 或者和 hubot-#{adapter} 一致

[b]Chat服务的Adapter[/b]
{Adapter, TextMessage} = require 'hubot'
{EventEmitter} = require 'events'

class MyChatAdapter extends Adapter
send: (envelope, strings...) ->
@bot.send str for str in strings

run: ->
options =
token: process.env.HUBOT_CHAT_TOKEN
rooms: process.env.HUBOT_CHAT_ROOMS
account: process.env.HUBOT_CHAT_ACCOUNT

bot = new MyChatStreaming options, @robot

bot.on 'message', (userId, userData, message) ->
user = @robot.brain.userForId userId, userData
@receive new TextMessage user, message

bot.listen()

exports.use = (robot) ->
new MyChatAdapter robot

class MyChatStreaming extends EventEmitter
constructor: (options, @robot) ->
@token = options.token
@rooms = options.rooms.split(",")
@account = options.account

send: (message) ->
# Send data to your chat service

listen: ->
# Get messge data from chat service
# @emit 'message', user, message

具体可以参考: https://github.com/github/hubot/blob/master/src/adapters/campfire.coffee

[b]扩展robot的方法:[/b]
\node_modules\hubot\src\adapters\incircle.coffee
class TestXXX extends Adapter
constructor: (robot) ->
super robot
robot.hearXXX = (options, callback) ->
robot.listeners.push new TextListener(robot, "@XXXmessage", options, callback)


\scripts\testbot.coffee
module.exports = (robot) ->
robot.hearXXX (msg) ->
msg.send "#{JSON.stringify msg}"


[color=blue][b](八)微信adapter[/b][/color]
[url=https://github.com/KasperDeng/Hubot-WeChat]https://github.com/KasperDeng/Hubot-WeChat[/url]

主要机制是hack网页版微信协议,先用手机登录微信帐号,然后模拟网页版微信登录,这样就可以接受微信消息了。

[list]
[*]npm install hubot-weixin --save
[*]手机端登录微信
[*]打开网页微信:web.weixin.qq.com
[*]手机扫描登录
[*]控制台查看如下信息 /node_modules/hubot-weixin/config.yaml
cookie: Uin: Sid: Skey: DeviceID:
[*]bin\hubot.cmd -n bot -l / -a weixin
[/list]

参考:
[url=http://www.tmtpost.com/1505126.html]正在吃掉世界的Bot:它从哪里来,会到哪里去?[/url]
[url=http://www.infoq.com/cn/news/2015/06/Hubot-GitHub-chatting]Hubot:来自GitHub的聊天机器人[/url]
[url=http://gihyo.jp/dev/serial/01/hubot/0001]GitHub社謹製! bot開発・実行フレームワーク「Hubot」[/url]
[url=https://ngs.io/2014/06/13/tdd-hubot-scripts/]TDD Hubot scripts with gulp+mocha[/url]
[url=http://iambowen.github.io/2014/01/27/use-hubot-in-skype/]在Skype中使用Hubot[/url]
[url=http://qiita.com/bouzuya/items/c7d0ad80c357aab6b696]http://qiita.com/bouzuya/items/c7d0ad80c357aab6b696[/url]

你可能感兴趣的:(杂七杂八)