钉钉企业机器人outgoing功能实现(超详细)
转载自:https://blog.csdn.net/m0_56223006/article/details/126368534
用户:给钉钉机器人发送指定的消息,钉钉机器人会自动给配置的http地址发送消息
实现原理
这是@机器人后,要经过三处的交互,钉钉客户端、钉钉服务器、部署的http服务器,具体如下图:
1、创建企业机器人
这里指的是企业机器人,不是个人机器人,企业机器人,需要自己在钉钉里面创建一个团队,不然以个人的账号登陆【钉钉开放平台】会提示【暂无权限】钉钉开放平台
1.1钉钉创建团队
点击pc端左上角公司按钮,下拉列表后,会有一个【创建企业/组织/团队】,点击后,按流程操作
注意:创建好团队后,给自己加一个最高职位的权限,一般是CEO,具体步骤到时候可以摸索下
1.2创建企业机器人
这里的具体步骤可以看看钉钉官方文档:创建钉钉企业机器人
1.3登陆钉钉开放平台
这里首先登陆[钉钉开放平台](https://open-dev.dingtalk.com/unauth)
然后点击:应用开发-企业内部开发
然后创建应用,创建一个机器人
应用信息这里的AppSecret要记住,后面代码需要用到
点击基础信息-开发管理
服务器出口ip:这里的是你需要填写的公网ip地址,一般服务器都有公网,如果需要本地调试的话,需要使用:内网穿透
使用内网穿透后,外网可以访问本地的域名就可以了
消息接收地址:这里填写http服务,我这里用的是Flask框架搭建的简易http服务
最后就可以进行机器人发布啦
1.4钉钉企业机器人创建
机器人发布后,在钉钉机器人管理里面,就可以看到发布的企业机器人啦
注意:这里只有发布机器人的团队企业,创建内部钉钉群,添加企业机器人才有效。内部群需要加入你创建的企业,才可以创建内部群
这里的post地址可以和钉钉开放平台里面的消息接收地址填写一致
这里的主要作用是你@机器人的时候,就是通过这个post地址,发放到你搭建的http服务里
到这一步,所有的基础工作都完成了,我们继续进行第二步
2、代码编写
我这里用的是python,所以以python为例,下面先直接贴代码
# pip install flask,requests
# pip install urllib3==1.26.15
import flask
from flask import request
import json
import requests
import time
import hmac
import base64
import hashlib
server = flask.Flask(__name__)
@server.route("/run",methods=['post'])
def run():
#获取到post响应体中的sign
post_sign = request.headers.get("Sign")
#获取到post响应体中的Timestamp
post_timestamp = request.headers.get("Timestamp")
# 得到当前时间戳
timestamp = str(round(time.time() * 1000))
# 计算签名
app_secret = '这里填写钉钉开放平台-应用信息-里面的AppSecret'
app_secret_enc = app_secret.encode('utf-8')
string_to_sign = '{}\n{}'.format(post_timestamp, app_secret)
string_to_sign_enc = string_to_sign.encode('utf-8')
hmac_code = hmac.new(app_secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest()
sign = base64.b64encode(hmac_code).decode('utf-8')
print("根据加密规则生成的sign:", sign)
# 验证是否来自钉钉的合法请求
#这里需要需要两个要求,请求的sign和响应的sign要一致,且当前时间和响应的时间不能大于10分钟
if (abs(int(post_timestamp) - int(timestamp)) < 3600000 and post_sign == sign):
request_data_dict = json.loads(request.get_data())
print("请求数据:", request_data_dict)
# 请求用户id
post_userid = request_data_dict.get("senderStaffId")
# 这里拿到的就是你@机器人是输入的文本,可以根据输入文本进行一些if判断
post_message = request_data_dict.get("text").get("content").strip()
print("请求内容:", post_message)
#以上部分是接收@机器人时发送的post请求,对响应数据进行处理。进行签名验证,签名验证这一步也可不需要
#------------------------------------------分割线------------------------------------
#以下部分是进行消息发送,我们接收到机器人发送的请求了,对请求进行一系列的出来,然后就需要返回给钉钉了
# 请求的群机器人webhook
post_webhook = request_data_dict.get("sessionWebhook")
# 构建请求头部
header = {
"Content-Type": "application/json",
"Charset": "UTF-8",
}
# 构建请求数据
tex = "监控报警TEST\n回复消息{0}".format(post_message)
data = {
"msgtype": "text",
"text": {
"content": tex
},
"at": {
"isAtAll": False,
'atMobiles': ['18#########2'],
"atUserIds": [post_userid],
}
}
# 对请求的数据进行json封装
message_json = json.dumps (data)
# 发送请求
info = requests.post (url=post_webhook, data=message_json, headers=header)
# 打印返回的结果
print (info.text)
return info.text
else:
print("这不是一个post请求")
if __name__ == '__main__':
server.run(host="0.0.0.0", port=5050)
2.1解析
这里的代码分成了上下两部分
上部分是接收@机器人时发送的post请求,对响应数据进行处理。进行签名验证,签名验证这一步也可不需要,签名这里具体可以看钉钉签名解析钉钉企业机器人签名计算
下部分是进行消息发送,我们接收到机器人发送的请求了,对请求进行一系列的出来,然后就需要返回给钉钉了
其他一些消息类型也可以参考钉钉官方文档钉钉机器人消息类型
在代码中,我们@机器人时,相当于像我们搭建的http发送了一个post请求,这个时候我们可以拿到post请求的响应体,具体响应字段如下,有需要用到的字段,可以去获取
{
"conversationId": "xxx",
"atUsers": [
{
"dingtalkId": "xxx",
"staffId":"xxx"
}
],
"chatbotCorpId": "dinge8a565xxxx",
"chatbotUserId": "$:LWCP_v1:$Cxxxxx",
"msgId": "msg0xxxxx",
"senderNick": "杨xx",
"isAdmin": true,
"senderStaffId": "user123",
"sessionWebhookExpiredTime": 1613635652738,
"createAt": 1613630252678,
"senderCorpId": "dinge8a565xxxx",
"conversationType": "2",
"senderId": "$:LWCP_v1:$Ff09GIxxxxx",
"conversationTitle": "机器人测试-TEST",
"isInAtList": true,
"sessionWebhook": "https://oapi.dingtalk.com/robot/sendBySession?session=xxxxx",
"text": {
"content": " 你好"
},
"msgtype": "text"
}
2.2部署
这里我们把代码放到服务器,然后使用命令:python ****.py
显示如下就是服务启动成功了
注意:这里首先要确认是否安装了python环境,一般云服务器自带python2环境的,应该也可以用
然后就是你服务设置的端口是否开放,如果没有开放,外网是访问不了的
服务启动后,就可以使用:http://公网ip:端口号/run 进行外网访问了
这里的http://公网ip:端口号/run也就是之前填入到钉钉开放平台的【消息接收地址】和钉钉机器人的【post地址】
这里会发现,关闭服务器连接后,http服务也会被关闭
这个时候我们使用命令:nohup python xx.py &
可以服务器连接关闭后,也不断开
需要关闭服务的话,使用命令:netstat -ntpl 找到启动的服务pid
然后:kill -9 pid 关闭服务
最后贴上实现效果
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
2021-09-16 第1篇----Istio原理篇
2019-09-16 部署java应用的几种方式