之前使用钉钉做过三方登录,今天我们来说一下使用python结合钉钉做一个钉钉群自定义机器人。
这个功能属于比较极客的功能,它可以将第三方服务的信息聚合到钉钉群中,实现信息的自动化同步,例如:通过聚合Github、Gitlab等源码管理服务,实现源码更新同步;通过聚合Trello、JIRA等项目协调服务,实现项目信息同步;同事,支持Webhook协议的自定义接入,支持更多可能性,例如:将运维报警提醒、自动化测试的结果报告提醒、工作、生活日程安排(上班打卡、下班吃饭、健身、读书、生日、纪念日…)等等的提醒,通过自定义机器人聚合到钉钉中。
过关于钉钉机器人网上的一些攻略年代都比较久远,代码很多都基于python2,为了与时俱进,我们尝试用python3.7来开发配置钉钉自定义机器人。
查看机器人官方文档:https://ding-doc.dingtalk.com/doc#/serverapi2/qf2nxq
首先明确一点,钉钉自定义机器人早就不支持在手机端创建了,所以得使用你的pc端或者mac端的钉钉客户端
创建机器人
在需要机器人的聊天群界面,点击智能群助手(一个群可以添加6个自定义机器人,而且还得有管理员权限)

我们选择添加机器人

点进去发现好多机器人,各有各的功能,本次我们选择自定义机器人。

钉钉的机器人基于webhook协议,webhook呢是一个api概念,是微服务api的使用范式之一,也被成为反向api,即前端不主动发送请求,完全由后端推送。
在添加机器人页面填写一些基本信息。

需要注意的是,在安全设置一栏里,我们选择加签的方式来验证,在此说明一下,钉钉机器人的安全策略有三种,第一种是使用关键字,就是说你推送的消息里必须包含你创建机器人时定义的关键字,如果不包含就推送不了消息,第二种就是使用加密签名,第三种是定义几个ip源,非这些源的请求会被拒绝,综合来看还是第二种又安全又灵活。

创建成功后,系统会分配给你一个webhook地址,这个地址需要保存一下,地址中有唯一的accesstoken
这是我们的钉钉机器人已经添加完成了,于是我们要写入让他进行自动发送消息
使用机器人发送消息
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 26 27 28 29 30
| import time import hmac import hashlib import base64 import urllib.parse
timestamp = str(round(time.time() * 1000)) secret = '创建机器人的签名' secret_enc = secret.encode('utf-8') string_to_sign = '{}\n{}'.format(timestamp, secret) string_to_sign_enc = string_to_sign.encode('utf-8') hmac_code = hmac.new(secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest() sign = urllib.parse.quote(base64.b64encode(hmac_code))
import requests,json headers={'Content-Type': 'application/json'} webhook = '你的webhook地址×tamp='+timestamp+"&sign="+sign
data = { "msgtype": "text", "text": {"content": '我是机器人,这是我发的第一条消息'}, "isAtAll": True} res = requests.post(webhook, data=json.dumps(data), headers=headers)
print(res.text)
|
这是我们已经发现机器人可以推送消息了,看效果:

关于发送消息类型和数据格式
文本格式1 2 3 4 5 6 7 8 9 10 11 12 13
| { "msgtype": "text", "text": { "content": "我就是我, 是不一样的烟火@156xxxx8827" }, "at": { "atMobiles": [ "156xxxx8827", "189xxxx8325" ], "isAtAll": false } }
|
link格式1 2 3 4 5 6 7 8 9
| { "msgtype": "link", "link": { "text": "这个即将发布的新版本,创始人xx称它为红树林。而在此之前,每当面临重大升级,产品经理们都会取一个应景的代号,这一次,为什么是红树林", "title": "时代的火车向前开", "picUrl": "", "messageUrl": "https://www.dingtalk.com/s?__biz=MzA4NjMwMTA2Ng==&mid=2650316842&idx=1&sn=60da3ea2b29f1dcc43a7c8e4a7c97a16&scene=2&srcid=09189AnRJEdIiWVaKltFzNTw&from=timeline&isappinstalled=0&key=&ascene=2&uin=&devicetype=android-23&version=26031933&nettype=WIFI" } }
|
markdown类型1 2 3 4 5 6 7 8 9 10 11 12 13
| { "msgtype": "markdown", "markdown": { "title":"杭州天气", "text": "#### 杭州天气 @150XXXXXXXX \n> 9度,西北风1级,空气良89,相对温度73%\n> \n> ###### 10点20分发布 [天气](https://www.dingalk.com) \n" }, "at": { "atMobiles": [ "150XXXXXXXX" ], "isAtAll": false } }
|
关于类型还有多种及参数,点击https://ding-doc.dingtalk.com/doc#/serverapi2/qf2nxq/uKPlK查看
检验失信信息
针对上边选择设置的三种方式,至少设置其中一种,以进行安全保护。否则会校验不通过
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| { "errcode":310000, "errmsg":"keywords not in content" }
{ "errcode":310000, "errmsg":"invalid timestamp" }
{ "errcode":310000, "errmsg":"sign not match" }
{ "errcode":310000, "errmsg":"ip X.X.X.X not in whitelist" }
|