抱歉,您的浏览器无法访问本站

本页面需要浏览器支持(启用)JavaScript


了解详情 >

封装钉钉的api,可用于自定义机器人发送mardown消息,普通文本消息,卡片消息等。access_token和secret需要配置好。 (代码见最后)

消息体

纯文本

  • 支持 @
1
2
3
4
5
6
7
access_token = ""
secret = ""
dd = DDingWebHookPush(access_token=access_token, secret=secret)

template_initialize = dd.initialize_text_template()
dd.setContent(template_initialize, "你瞅啥")
dd.sendMsg(template_initialize)

效果

image.png

  • 超链接
  • 可加图片,点击跳转
1
2
3
4
5
6
7
8
9
access_token = ""
secret = ""
dd = DDingWebHookPush(access_token=access_token, secret=secret)

template_initialize = dd.initialize_link_template(
title="随便试试",
messageUrl="www.baidu.com")
dd.setContent(template_initialize, "百度搜索")
dd.sendMsg(template_initialize)

效果

image.png

FeedCard卡片消息

  • 类似公众号推送的格式

  • 支持图文

  • 支持跳转

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
access_token = ""
secret = ""
dd = DDingWebHookPush(access_token=access_token, secret=secret)

card_msg = dd.initialize_actionCard_template(
title="乔布斯 20 年前想打造一间苹果咖啡厅,而它正是 Apple Store 的前身",
singleTitle="阅读全文",
singleURL="https://www.dingtalk.com/")

content = """![screenshot](https://gw.alicdn.com/tfs/TB1ut3xxbsrBKNjSZFpXXcXhFXa-846-786.png)
### 乔布斯 20 年前想打造的苹果咖啡厅
Apple Store 的设计正从原来满满的科技感走向生活化,而其生活化的走向其实可以追溯到 20 年前苹果一个建立咖啡馆的计划
"""
dd.setContent(card_msg, content)
dd.sendMsg(card_msg)

效果

image.png

actionCard整体跳转

1
2
3
4
5
6
7
8
9
10
access_token = ""
secret = ""
dd = DDingWebHookPush(access_token=access_token, secret=secret)

template_initialize = dd.initialize_actionCard_template(
title="随便试试",
singleTitle="查看更多",
singleURL="www.baidu.com")
dd.setContent(template_initialize, "哈哈哈哈哈哈哈哈")
dd.sendMsg(template_initialize)

效果

image.png

actionCard独立跳转

1
2
3
4
5
6
7
8
9
10
access_token = ""
secret = ""
dd = DDingWebHookPush(access_token=access_token, secret=secret)

btns = [
{"title": "标题1", "actionURL": "www.qq.com"},
{"title": "标题2", "actionURL": "www.baidu.com"}]
template_initialize = dd.initialize_actionCard_template(title="", btns=btns)
dd.setContent(template_initialize, "呵呵呵呵呵呵")
dd.sendMsg(template_initialize)

效果

image.png

markdown消息

  • 支持@
  • markdown消息中注意换行 \n 前后需要空两格
1
2
3
4
5
6
7
access_token = ""
secret = ""
dd = DDingWebHookPush(access_token=access_token, secret=secret)

content = "# 你瞅啥 \n ## 哈哈 \n * a \n * b \n * c"
dd.setContent(markdown_msg, content)
dd.sendMsg(markdown_msg)

效果

image.png

群内@ 成员

通过手机号

1
2
3
4
5
6
7
8
access_token = ""
secret = ""
dd = DDingWebHookPush(access_token=access_token, secret=secret

template_initialize = dd.initialize_text_template()
dd.setContent(template_initialize, "你瞅啥")
dd.setAtmobiles(template=template_initialize, mobiles=["17551088538", "189xxxxxxxx"])
dd.sendMsg(template_initialize)

如果找到手机号就 @

效果

image.png

通过userId

1
2
3
4
5
6
7
8
access_token = ""
secret = ""
dd = DDingWebHookPush(access_token=access_token, secret=secret

template_initialize = dd.initialize_text_template()
dd.setContent(template_initialize, "你瞅啥")
dd.setAtByUserIds(template=template_initialize, userIds=["10001", "10002"])
dd.sendMsg(template_initialize)

这种应该不常用,我不知道自己的userId,不做演示。

代码

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# -*- coding: utf-8 -*-
# @Author : ryan
# @Time : 2021/1/15 下午5:37
import time
import hmac
import hashlib
import base64
import urllib.parse
import requests
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)


class DDingWebHookPush:

def __init__(self, access_token, secret):
self.access_token = access_token
self.secret = secret
self.headers = {"Content-Type": "application/json ;charset=utf-8 "}

@staticmethod
def initialize_markdown_template(title):
"""
markdown格式,支持markdown语法
:param title:
:return:
"""
return {
"msgtype": "markdown",
"markdown": {
"title": title,
"text": ''
},
"at": {
"isAtAll": False
}
}

@staticmethod
def initialize_text_template():
"""
普通文本类消息
:return:
"""
return {
"msgtype": "text",
"text": {
"content": "",
},
"at": {
"isAtAll": False
}
}

@staticmethod
def initialize_link_template(title, messageUrl, picUrl=None):
"""
超链接类型
:param messageUrl: 跳转链接
:param title: 图片链接,可为空
:return:
"""
return {
"msgtype": "link",
"link": {
"text": "",
"title": title,
"picUrl": picUrl if picUrl else "",
"messageUrl": messageUrl
}
}

@staticmethod
def initialize_actionCard_template(title, singleTitle="阅读全文", singleURL=None, btns=None):
"""
卡片类型
:param btns:
:param singleURL: 跳转地址
:param singleTitle: 跳转链接绑定的文字
:param title:
:return:
"""
if btns:
return {
"msgtype": "actionCard",
"actionCard": {
"text": "",
"title": title,
"btnOrientation": "0",
"btns": btns
}
}
return {
"msgtype": "actionCard",
"actionCard": {
"text": "",
"title": title,
"btnOrientation": "0",
"singleURL": singleURL if singleURL else "",
"singleTitle": singleTitle
}
}

@staticmethod
def initialize_feedCard_template(links: list):
"""
卡片类型
:param links: [{"title": "", "messageURL": "", "picURL": ""}]
:return:
"""
return {
"msgtype": "actionCard",
"feedCard": {
"links": links
}
}

def makeSign(self):
"""
加签
:return:
"""
timestamp = str(round(time.time() * 1000))
secret_enc = self.secret.encode('utf-8')
string_to_sign = '{}\n{}'.format(timestamp, self.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_plus(base64.b64encode(hmac_code))
return timestamp, sign

def setContent(self, template, __content):
"""
内容主体
:param template: 内容模版
:param __content: 内容
:return:
"""
msgtype = template.get("msgtype")
if msgtype == 'markdown':
template.get("markdown").update({'text': __content})
elif msgtype == 'text':
template.get("text").update({'content': __content})
elif msgtype == 'link':
template.get("link").update({'text': __content})
elif msgtype == 'actionCard':
template.get("actionCard").update({'text': __content})
else:
raise Exception("this type could not set content!")

def setAtmobiles(self, template, mobiles: list):
"""
通过手机号来找到群里人进行@,若群内无此人@的是手机号,有此人则正常@人昵称
:param template:
:param mobiles:['','']
:return:
"""
template.update({"at": {'atMobiles': mobiles}})

def setAtByUserIds(self, template, userIds: list):
"""
通过手机号来找到群里人进行@,若群内无此人@的是手机号,有此人则正常@人昵称
:param template:
:param userIds:['','']
:return:
"""
template.update({"at": {'atUserIds': userIds}})

def setAtAll(self, template):
"""
@ 所有人
:param template:
:return:
"""
template["at"] = {'isAtAll': True}

def sendMsg(self, template):
"""
发送消息
:param template:
:return:
"""
if not self.access_token or not self.secret:
return False
timestamp, sign = self.makeSign()
url = "https://oapi.dingtalk.com/robot/send?access_token=%s&timestamp=%s&sign=%s" % (self.access_token, timestamp, sign)
res = requests.post(url, json=template, headers=self.headers, verify=False)
return res.json()

评论