继续水文章。今天主要是吐槽一下钉钉的接口文档
前几天碰见个需求:
- 从jira接口查出每日未完成的任务
- 用钉钉机器人把任务发送到钉钉工作群里,并标注是谁的任务、任务标题
- 发送时,艾特对应的人员
- 给每个人创建待办任务
- 每天定时18:00触发
刚听到这需求,感觉是个小case,应该不麻烦。但是实操过程中,坑了我一把。今天记录一下遇到的问题。(涉及工作上的事儿,就不附全部源码了,就拿部分源码用以说明问题)
为啥说坑呢?其实主要是钉钉的官方api写的含糊不清、概念繁杂、重要的细节不讲清楚,得让你一个一个的去实,看看ta到底支持不支持。
下面是步骤:
1、编写jira查询的公共方法。略
2、编写钉钉机器人发送消息的公共方法
(钉钉支持多种格式的消息体,这里只写了markdown如何发送。其他的原理一致,照着接口文档抄就行了)
# -*- coding: utf-8 -*-
import base64
import hashlib
import hmac
import json
import os
import time
from urllib.parse import quote_plus
import requests
import dingding_get_id
class Messenger:
def __init__(self, token=os.getenv("DD_ACCESS_TOKEN"), secret=os.getenv("DD_SECRET")):
self.timestamp = str(round(time.time() * 1000))
self.URL = "https://oapi.dingtalk.com/robot/send"
self.headers = {
'Content-Type': 'application/json'}
secret = secret
secret_enc = secret.encode('utf-8')
string_to_sign = '{}\n{}'.format(self.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()
self.sign = quote_plus(base64.b64encode(hmac_code))
self.params = {
'access_token': token, "sign": self.sign}
def send_markdown(self, title: object, text: object, atUserIds):
"""
发送markdown
"""
data = {
"msgtype": "markdown",
"markdown": {
"title": title,
"text": text
},
"at": {
"atMobiles": [
],
"atUserIds": [
*atUserIds
],
"isAtAll": False
}
}
self.params["timestamp"] = self.timestamp
r = requests.post(
url=self.URL,
data=json.dumps(data),
params=self.params,
headers=self.headers
)
print("data:", data)
print("-----------------")
print(r.json())
3、艾特钉钉用户的步骤和方法
官方文档:企业内部机器人群聊实现@人接入指南
这里我感觉写的挺不清楚的。
1、类型是array,java里数组的意思。但是对于python来说没有这个类型,但是可以用list列表代替。对于像我这种的新手菜鸡们来讲,不太容易理解。幸亏我之前学过点java基础,不然估计还看不懂。
2、
atMobiles参数里,写的是:消息内容text内;
atUserids参数里,写的是:消息内容content中。
text和content是俩词,特容易让人理解是俩不同的东西,但是实际使用上来讲,就是指的消息内容这几个字。
3、需要跟atMobiles/atUserids参数结合使用,才有@效果。我看了三遍才明白啥意思:就是下图里的这俩参数里,消息内容必须写@+手机号(或id),然后对应的atMobiles/atUserids里,也写上对应的手机号(或id)才能显示@效果。
关于@这个功能,有俩疑问:
3.1、要是有多个人需要艾特怎么办?(看着atMobiles、atUserids的类型是java的数组(Python里的list),感觉可以传多个进去来实现多人艾特,但是人家接口文档就是不说)
3.2、必须手机号和id一起写才有效么?只写id不写手机号可以不?
这俩问题,他接口文档里都没写,都得自己去实验。
最终实验结果是:
3.1的答案是:传多个值进去,可以实现多人艾特
3.2不用手机号和id一起写,只用一个就行了。比如选用手机号作为艾特方式,那消息内容就写手机号,并且传atMobiles参数;反之,消息内容就写id,并且传atUserids参数。
调用发送钉钉机器人并艾特:
msg = ''
for user_info in user_info_list:
atuserid = user_info['userid']
msg = f"+ 经办人:@{
atuserid}"
dingding.send_markdown(title='所有未关闭的需求',
text=msg,
atUserIds=(j for j in user_id_list)
)
这两句话的配合是个知识点,有空再讲
艾特这块的接口文档,看的最是难受,就算我笨吧。
4、创建钉钉待办任务的步骤和方法
官方文档:创建钉钉待办任务
这里出了想吐槽一下旧版sdk过于不好用(rbs)之外,没其他吐槽的。按步骤走就行。
5、定时任务的创建
5.1、可以用Jenkins持续集成
5.2、也可以用我之前写的:APScheduler定时框架
在Linux服务器上执行python定时任务(APScheduler定时框架)
The End
这几个大厂的官方API,个人感觉友好度:百度>微信>钉钉