之前使用钉钉做过三方登录,今天我们来说一下使用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))
# print(timestamp)
# print(sign)


import requests,json #导入依赖库
headers={'Content-Type': 'application/json'} #定义数据类型
webhook = '你的webhook地址&timestamp='+timestamp+"&sign="+sign
#定义要发送的数据
#"at": {"atMobiles": "['"+ mobile + "']"
data = {
"msgtype": "text",
"text": {"content": '我是机器人,这是我发的第一条消息'},
"isAtAll": True}
res = requests.post(webhook, data=json.dumps(data), headers=headers) #发送post请求

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> ![screenshot](https://img.alicdn.com/tfs/TB1NwmBEL9TBuNjy1zbXXXpepXa-2400-1218.png)\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"
}

// timestamp 无效
{
"errcode":310000,
"errmsg":"invalid timestamp"
}

// 签名不匹配
{
"errcode":310000,
"errmsg":"sign not match"
}

// IP地址不在白名单
{
"errcode":310000,
"errmsg":"ip X.X.X.X not in whitelist"
}

评论





载入天数...载入时分秒...

Blog content follows the Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0) License

Use WZH as theme, total visits times