打造自己的聊天机器人Hubot

  记得以前看钢铁侠的时候,看到有一个小罗伯特有一个私人的语音智能系统贾维斯,协助钢铁侠处理各种事务、计算各种数据和信息,相当的方便,让我欣羡不已。于是我就想着有一个自己的机器人帮我处理事情,正好在网上看到GitHub的一个开源聊天机器人Hubot,学习着用了一下,虽然没有贾维斯那么狂拽酷眩,但是毕竟是属于自己的Hubot。

一、介绍Hubot

  Hubot是GitHub的开源聊天机器人,前身主要是GitHub用来完成一些自动化的任务,比如部署站点、自动处理任务(别问我,笔者也不知道是什么任务)等。随着使用Hubot使用越来越频繁,它也变得更健壮更智能。为了帮助更多的人,GitHub将它重写并且开源。
  Hubot采用CoffeeScript语言开发,这是一套类似于JavaScript的语言,但是更加的简洁,很容易就能够读懂。目前Hubot原生带有一些功能,比如搜索图片、翻译、地图服务,还可以自定义插件脚本,同时还能使用别人开发好的插件。Hubot插件库中大概有一百多个插件。
  要运行Hubot,需要对nodejs和npm有一些了解,最好还装有redis服务。推荐使用Git工具进行以下操作。

hello

二、安装Hubot

  下面就开始在电脑上安装我们的Hubot,默认读者们把nodejs和npm都安装好了。

一些准备工作

  由于官方支持使用CoffeeScript语言编写代码,所以先安装脚本编译器和Hubot的框架

1
npm install yo generator-hubot coffee-script -g

  接着创建项目目录,这里的目录名建议跟Hubot的名称保持一致,这里我的Hubot叫jarvis

1
2
mkdir jarvis
cd jarvis

开始安装

  在git命令行中输入如下命令,开始我们的安装过程。

1
yo hubot

  出现了如下安装提示界面,输入我们的所有者、Hubot名称和描述等。

step1

谢小飞博客专用防爬虫链接,想要看最新的前端博客请点这里

  输好后会根据你输入的创建对应的配置文件,然后进行处理,并且安装一些模块文件等。等待安装完成就可以使用了。

step2

配置文件

  安装完后启动Hubot,在命令行输入bin/hubot,看到有报错:

谢小飞博客专用防爬虫链接,想要看最新的前端博客请点这里

error

  出现这个报错是因为没有配置heroku和redis服务没有开启。可以忽略,也可以在external-script.json中把hubot-heroku-keepalive和hubot-redis-brain注释掉。

  然后把/scripts目录下的example.coffee打开,将下面两行代码中的#删除:

1
2
#   robot.hear /badger/i, (res) ->
# res.send "Badgers? BADGERS? WE DON'T NEED NO STINKIN BADGERS"

  然后再次启动,这时候就能看到我们的jarvis正常启动。在命令行里输入jarvis ping,如果能看到jarvis回复pong,Hubot就安装完成了。

三、脚本

  首先查看一下我们可以使用哪些命令。在命令行里输入jarvis help,可以看到所有可以使用的命令以及描述,比如map、pug、time、image命令等。在安装过其他插件后可以使用同样的命令查看新增加的命令。
  需要注意的是,这里的jarvis help中的jarvis是笔者的自定义机器人名称,读者需要替换成自己的机器人名称,比如myhubot help

自定义脚本

  Hubot是基于事件监听机制的,我们可以为他自定义事件发生时的回调,当触发这个事件时执行回调。
  在项目目录下有一个/scripts目录,存放的就是我们自己定义的脚本,像之前的example.coffee就是一个小的demo。
  我们新建一个greet.coffee,输入一下代码:

1
2
3
module.exports = (robot) ->
robot.hear /greet/i, (res) ->
res.send "Hello,My Master"

谢小飞博客专用防爬虫链接,想要看最新的前端博客请点这里

  每个自定义的脚本都需要导出一个函数function,默认有一个robot的参数。这里的module.exports = (robot) ->就相当于JavaScript中的module.exports = function(rebot){}。
  这里的robot的hear方法相当于一个监听事件,它有两个参数,第一个是一个正则表达式,只要匹配了这个正则表达式就执行下面的回调函数,回调函数中我们通过send方法返回一个字符串。
  再次重启我们的Hubot,输入jarvis greet,会看到Hubot跟我们打招呼了。

添加命令到help中

  但是这时候使用help命令,没有看到可以使用greet命令的提示,怎么样将我们自定义的greet命令添加到help中去呢?如下修改我们的greet.coffee脚本,添加头部注释说明。

1
2
3
4
5
6
7
# Description:
# Greet To Master
# Commands:
# hubot greet - Greet To Master
module.exports = (robot) ->
robot.hear /greet/i, (res) ->
res.send "Hello,My Master"

添加路由地址

  Hubot不仅能通过命令行监听命令,还能够通过路由监听地址。
  我们新建一个文件router.coffee。

1
2
3
module.exports = (robot) ->
robot.router.get "/foo", (req, res) ->
res.end "bar"

  这时候我们打开浏览器输入http://localhost:8080/foo就能看到输出bar。这里的端口默认识8080,如果需要更改端口可以在启动Hubot的时候通过PORT=8888 bin/hubot命令设置端口号

自定义脚本发送异步

  Hubot不仅可以静态的设置要回复的内容,还能够动态地通过异步数据返回对应的内容,比如这里我们通过Hubot来查询城市的天气。
  我们新建一个weather.coffee脚本(需要申请openweathermap.org的APPID)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# Description:
# Tells the weather
#
# Configuration:
# HUBOT_WEATHER_API_URL - Optional openweathermap.org API endpoint to use
#
# Commands:
# weather in <location> - Tells about the weather in given location
#
# Author:
# Corner

process.env.HUBOT_WEATHER_API_URL ||=
'http://openweathermap.org/data/2.5/weather?units=imperial&appid=[your appid]&q='

module.exports = (robot) ->
robot.hear /weather in (\w+)/i, (msg) ->
city = msg.match[1]
url = process.env.HUBOT_WEATHER_API_URL + city
msg.robot.http(url).get() (err, res, body) ->
data = JSON.parse(body)
weather = [ "#{Math.round(data.main.temp)} degrees" ]
for w in data.weather
weather.push w.description
msg.send "It's #{weather.join(', ')} in #{data.name}, #{data.sys.country}"

  process.env允许我们设置一个环境变量,这里我们自定义了一个天气url接口的变量。在CoffeeScript中x ||=yx = (x != null) ? x : y的简写方式,代表了如果x没有赋值,就取y的值,保证了x一定有值。
  通过调用msg.robot.http()方法来发送异步请求,在回调方法中先解析成JSON格式,然后对数据进行拼接处理,再用msg返回。
  再次启动Hubot,输入jarvis weather in Suzhou就能查到对应城市的天气了。

处理没有识别的信息

  有时候,我们输入的信息没有被任何脚本的正则捕获到,我们还是希望对这些信息进行处理,那么可以新建一个catchAll.coffee脚本。

1
2
3
module.exports = (robot) ->
robot.catchAll (res) ->
res.send "Sorry My Master,I do not know what you are saying"

谢小飞博客专用防爬虫链接,想要看最新的前端博客请点这里

四、插件

  虽然我们写了很多的脚本,但是有的功能已经有现成的,可以直接使用。

自带插件

  Hubot自带了几个插件,让我们来看一下。

hubot-pugme

  这个插件有两个命令,一个是hubot pug me,另一个是hubot pug bomb [number]
  输入第一个命令看到出现一个链接,在浏览器中打开我们看到了一只可爱的哈巴狗,输入第二个链接,我们把[number]改成随意的一个数字6,我们看到出来6张照片,打开是6张哈巴狗的照片,没错,这个插件就是给你看狗狗的(难道是狗狗爱好者做的?)。
  我顿时就忍不住吐槽了,居然还标榜自己是最重要的Hubot插件(Pugme is the most important hubot script),简直鸡肋啊。

hubot-google-images

  这个插件有两个命令,一个是hubot image me,另一个是hubot animate me
  官网解释它是用来搜索图片地址的,那么就让我们用官网的例子来尝试一下吧jarvis image me bananas
  很遗憾的是Hubot提醒我这个谷歌的图片搜索引擎不能用了,要设置自定义的引擎。再看了一下官方的文档,这个谷歌图片搜索引擎还要注册,并且每天只能免费搜索一百次,超过了还要收费,有点坑啊。

hubot-maps

  这个插件看样子是地图插件,看了一下官方说明,也有两个命令hubot map mehubot direction me。抱着希望再次尝试了一下jarvis map me wuxi,幸运的是结果出来了,是一个地图的地址,再看了一下是谷歌地图的地址,那不用说了,绝壁要科学上网了。

下载插件

  自带的插件用完了,笔者顿时累觉不爱了,想着去网上找找有没有其他的插件。
  笔者在网上看到能够使用npm search hubot-scripts github命令查看Hubot的插件,但是试了一下老是报错,求好心人告知。
  于是又找到了Hubot在线插件库的链接,进去看到确实有不少插件。详细的插件用法本文不再赘述,读者可以自行根据需要下载使用,使用前需要把插件名称添加到/external-scripts.json文件中去

五、总结

  经过这几天对Hubot的学习,对Hubot我有以下几点感悟:

  • Hubot确实能够做一些自动化的工作,但是需要我们去写脚本配置
  • Hubot能够聊天但是没有很智能,基于事件监听的基础上,只能够设置几种固定的回复语句,实现类似于京东JIMI的效果,距离电影中的效果还差的很远。
  • 插件数量不多,只有一百多个,实用的插件数量更少,很多插件都比较的鸡肋,不具实用性。
  • 很多插件还不能用,比如Hubot-WeChat据说能够集成到微信,我用了一直有报错,希望有好心人成功了交流下经验。

谢小飞博客专用防爬虫链接,想要看最新的前端博客请点这里


本网所有内容文字和图片,版权均属谢小飞所有,任何媒体、网站或个人未经本网协议授权不得转载、链接、转贴或以其他方式复制发布/发表。如需转载请关注公众号【前端壹读】后回复【转载】。