Hubot集成企业微信+jenkins+ansible

Hubot是一个通用的聊天机器人,能和很多聊天软件集成,比如slack、rockchat、telegram、企业微信、IRC等。

公司用的是企业微信,之前用群机器人和 prometheus 集成,发送各种告警信息,但是群机器人无法接收消息;同时我们想集成进去很多自定义命令,比如发送指令就开始 jenkins build,发送 ansible 指令执行,发送流量图就自动把机房的流量图发过来,这个群机器人就用不成了。所以必须再直接一些,构建一个企业微信的应用。

一、企业微信安装前准备

安装前需要在企业微信中拿到4个信息:

  1. WECHATWORK_CORP_ID
  2. WECHATWORK_APP_AGENT_ID
  3. WECHATWORK_APP_SECRET
  4. WECHATWORK_AES_KEY

首先联系企业微信管理员新增一个应用:

image-20211222144935256

在“管理后台-我的企业”中可以获得地一个信息,企业 ID 信息,CORP_ID :

image-20211222144654696 拿拿 在“管理后台-应用管理-点击某具体应用-详情”页中可以获得二、三个信息, APP_AGENT_ID 和 APP_SECRET

image-20211222150424143

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

image-20211222151155307

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

image-20211222151325525

然后设置一下

image-20211222151552345

然后点击保存,这里必然会失败!没有关系,因为我们还没有装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

image-20211222154655729

确认一下,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

然后就会是漫长的等待:

image-20211222155430133

最后会报几个警告,不用管,忽略即可。

 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,说明启动没啥毛病

image-20211228152907465

然后我们回到企业微信这个应用的应用管理,点击保存接收消息服务器配置,这次就应该能成功了。

测试一下,我们在企业微信中,对这个应用机器人私聊,发个 hi:

image-20211228153139262

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

image-20211228153351091

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

image-20211228153542953

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

image-20211228153847963

要注意的命令:

wechatwork 有一条命令 chat create CHATID USER1,USER2,USER3,…

解释一下,是用来建立一个企业微信群聊的,群主默认是第一个人:

chatid 是指一个群聊的 id 号,格式是字母+数字,比如yunwei001,这个一旦创建就无法销毁,会永远保存在企业微信那里,切切记住!!!

user1,user2 这种是员工企业微信的id,通常是用户名全称,比如 zhangrenren,liudaqiang

所以说的时候务必要小心,万万记住 chatid 一旦建立就无法收回。

之后可以调用 sendChatMessage 来给群聊发送消息。

image-20211228163631248

四、准备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,记录下来

image-20211228155054104

用法很简单: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 来获得

image-20211228155834837

六、集成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 ,就会得到所有命令列表

image-20211228161435568

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

image-20211228161857621

参考资料:

https://qydev.weixin.qq.com/wiki/index.php?title=%E5%8F%91%E9%80%81%E6%8E%A5%E5%8F%A3%E8%AF%B4%E6%98%8E

http://sd.blackball.lv/library/Automation_and_Monitoring_with_Hubot_(2014).pdf


Nodejs多版本的安装与管理
Javascript的项目与babel和eslint
comments powered by Disqus