首页 > 编程语言 > 详细

Python3使用钉钉机器人推送消息(签名方式)

时间:2020-03-08 12:26:54      阅读:175      评论:0      收藏:0      [点我收藏+]
技术分享图片
  1 import time
  2 import hmac
  3 import hashlib
  4 import base64
  5 import urllib
  6 import json
  7 import requests
  8 import logging
  9 
 10 try:
 11     JSONDecodeError = json.decoder.JSONDecodeError
 12 except AttributeError:
 13     JSONDecodeError = ValueError
 14 
 15 
 16 def is_not_null_and_blank_str(content):
 17     if content and content.strip():
 18         return True
 19     else:
 20         return False
 21 
 22 
 23 class DingtalkRobot(object):
 24     def __init__(self, webhook, sign=None):
 25         super(DingtalkRobot, self).__init__()
 26         self.webhook = webhook
 27         self.sign = sign
 28         self.headers = {Content-Type: application/json; charset=utf-8}
 29         self.times = 0
 30         self.start_time = time.time()
 31 
 32     # 加密签名
 33     def __spliceUrl(self):
 34         timestamp = int(round(time.time() * 1000))
 35         secret = self.sign
 36         secret_enc = secret.encode(utf-8)
 37         string_to_sign = {}\n{}.format(timestamp, secret)
 38         string_to_sign_enc = string_to_sign.encode(utf-8)
 39         hmac_code = hmac.new(secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest()
 40         sign = urllib.parse.quote_plus(base64.b64encode(hmac_code))
 41         url = f"{self.webhook}&timestamp={timestamp}&sign={sign}"
 42         return url
 43 
 44     def send_text(self, msg, is_at_all=False, at_mobiles=[]):
 45         data = {"msgtype": "text", "at": {}}
 46         if is_not_null_and_blank_str(msg):
 47             data["text"] = {"content": msg}
 48         else:
 49             logging.error("text类型,消息内容不能为空!")
 50             raise ValueError("text类型,消息内容不能为空!")
 51 
 52         if is_at_all:
 53             data["at"]["isAtAll"] = is_at_all
 54 
 55         if at_mobiles:
 56             at_mobiles = list(map(str, at_mobiles))
 57             data["at"]["atMobiles"] = at_mobiles
 58 
 59         logging.debug(text类型:%s % data)
 60         return self.__post(data)
 61 
 62     def __post(self, data):
 63         """
 64         发送消息(内容UTF-8编码)
 65         :param data: 消息数据(字典)
 66         :return: 返回发送结果
 67         """
 68         self.times += 1
 69         if self.times > 20:
 70             if time.time() - self.start_time < 60:
 71                 logging.debug(钉钉官方限制每个机器人每分钟最多发送20条,当前消息发送频率已达到限制条件,休眠一分钟)
 72                 time.sleep(60)
 73             self.start_time = time.time()
 74 
 75         post_data = json.dumps(data)
 76         try:
 77             response = requests.post(self.__spliceUrl(), headers=self.headers, data=post_data)
 78         except requests.exceptions.HTTPError as exc:
 79             logging.error("消息发送失败, HTTP error: %d, reason: %s" % (exc.response.status_code, exc.response.reason))
 80             raise
 81         except requests.exceptions.ConnectionError:
 82             logging.error("消息发送失败,HTTP connection error!")
 83             raise
 84         except requests.exceptions.Timeout:
 85             logging.error("消息发送失败,Timeout error!")
 86             raise
 87         except requests.exceptions.RequestException:
 88             logging.error("消息发送失败, Request Exception!")
 89             raise
 90         else:
 91             try:
 92                 result = response.json()
 93             except JSONDecodeError:
 94                 logging.error("服务器响应异常,状态码:%s,响应内容:%s" % (response.status_code, response.text))
 95                 return {errcode: 500, errmsg: 服务器响应异常}
 96             else:
 97                 logging.debug(发送结果:%s % result)
 98                 if result[errcode]:
 99                     error_data = {"msgtype": "text", "text": {"content": "钉钉机器人消息发送失败,原因:%s" % result[errmsg]},
100                                   "at": {"isAtAll": True}}
101                     logging.error("消息发送失败,自动通知:%s" % error_data)
102                     requests.post(self.webhook, headers=self.headers, data=json.dumps(error_data))
103                 return result
104 
105 
106 if __name__ == __main__:
107     URL = "你的钉钉机器人地址"
108     SIGN = "签名"
109     ding = DingtalkRobot(URL, SIGN)
110     print(ding.send_text("Hello World"))
View Code

做通知实例,如图:

技术分享图片

Python3使用钉钉机器人推送消息(签名方式)

原文:https://www.cnblogs.com/kingling/p/12441416.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!