前言

Slack 是一个最近一年兴起的团队沟通协作平台。程序员对工具其实是最有品位和要求的,相信国内很多公司和团队都在使用,豆瓣也算比较早在用. 相信用过的人会理解本文。如果你还没有接触它,尤其是对现有的团队沟通协作工具有些不满,可以试一下.

本文就是介绍我们在最近做出来的一个 bot - slack_bot . 它的口号是:立志成为一个可被调戏且有用的 Bot

为什么

无论是运维还是开发,某些时间都会收到一些邮件 / 提醒,可能是固定的时间的定时任务跑出来的结果,也可能是某个故障引起的问题邮件。我们都很烦手头有好几个东西来接收这些消息, 而 slack 可以使用某些方法让这些问题集中起来.

比如很常用的,使用 chat 或者 incoming-webhooks 接收消息。做什么呢?我可以把一些昨天的数据汇总或者汇总的地址在今天早上发到某个 channel 下,这样想要看这个数据的人直接点进去就好了. 当然啦,也可以直接发消息到某个人。一个具体的例子:豆瓣的同事都知道,我们的测试环境时间过期就会被删除,在某段时间里面每天都有很多人在关注我们要新上的一个测试的地址,但是经常被同事 @, 说地址怎么找不到了,那么我就要抽出精力再去创建一个。后来一想,索性跑个定时任务,拉最新的代码,走逻辑,生成一个测试环境。每天都会在 channel 里面发消息给对应关心这个消息的人. 一段时间以后,我们的工作完成了,同事都有点不适用,哎, 怎么早上看不到那个消息了...

但是今天说的是什么呢?我们的 slack_bot 主要借用 outgoing-webhooks . incoming 表示把消息推到 slack 里面,outgoing 其实就是当有人在某些符合的 channel 里面说了什么,会跳到我们提供的回调地址,根据内容返回对应符合的回复。大家是不是有点懂了,这就是小黄鸡的原理.

说到这里大家应该明白了。其实 slack 给我们提供了很大的想象和实现的空间。我立刻想起来做运维时候做的一些事情:

比如当时有时候要去机房,路上没有网 (2g 上网太慢), 有时候想看个监控状态,切个负载均衡,重启个服务什么的,后来做了一个东西,就是给某些号码发某些特殊的短信内容就可以获得想要的结果,执行想做的事情. 其实 slack_bot 只是一些爬虫的集合,一些功能实现的例子。在实际开发和工作中可以做很多更有意思的,公司内部的插件。和公司的业务相关,和自己做的事情相关。这样在路上就能用. 比如我的地图功能,我可以在网络不好的时候找到行程的最好路线;我用公交插件可以实时的看我要等的公交需要多久到达,我可以踩着点去站牌....

小黄鸡原理

小黄鸡很火的时候,我还是一个 perl 运维...

小黄鸡其实调用的是 simsim 的接口。大家都可以去注册一个 key 来玩,也可以用项目自带的.

其实就是 post 一个数据到 simsim 的 api 上,他会返回你对应的小黄鸡的回复.

项目介绍

很多人听过甚至曾经用过 小黄鸡 . 你可以把本 bot 理解为增加了很多 功能, 只保留小黄鸡交流的基本逻辑, 用于slackchannel里面小黄鸡

项目使用 flask, 目前本项目是一个 heroku 应用。地址是https://slack-bot2.herokuapp.com/slack_callback但是你 也可以直接裸跑

gunicorn wsgi:app localhost:5000 --timeout 240 --log-file -

你也可以使用 heroku 创建一个新的应用,直接用我们的项目代码就可以.

我们使用 slack 的特性

  1. 可以把消息私聊发给自己
  2. 可以使用带图的方式接收结果 (支持 canvas, 以下会看到例图)

继承自小黄鸡的模块们,但是都做了对应的修改:

  1. 空气插件
  2. wikipedia
  3. 地震了
  4. 糗百
  5. orz # orz 需要自定义 emoji

新加的模块们:

地图插件 - 你可以输入我想从哪去哪,会给你个路线 (步行 / 开车 / 公交)

天气插件 - 使用了百度 api, 获得城市的天气情况

北京公交插件 - 可以查询北京公交线路,获取实时的到某站的信息 (有些线路站点不准)

美食插件 - 使用大众点评网 api, 获取附近餐饮信息,评分,电话地址,距离等等

技术活动插件 - 从 segmentfault/csdn/ 车库咖啡 / 活动行获得最近的活动列表

Github_issue 插件 - 获得你个人或者组织下未处理的 Pull requests 列表

电影信息插件 - 列出最近上映和即将上映的电影信息

pycoders 插件 - 获得订阅数据

pythonweekly 插件 - 获得订阅数据

头条插件 - 获得今日头条新闻

travel 插件 - 旅游推荐 / 景点介绍

v2ex feed 插件 - 获得一些节点的最新 feed

help 插件 - 列出所有插件的帮助信息

最主要的是小黄鸡 (simsim)

也可以直接发到个人的 slackbot channel 里:

配置 slack

去你的 slack 组织的 services 页面。比如我们是https://pythoncn.slack.com/services/new. 找到Outgoing WebHooks:

点击Add+并确认到新建页面:

channel可以选择 any, 也可以指定单独一个.Trigger Word(s)可以不填,那就是所有的记录都会走. 也可以找关键词 / 字,用逗号隔开.url就是你控制的回调的地址。本图中的是我们用的 herokuapp 地址:https://slack-bot2.herokuapp.com/slack_callback

你还可以自定义 icon 的图标和名字:

实现原理

我还是抄袭了 小黄鸡 的插件思想。但是完全脱离和小黄鸡的代码关系。只留下了几个原有的插件并更新. plugins 目录下有一些插件. 系统会按照 plugins/__init__.py 里面的all的列表顺序,挨个插件对比是否符合。符合即停止。都不符合最后会使用 simsim 模块

具体的插件编写可以参看项目的 插件编写

一些 trick

  1. 假如你没有设置 Trigger Word. 你要保证你的回复可以被停止,否者你的回复会被当成下一次的输入。这样就死循环了。比如我们使用一个函数,只要文本用 ! 开头就不会回调。表示这个是一个正常的,不想被 out-going 的记录.
  2. 这里的天气图片是一个 html5 的 data image. 还有豆瓣电影的海报图片做了防盗链, 不能被 slack 识别和正常显示. 我的用法是 upload 到 slack. 获得返回的 url. 然后在生成附件.
  3. direct message 其实是被限定了 post 的长度。太长的话会报 414. 需要对长数据切分. slack_bot 已经实现了
  4. 现在 simsim 的借口被玩坏了,有些低级,无聊,带有攻击性的回复。酌情使用