Hubot是一个通用的聊天机器人,能和很多聊天软件集成,比如slack、rockchat、telegram、企业微信、IRC等。
公司用的是企业微信,之前用群机器人和 prometheus 集成,发送各种告警信息,但是群机器人无法接收消息;同时我们想集成进去很多自定义命令,比如发送指令就开始 jenkins build,发送 ansible 指令执行,发送流量图就自动把机房的流量图发过来,这个群机器人就用不成了。所以必须再直接一些,构建一个企业微信的应用。
一、企业微信安装前准备
安装前需要在企业微信中拿到4个信息:
- WECHATWORK_CORP_ID
- WECHATWORK_APP_AGENT_ID
- WECHATWORK_APP_SECRET
- WECHATWORK_AES_KEY
首先联系企业微信管理员新增一个应用:

在“管理后台-我的企业”中可以获得地一个信息,企业 ID 信息,CORP_ID :
拿拿 在“管理后台-应用管理-点击某具体应用-详情”页中可以获得二、三个信息, APP_AGENT_ID 和 APP_SECRET

第四个 AES_KEY 就比较麻烦了,我们进入这个应用,点击配置的图标:

然后进入,点击启用 API 接收

然后设置一下
- url 填写 https://hubot.rendoumi.com/wechatwork/webhook
- Token 点随机获取
- EncodingAESKey 点随机获取,这就是具体的 AESKey 了

然后点击保存,这里必然会失败!没有关系,因为我们还没有装hubot呢。我们把这三个地方先记录下来,随后再来点击保存。
二、Hubot 安装前准备
1、注意上面地址:URL 地址是 https ,然后 hubot 的缺省地址是 http://xxx:8080 ,这样如果前面没有证书卸载的设备,就得搭建一个Nginx(haproxy、traefik)来代理 https 443端口到8080。
2、Hubot 是支持 Coffeescript 和 nodejs 的,从它的 Adapters 网页看
https://hubot.github.com/docs/adapters/development/
里面都是 coffee 味的单箭头函数,导致不太熟悉的八戒以为在 wechatwork module导出的时候也应该用单箭头函数,结果就悲剧了。
所以务必清楚,Adapter 的语法是 js,普通自建自动回复script可以用coffeescript,后面会详细说这一点。
3、安装Hubot必须新建一个普通用户,不能用 root 装
用 root 会导致 nodejs 一堆报错,八戒新建了一个用户 bot,家目录/home/bot,然后再在这下面建立/home/bot/myhubot,在这个目录下安装。
理由是这个如果直接装在这个用户的 home 目录下,会导致这个用户只能有这一个用途了,目录结构太浅,一堆文件
4、Hubot的变量引入都是通过环境变量引入的
所以无论什么wechatwork还是jenkins,都需要通过环境变量导入变量
三、安装Hubot
首先安装nvm,参看文章 Nodejs多版本的安装与管理
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
安装的时候最好加个 https_proxy 代理,因为这个 shell 脚本不翻墙很难下下来。
然后务必关了代理,退出终端并重新进入,安装 nodejs 的最新版本
nvm ls-remote
nvm install v16.13.1
nvm list

确认一下,nodejs 的版本缺省是 v16.13.1
这里千万不要手欠把 npm 的源换成国内的腾讯等,就是国外源
然后安装hubot,并初始化
su - bot
npm install -g yo generator-hubot
mkdir /home/bot/myhubot
cd /home/bot/myhubot
yo hubot
会问几个问题:
- Ower:写自己邮箱就行
- Bot name: bot
- Description: rendoumi corp
- Bot adapter: campfire
注意最后一个,选campfire就好,我们稍后再装wechatwork
_____________________________
/ \
//\ | Extracting input for |
////\ _____ | self-replication process |
//////\ /_____\ \ /
======= |[^_/\_]| /----------------------------
| | _|___@@__|__
+===+/ /// \_\
| |_\ /// HUBOT/\\
|___/\// / \\
\ / +---+
\____/ | |
| //| +===+
\// |xx|
? Owner zhangranrui@rendoumi.com
? Bot name bot
? Description rendoumi corp
? Bot adapter campfire
然后就会是漫长的等待:

最后会报几个警告,不用管,忽略即可。
npm notice created a lockfile as package-lock.json. You should commit this file.
+ hubot-help@1.0.1
+ hubot-google-images@0.2.7
+ hubot-rules@1.0.0
+ hubot-shipit@0.2.1
+ hubot-redis-brain@1.0.0
+ hubot-google-translate@0.2.1
+ hubot-diagnostics@1.0.0
+ hubot-scripts@2.17.2
+ hubot@3.3.2
+ hubot-maps@0.0.3
+ hubot-heroku-keepalive@1.0.3
+ hubot-pugme@0.1.1
added 99 packages from 53 contributors and audited 99 packages in 20.176s
2 packages are looking for funding
run `npm fund` for details
found 1 low severity vulnerability
run `npm audit fix` to fix them, or `npm audit` for details
我们先跑一下,简单测一下功能,我们的bot name输入的是bot
cd /home/bot/myhubot
./bin/hubot
#进入后
bot ping
#得到回应
PONG
这样就装好了 hubot,我们做一下修改,去掉 heroku 和 redis,否则会不停丢出报错信息,但是不要用 npm 去删除这两个包,放着那里备用也不占多少空间的
cd /home/bot/myhubot
vi external-scripts.json
[
"hubot-diagnostics",
"hubot-help",
"hubot-heroku-keepalive",
"hubot-google-images",
"hubot-google-translate",
"hubot-pugme",
"hubot-maps",
"hubot-redis-brain",
"hubot-rules",
"hubot-shipit"
]
#去掉下面两行
hubot-heroku-keepalive
hubot-redis-brain
三、安装微信 Adapter
Adapter 插件,hubot是一套系统,通过各种插件跟各种聊天软件进行交互
微信插件原始地址:https://github.com/billtt/hubot-wechatwork
八戒稍微改了一下:https://github.com/zhangrr/hubot-wechatwork
主要是添加了个自动回应和添加了一些调试信息,否则不知道加载成不成功。
#先装那个老的
cd /home/bot/myhubot
npm install hubot-wechatwork
#覆盖掉老的模块
cd /home/bot/myhubot/node_modules
git clone https://github.com/zhangrr/hubot-wechatwork
启动之前普及一下 hubot 基本知识,hubot 中变量的传入都是通过环境变量导入的,启动测试一下wechatwork
export WECHATWORK_CORP_ID=aaaa
export WECHATWORK_APP_AGENT_ID=bbbb
export WECHATWORK_APP_SECRET=cccc
export WECHATWORK_AES_KEY=dddd
cd /home/bot/myhubot
./bin/hubot -a wechatwork
看到信息,INFO Yunwei: loading wechatwork Adapter,说明启动没啥毛病

然后我们回到企业微信这个应用的应用管理,点击保存接收消息服务器配置,这次就应该能成功了。
测试一下,我们在企业微信中,对这个应用机器人私聊,发个 hi:

再发个help,会冒出一堆信息

然后我们可以试试指令,再发个ping,机器人回PONG,这就算正常工作了

同时我们在终端也可以看到接收到的消息

要注意的命令:
wechatwork 有一条命令 chat create CHATID USER1,USER2,USER3,…
解释一下,是用来建立一个企业微信群聊的,群主默认是第一个人:
chatid 是指一个群聊的 id 号,格式是字母+数字,比如yunwei001,这个一旦创建就无法销毁,会永远保存在企业微信那里,切切记住!!!
user1,user2 这种是员工企业微信的id,通常是用户名全称,比如 zhangrenren,liudaqiang
所以说的时候务必要小心,万万记住 chatid 一旦建立就无法收回。
之后可以调用 sendChatMessage 来给群聊发送消息。

四、准备systemd启动hubot
这样不能每次用个终端启动 hubot 吧,写个 systemd 文件来处理吧
由于我们用到了nvm,这里确实需要一些技巧,cat /etc/systemd/system/hubot.service
[Unit]
Description=Hubot
Requires=network.target
After=network.target
[Service]
Type=simple
WorkingDirectory=/home/bot/myhubot
User=bot
Restart=always
TimeoutStartSec=10
RestartSec=10
; Configure Hubot environment variables, use quotes around vars with whitespace as shown below.
; Environment="HUBOT_SLACK_TOKEN=SLACK_TOKEN"
; Environment="HUBOT_JENKINS_AUTH=pe:x837491lkaflajksdf7"
; Environment="HUBOT_JENKINS_URL=http://192.168.1.90:8080/"
Environment="NODE_VERSION=default"
Environment="WECHATWORK_CORP_ID=aaaa"
Environment="WECHATWORK_APP_AGENT_ID=bbbb"
Environment="WECHATWORK_APP_SECRET=cccc"
Environment="WECHATWORK_AES_KEY=dddd"
ExecStart=/home/bot/.nvm/nvm-exec /home/bot/myhubot/bin/hubot --adapter wechatwork
[Install]
WantedBy=multi-user.target
注意上面,我们指定了环境变量 NODE_VERSION=default,以及最下的 ExecStart,确定用 nvm-exec 引动 node
另外把 wechatwork 所需的4个参数也放进环境变量中,这样重启就可以了
systemctl daemon-reload
systemctl start hubot
五、集成jenkins
准备知识,我们必须在 jenkins 拿到用户名和 token(token是用来代替密码的),用来访问 jenkins
首先登录 jenkins,访问网址:$JENKINS_URL/me/configure,新建一个 API Token,记录下来

用法很简单:token替代密码用于 url 认证即可。
cd /home/bot/myhubot
npm install hubot-jenkins-optimised
#编辑external-scripts.json
vi external-scripts.json
[
"hubot-diagnostics",
"hubot-help",
"hubot-google-images",
"hubot-google-translate",
"hubot-pugme",
"hubot-maps",
"hubot-rules",
"hubot-shipit",
"hubot-jenkins-optimised"
]
#上面增加了一行
hubot-jenkins-optimised
#编辑 /etc/systemd/system/hubot.service ,添加 jenkins 的环境变量
#jenkins的用户名是pe,所有auth是 "pe:x837491lkaflajksdf7"
......
Environment="HUBOT_JENKINS_AUTH=pe:x837491lkaflajksdf7"
Environment="HUBOT_JENKINS_URL=http://192.168.1.90:8080/"
......
# 重启 hubot
systemctl daemon-reload
systemctl restart hubot
然后我们私聊这个机器人,对它说: jenkins list,就可以看到项目了, jenkins b 3 就可以开始build第三个项目了,所有命令可以通过对机器人说 help 来获得

六、集成ansible
集成 ansible,其实就是集成一个 shell,也很简单
cd /home/bot/myhubot
npm install hubot-script-shellcmd
#编辑external-scripts.json
vi external-scripts.json
[
"hubot-diagnostics",
"hubot-help",
"hubot-google-images",
"hubot-google-translate",
"hubot-pugme",
"hubot-maps",
"hubot-rules",
"hubot-shipit",
"hubot-jenkins-optimised",
"hubot-script-shellcmd"
]
#上面增加了一行
hubot-script-shellcmd
#把shellcmd目录下的bash目录,复制一份到/home/bot/myhubot/bash
cp -R node_modules/hubot-script-shellcmd/bash ./
#我们把ansible的yml都放到/homebot/myhubot/bash/ansible目录下
cd /home/bot/myhubot/bash
mkdir ansible
#把ansible-playbook的yml都放进去
....
#然后编写命令脚本
cd /home/bot/myhubot/bash/handles
cat < EOF >> fuse
#!/bin/bash
if [ -n "$1" ] ; then
if [ -n "$2" ] ; then
ansible-playbook /home/bot/myhubot/bash/ansible/check-disk.yml -e "ip=$1 fs=$2"
else
ansible-playbook /home/bot/myhubot/bash/ansible/check-disk.yml -e "ip=$1 fs=/"
fi
fi
exit 0
EOF
#给执行权
chmod 755 /home/bot/myhubot/bash/handles/fuse
#重启hubot
systemctl restart hubot
check-disk.yml 的真身,是在远程机器上调用本机才有的rust dust命令,来算出远程机器的某个目录的使用情况
---
- name: check machine disk space
hosts: "{{ ip }}"
gather_facts: false
vars:
- ip: "{{ ip }}"
- fs: "{{ fs }}"
- ansible_ssh_user: "root"
- ansible_ssh_pass: "Fuck2021!"
- ansible_ssh_common_args: "-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
- host_key_checking: False
tasks:
- name: Run a script with arguments (using 'cmd' parameter)
ansible.builtin.script:
cmd: /usr/local/bin/dust -bcr {{ fs }}
register: output
- debug: var=output.stdout_lines
我们在企业微信对机器说 shell ,就会得到所有命令列表

对它说 shell fuse 172.19.16.1 /export ,就会把本机才有的 dust 命令,拷贝到172.19.16.1的机器上,并对 /export 执行,得到占磁盘空间最大的文件和目录。

参考资料:
http://sd.blackball.lv/library/Automation_and_Monitoring_with_Hubot_(2014).pdf