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多版本的安装与管理
1curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
安装的时候最好加个 https_proxy 代理,因为这个 shell 脚本不翻墙很难下下来。
然后务必关了代理,退出终端并重新进入,安装 nodejs 的最新版本
1nvm ls-remote
2nvm install v16.13.1
3nvm list
确认一下,nodejs 的版本缺省是 v16.13.1
这里千万不要手欠把 npm 的源换成国内的腾讯等,就是国外源
然后安装hubot,并初始化
1su - bot
2npm install -g yo generator-hubot
3
4mkdir /home/bot/myhubot
5cd /home/bot/myhubot
6yo hubot
会问几个问题:
- Ower:写自己邮箱就行
- Bot name: bot
- Description: rendoumi corp
- Bot adapter: campfire
注意最后一个,选campfire就好,我们稍后再装wechatwork
1 _____________________________
2 / \
3 //\ | Extracting input for |
4 ////\ _____ | self-replication process |
5 //////\ /_____\ \ /
6 ======= |[^_/\_]| /----------------------------
7 | | _|___@@__|__
8 +===+/ /// \_\
9 | |_\ /// HUBOT/\\
10 |___/\// / \\
11 \ / +---+
12 \____/ | |
13 | //| +===+
14 \// |xx|
15
16? Owner zhangranrui@rendoumi.com
17? Bot name bot
18? Description rendoumi corp
19? Bot adapter campfire
然后就会是漫长的等待:
最后会报几个警告,不用管,忽略即可。
1npm notice created a lockfile as package-lock.json. You should commit this file.
2+ hubot-help@1.0.1
3+ hubot-google-images@0.2.7
4+ hubot-rules@1.0.0
5+ hubot-shipit@0.2.1
6+ hubot-redis-brain@1.0.0
7+ hubot-google-translate@0.2.1
8+ hubot-diagnostics@1.0.0
9+ hubot-scripts@2.17.2
10+ hubot@3.3.2
11+ hubot-maps@0.0.3
12+ hubot-heroku-keepalive@1.0.3
13+ hubot-pugme@0.1.1
14added 99 packages from 53 contributors and audited 99 packages in 20.176s
15
162 packages are looking for funding
17 run `npm fund` for details
18
19found 1 low severity vulnerability
20 run `npm audit fix` to fix them, or `npm audit` for details
我们先跑一下,简单测一下功能,我们的bot name输入的是bot
1cd /home/bot/myhubot
2
3./bin/hubot
4
5#进入后
6bot ping
7
8#得到回应
9PONG
这样就装好了 hubot,我们做一下修改,去掉 heroku 和 redis,否则会不停丢出报错信息,但是不要用 npm 去删除这两个包,放着那里备用也不占多少空间的
1cd /home/bot/myhubot
2
3vi external-scripts.json
4[
5 "hubot-diagnostics",
6 "hubot-help",
7 "hubot-heroku-keepalive",
8 "hubot-google-images",
9 "hubot-google-translate",
10 "hubot-pugme",
11 "hubot-maps",
12 "hubot-redis-brain",
13 "hubot-rules",
14 "hubot-shipit"
15]
16
17#去掉下面两行
18hubot-heroku-keepalive
19hubot-redis-brain
三、安装微信 Adapter
Adapter 插件,hubot是一套系统,通过各种插件跟各种聊天软件进行交互
微信插件原始地址:https://github.com/billtt/hubot-wechatwork
八戒稍微改了一下:https://github.com/zhangrr/hubot-wechatwork
主要是添加了个自动回应和添加了一些调试信息,否则不知道加载成不成功。
1#先装那个老的
2cd /home/bot/myhubot
3npm install hubot-wechatwork
4
5#覆盖掉老的模块
6cd /home/bot/myhubot/node_modules
7git clone https://github.com/zhangrr/hubot-wechatwork
启动之前普及一下 hubot 基本知识,hubot 中变量的传入都是通过环境变量导入的,启动测试一下wechatwork
1export WECHATWORK_CORP_ID=aaaa
2export WECHATWORK_APP_AGENT_ID=bbbb
3export WECHATWORK_APP_SECRET=cccc
4export WECHATWORK_AES_KEY=dddd
5
6cd /home/bot/myhubot
7./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
1[Unit]
2Description=Hubot
3Requires=network.target
4After=network.target
5
6[Service]
7Type=simple
8WorkingDirectory=/home/bot/myhubot
9User=bot
10
11Restart=always
12TimeoutStartSec=10
13RestartSec=10
14
15; Configure Hubot environment variables, use quotes around vars with whitespace as shown below.
16; Environment="HUBOT_SLACK_TOKEN=SLACK_TOKEN"
17; Environment="HUBOT_JENKINS_AUTH=pe:x837491lkaflajksdf7"
18; Environment="HUBOT_JENKINS_URL=http://192.168.1.90:8080/"
19Environment="NODE_VERSION=default"
20Environment="WECHATWORK_CORP_ID=aaaa"
21Environment="WECHATWORK_APP_AGENT_ID=bbbb"
22Environment="WECHATWORK_APP_SECRET=cccc"
23Environment="WECHATWORK_AES_KEY=dddd"
24
25ExecStart=/home/bot/.nvm/nvm-exec /home/bot/myhubot/bin/hubot --adapter wechatwork
26
27[Install]
28WantedBy=multi-user.target
注意上面,我们指定了环境变量 NODE_VERSION=default,以及最下的 ExecStart,确定用 nvm-exec 引动 node
另外把 wechatwork 所需的4个参数也放进环境变量中,这样重启就可以了
1systemctl daemon-reload
2systemctl start hubot
五、集成jenkins
准备知识,我们必须在 jenkins 拿到用户名和 token(token是用来代替密码的),用来访问 jenkins
首先登录 jenkins,访问网址:$JENKINS_URL/me/configure,新建一个 API Token,记录下来
用法很简单:token替代密码用于 url 认证即可。
1cd /home/bot/myhubot
2npm install hubot-jenkins-optimised
3
4#编辑external-scripts.json
5vi external-scripts.json
6[
7 "hubot-diagnostics",
8 "hubot-help",
9 "hubot-google-images",
10 "hubot-google-translate",
11 "hubot-pugme",
12 "hubot-maps",
13 "hubot-rules",
14 "hubot-shipit",
15 "hubot-jenkins-optimised"
16]
17
18#上面增加了一行
19hubot-jenkins-optimised
20
21#编辑 /etc/systemd/system/hubot.service ,添加 jenkins 的环境变量
22#jenkins的用户名是pe,所有auth是 "pe:x837491lkaflajksdf7"
23......
24Environment="HUBOT_JENKINS_AUTH=pe:x837491lkaflajksdf7"
25Environment="HUBOT_JENKINS_URL=http://192.168.1.90:8080/"
26......
27
28# 重启 hubot
29systemctl daemon-reload
30systemctl restart hubot
然后我们私聊这个机器人,对它说: jenkins list,就可以看到项目了, jenkins b 3 就可以开始build第三个项目了,所有命令可以通过对机器人说 help 来获得
六、集成ansible
集成 ansible,其实就是集成一个 shell,也很简单
1cd /home/bot/myhubot
2npm install hubot-script-shellcmd
3
4#编辑external-scripts.json
5vi external-scripts.json
6[
7 "hubot-diagnostics",
8 "hubot-help",
9 "hubot-google-images",
10 "hubot-google-translate",
11 "hubot-pugme",
12 "hubot-maps",
13 "hubot-rules",
14 "hubot-shipit",
15 "hubot-jenkins-optimised",
16 "hubot-script-shellcmd"
17]
18
19#上面增加了一行
20hubot-script-shellcmd
21
22#把shellcmd目录下的bash目录,复制一份到/home/bot/myhubot/bash
23cp -R node_modules/hubot-script-shellcmd/bash ./
24
25#我们把ansible的yml都放到/homebot/myhubot/bash/ansible目录下
26cd /home/bot/myhubot/bash
27mkdir ansible
28
29#把ansible-playbook的yml都放进去
30....
31
32#然后编写命令脚本
33cd /home/bot/myhubot/bash/handles
34
35cat < EOF >> fuse
36#!/bin/bash
37
38if [ -n "$1" ] ; then
39 if [ -n "$2" ] ; then
40 ansible-playbook /home/bot/myhubot/bash/ansible/check-disk.yml -e "ip=$1 fs=$2"
41 else
42 ansible-playbook /home/bot/myhubot/bash/ansible/check-disk.yml -e "ip=$1 fs=/"
43 fi
44fi
45
46exit 0
47EOF
48
49#给执行权
50chmod 755 /home/bot/myhubot/bash/handles/fuse
51
52#重启hubot
53systemctl restart hubot
check-disk.yml 的真身,是在远程机器上调用本机才有的rust dust命令,来算出远程机器的某个目录的使用情况
1---
2- name: check machine disk space
3 hosts: "{{ ip }}"
4 gather_facts: false
5 vars:
6 - ip: "{{ ip }}"
7 - fs: "{{ fs }}"
8 - ansible_ssh_user: "root"
9 - ansible_ssh_pass: "Fuck2021!"
10 - ansible_ssh_common_args: "-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
11 - host_key_checking: False
12 tasks:
13 - name: Run a script with arguments (using 'cmd' parameter)
14 ansible.builtin.script:
15 cmd: /usr/local/bin/dust -bcr {{ fs }}
16 register: output
17
18 - 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