不多说,先上最终效果图

[Python钉钉Outgoing机器人初步研究

再上一段连接,后续所有过程都是在大佬的思路下进行的,代码也是从大佬这里复制的,只是稍微改动的一部分,大家可以在联调通过能实现交互之后再去自己开发后台逻辑。但是因为大佬写的太简单了,省了很多步骤,所以我才自己重新写一份,防止后面忘记了

先直接贴代码,再说我的从零开始的步骤

1.先安装apache http服务,并配置反向代理,代理的就是python绑定的端口和ip,配置方法参考如下
利用Apache的转发模块实现反向代理服务器

2.因为企业内部机器人需要一个公网的http服务,所以使用钉钉推荐的内网穿透去实现。这一点没遇到什么问题,仔细看官方文档就好了
钉钉内网穿透实现

3.到钉钉开发者后台去创建一个机器人
注意:机器人创建后凭证与基础信息这一栏中的参数AppSecret需要复制出来,到代码里替app_secret变量的值
然后再发布机器人到钉钉群,此时可以看到机器人有一个参数叫Webhook,这个直接复制到代码里,后面会讲有什么用。

大概的准备工作都准备完了,就开始逐一打通了

因为内网穿透之后要启动一个http服务才可以看到具体的使用效果,所以安装apache,至于为什么不用python代码来实现http服务,个人喜好吧。因为本身就有apache所以我就懒得再去看别人的代码学习了,

然后至于为什么要使用apache反向代理,因为我发现打通了之后,钉钉发送的请求可以被apache http接收到,但是我的python后台运行过程中并没有任何动作,所以我立马反映过来他们根本没有联通!于是尝试nginx代理,发现不可取具体原因我也忘了,这两天一直弄这个注意力转义的也快哈哈哈。

用apache来配置反向代理后,钉钉发送的http请求先会根据内网穿透后提供的公网域名来发送到本地的apache http服务,再由反向代理转发到我们运行的python程序上。

到这一步基本上获取数据这一块就完成了,接下来就是outgoing机器人的自动回复实现了。

根据获取到的数据getPost() 方法会把数据解析出来,然后调用initKey()方法去实现返回。其中initKey()方法中发送数据用的思路还是和钉钉自定义机器人一样,用获取到的webhook直接用request请求讲我们要发送的数据发送出去。
这一步我卡了足足有十个小时之久,因为大佬之前的代码中webhook是他自己拼凑的,但是我根据钉钉https://oapi.dingtalk.com/gettoken?接口去获得的token一直提示不对,百度了很久也没找到原因。直到在钉钉看机器人配置的时候,无意间发现企业内部机器人也会有webhook,一开始配置机器人的时候都没看到,一直以为只有自定义机器人才有webhook。于是不禁大喜,直接把他复制过来套进去就用了,果然可以!

所以,交互的原理就是根据钉钉http发送过来的请求中的报文信息,用python解析后在对信息进行判断,在执行对应的方法去处理,最后通过调用request方法把处理结果返回到钉钉。这样就大功告成了

接下来再对我重点遇到的问题进行一个总结:

  1. 因为之前安装过禅道,其中也包含了apache http服务,导致新安装的apache服务无法新增,处理办法如下
    如何手动创建Apache Windows服务
  2. 内网穿透后报错Unable to initiate connection to 127.0.0.1:81. A web server must be running on port 127.0.0.1:81to complete the tunnel.
    这个是因为没有启动http服务,并且apache监听的端口要和内网穿透的端口要保持一致。
  3. 就是代码中的参数问题,只恨我没有仔细看官方文档,只顾拿别人的代码复制粘贴就用,到后面才慢慢摸索各个参数的来源

app_secret参数:这个很重要,是用来计算sgin的

webhook参数:就是这个参数,折磨了我十多个小时,我至今没搞懂大佬的参数是怎么获取的,反正我是直接拿来用的。
这个参数是在企业内部机器人上线后,添加到群里面以后才会有的!


如下是代码,请粘贴复制后仔细阅读,重点看handle_client(),getPost(),initKey()这三方法就好了,获取数据,数据处理,返回数据这三个主要功能都在这里。

# -*- coding: GBK -*-
import requests
import json
import time
import hmac
import hashlib
import base64
import socket
from multiprocessing import Processdef handle_client(client_socket):# 获取socketrequest_data = client_socket.recv(20000)post_userid, post_sign, post_timestamp, post_mes = getPost(request_data)# 回应socketinitKey(post_userid, post_sign, post_timestamp, post_mes)# 关闭socketclient_socket.close()def getPost(request_data):request_data = str(request_data, encoding="utf8").split('\r\n')items = []for item in request_data[1:-2]:items.append(item.split(':'))post_useful = {}for i in items:post_useful.update({i[0]: i[1]})if post_useful.get('sign') == None:print('other connect')return 0else:post_sign = post_useful.get('sign').strip()post_timestamp = post_useful.get('timestamp').strip()post_mes = json.loads(request_data[-1])post_userid = post_mes.get('senderId').strip()post_mes = post_mes.get('text').get('content').strip()return post_userid, post_sign, post_timestamp, post_mesdef initKey(post_userid, post_sign, post_timestamp, post_mes):# 配置token# 得到当前时间戳timestamp = str(round(time.time() * 1000))# 计算签名app_secret = 'bKHMrla5Jxxxxxxxxxxxxxxxxxxxxxx'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')# 验证是否来自钉钉的合法请求if (abs(int(post_timestamp) - int(timestamp)) < 3600000 and post_sign == sign):webhook="https://oapi.dingtalk.com/robot/send?access_token=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"#宝1header = {"Content-Type": "application/json","Charset": "UTF-8"}# 发送消息message_json = json.dumps(selectMes(post_userid, post_mes))# 返回发送状态info = requests.post(url=webhook, data=message_json, headers=header)print(info.text)else:print("Warning:Not DingDing's post")def selectMes(post_userid, post_mes):# 判断指令选择对应回复if (post_mes == '你好'):send_mes = '你好啊同学!'return sendText(post_userid, send_mes)if (post_mes == '你叫什么名字'):send_mes = '我是小宝一号~~'return sendText(post_userid, send_mes)elif (post_mes == '天气'):send_mes = getWeather()return sendMarkdown('天气预报', send_mes)else:return sendText(post_userid, 'Not understand')def sendText(post_userid, send_mes):# 发送文本形式message = {"msgtype": "text","text": {"content": send_mes},"at": {"atDingtalkIds": [post_userid],"isAtAll": False}}return messagedef sendMarkdown(title, send_mes):# 发送Markdown形式message = {"msgtype": "markdown","markdown": {"title": title,"text": send_mes},"at": {"atDingtalkIds": [],"isAtAll": False}}return messagedef getWeather():# 爬取天气数据返回的方法,这里就不多编写了send_mes = '#### 今日天气 \n' \'> 9度,西北风1级,空气良89,相对温度73%\n' \'> ![screenshot](https://img.alicdn.com/tfs/TB1NwmBEL9TBuNjy1zbXXXpepXa-2400-1218.png)\n' \'> ###### 10点20分发布 [天气](https://www.dingalk.com) \n'return send_mesif __name__ == "__main__":# 启动服务,端口9000server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)server_socket.bind(("", 9000))server_socket.listen(120)while True:client_socket, client_address = server_socket.accept()print(f"{client_address},用户连接上了")handle_client_process = Process(target=handle_client, args=(client_socket,))handle_client_process.start()client_socket.close()

用python实现钉钉Outgoing机器人(企业内部机器人)全过程相关推荐

  1. 钉钉企业内部机器人python开发(公网部署版本)

    钉钉企业内部机器人开发(公网部署版本) 钉钉给出的开发文档地址如下: https://open.dingtalk.com/document/group/enterprise-created-chatb ...

  2. 钉钉企业内部机器人开发——绑定群聊信息到机器人

    开发机器人的过程中,需要将用户添加的机器人存储在数据库中,对于企业内部机器人,官方只提供一个token,其他的机器人信息都没有提供. 对于自定义webhook机器人,还多了一个secret,其实,一个 ...

  3. 让服务器实时跟你报告 —— 钉钉机器人 企业微信机器人

    写在前面 一入炼丹深似海,希望天下没有空闲的GPU 每次训练开始跑起来总是要不断看什么时候结束,永远副屏都要开着终端实时查看GPU占用情况 原本想着能不能服务器有空闲时给我发邮件提醒呢,简单搜索了一番 ...

  4. 使用钉钉创建企业内部机器人

    目录 玩转钉钉机器人 创建钉钉机器人: 如何创建钉钉机器人 如何调用机器人api 支持的消息格式 text类型 markdown类型 整体跳转actionCard类型 feedCard类型 使用钉钉机 ...

  5. 钉钉企业内部机器人开发——同步组织架构人员信息到数据库

    开发钉钉机器人的过程中,我们不仅需要直接把组织架构用户信息导入数据库,还要不定时的进行同步,因为钉钉里面的人员总是在变动,部门也是不断在调整. 下面是使用递归的方式,调用钉钉接口,同步部门和人员信息, ...

  6. 钉钉小程序开发 (企业内部应用)

    是不是公司内部办公用钉钉的比较多? 哈哈,我现在的公司"是",所以开始了钉钉小程序的开发之路.先来展示一下钉钉官方的教程文档链接------( "钉钉小程序开发教程&qu ...

  7. 使用Python设置钉钉机器人和企业微信机器人的步骤

    文章目录 一.钉钉机器人 0.参考文档 1.创建一个群 2.设置群助手 3.设置机器人信息 4.编写测试文件 5.访问请求,预警成功 二.企业微信机器人 0.消息发送频率限制 1.创建群聊,增加机器人 ...

  8. 钉钉outgoing机器人开发

    这个接口,似乎官网提供出来并不长时间,网上对应博客也很少,那我就贡献 一点思路吧,希望对你有所帮助. 首先,还是详细阅读管网---- 企业内部机器人开发 就这个图,先分析下管网的目录结构. 一,案例介 ...

  9. 如何用钉钉宜搭制定企业疫情防控数字化管理方案?

    简介:[零起点入门系列教程]将会带给大家从业务视角出发由浅入深地学习用宜搭实现应用搭建.即便是没有任何代码基础的新手只要跟着系列课程,从0开始慢慢修炼,也能找到成功搭建应用的乐趣.今天第六讲,示例如何 ...

最新文章

  1. 弹出层,div的写法
  2. 沙龙报名 | 探索新零售时代的数字化创新
  3. window server2008 r2
  4. RBM/DBN训练中的explaining away概念
  5. 月活用户达7.55亿,阿里淘系如何在后流量时代引爆用户增长?
  6. 你见过错误 CS0234...吗?
  7. python kivy canvas_python – Kivy:使用canvas为动画设置动画的正确方法是什么?
  8. 长虹发布AI 3.0 引领电视行业跨入AI3.0时代
  9. java 正则 工具类_正则表达式工具类,正则表达式封装,Java正则表达式
  10. 【最大连接数】Linux的文件最大连接数
  11. 黑马程序员——Java高新技术枚举和自动装箱
  12. 与计算机运算速度相关参数,计算机CPU运算速度是多少
  13. Qt5学习笔记之串口助手三:打包成Windows软件
  14. Quick BI 支持多种数据源进行多维分析
  15. 幼儿园观察记录的目的和目标_幼儿园观察记录应该怎么写?
  16. BM3D算法学习总结
  17. 把一个base64编码的图片绘制到canvas (canvas的图片在转成dataurl)
  18. LM358运放(比较器、跟随器)输出最高电压问题的探讨
  19. TPScan一键ThinkPHP漏洞检测工具使用
  20. E1. Divisible Numbers (easy version)(数学)

热门文章

  1. php email包,PHPMailer下载
  2. 推荐一款实用的百度网盘下载神器
  3. 哪些方法可以有效降低论文的重复率
  4. html+reset+css,关于优酷网reset.css参考
  5. matlab制作字符模板
  6. 13.包装类型应用及场景
  7. vue ElementUI引入第三方icon
  8. cdn.jsdelivr.net无法访问【记录】
  9. AI 绘画,红杉、微软抢疯了
  10. 编程小白的第一本Python入门书学习笔记 Chaper5:循环与判断