Created
November 30, 2019 06:45
-
-
Save BruceZhang1993/96fe893e58848f09af396a7f79dca260 to your computer and use it in GitHub Desktop.
钉钉 WebHook 机器人的 Python 实现
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
#*-- coding: utf-8 --* | |
import json | |
import argparse | |
import time | |
import hmac | |
import hashlib | |
import base64 | |
from urllib import parse, request | |
# 钉钉机器人 Token | |
TOKEN = '' | |
# 钉钉机器人 Webhook 地址 | |
CHAT_API = 'https://oapi.dingtalk.com/robot/send?access_token={}' | |
# 签名密钥 (不使用设置为 None) | |
CRYPTION_KEY = None | |
def _get_signature(secret): | |
timestamp = round(time.time() * 1000) | |
unencrypted = '{}\n{}'.format(timestamp, secret) | |
hmac_code = hmac.new(secret.encode(), unencrypted.encode(), digestmod=hashlib.sha256).digest() | |
return (timestamp, parse.quote_plus(base64.b64encode(hmac_code))) | |
def _format_uri(): | |
uri = CHAT_API.format(TOKEN) | |
if CRYPTION_KEY: | |
data = _get_signature(CRYPTION_KEY) | |
uri += '×tamp=%s&sign=%s' % data | |
return uri | |
def _do_request(uri, data): | |
data = json.dumps(data).encode() | |
response = request.urlopen(request.Request(uri, data=data, headers={'Content-Type': 'application/json'})) | |
return json.loads(response.read()) | |
def text(content, at_mobiles = [], at_all = False): | |
params = { | |
'msgtype': 'text', | |
'text': { | |
'content': content.format(*list(map(lambda x: '@' + x, at_mobiles))) | |
}, | |
'at': { | |
'atMobiles': at_mobiles, | |
'isAtAll': at_all | |
} | |
} | |
return _do_request(_format_uri(), params) | |
def link(title, text, uri, pic_uri=None): | |
params = { | |
'msgtype': 'link', | |
'link': { | |
'text': text, | |
'title': title, | |
'messageUrl': uri, | |
'picUrl': pic_uri or '' | |
} | |
} | |
return _do_request(_format_uri(), params) | |
def markdown(title, content, at_mobiles = [], at_all = False): | |
params = { | |
'msgtype': 'markdown', | |
'markdown': { | |
'title': title, | |
'text': content.format(*list(map(lambda x: '@' + x, at_mobiles))) | |
}, | |
'at': { | |
'atMobiles': at_mobiles, | |
'isAtAll': at_all | |
} | |
} | |
return _do_request(_format_uri(), params) | |
def simple_action_card(title, content, bottom, url, orientation=None, hide_avatar=None): | |
params = { | |
'msgtype': 'actionCard', | |
'actionCard': { | |
'title': title, | |
'text': content, | |
'hideAvatar': 1 if hide_avatar else 0, | |
'btnOrientation': 1 if orientation else 0, | |
'singleTitle': bottom, | |
'singleURL': url | |
} | |
} | |
return _do_request(_format_uri(), params) | |
def multi_action_card(title, content, buttons = [], orientation=None, hide_avatar=None): | |
params = { | |
'msgtype': 'actionCard', | |
'actionCard': { | |
'title': title, | |
'text': content, | |
'hideAvatar': 1 if hide_avatar else 0, | |
'btnOrientation': 1 if orientation else 0, | |
'btns': list(map(lambda btn: {'title': btn[0], 'actionURL': btn[1]}, buttons)) | |
} | |
} | |
return _do_request(_format_uri(), params) | |
def feed_card(*links): | |
params = { | |
'msgtype': 'feedCard', | |
'feedCard': { | |
'links': list(map(lambda link: {'title': link[0], 'messageURL': link[1], 'picURL': link[2]}, links)) | |
} | |
} | |
return _do_request(_format_uri(), params) | |
def custom(): | |
pass | |
def main(): | |
def command_filter(val): | |
if callable(val[1]) and not val[0].startswith('_') and val[0] != 'main': | |
return True | |
return False | |
def evaluate(string): | |
try: | |
return eval(string) | |
except: | |
return string | |
functions = dict(filter(command_filter, globals().items())) | |
commands = list(functions.keys()) | |
parser = argparse.ArgumentParser(description='DingTalk Bot CLI') | |
parser.add_argument('command', choices=commands, help='Message type') | |
parser.add_argument('arguments', nargs='*', default=None, help='Arguments') | |
arguments = parser.parse_args() | |
print(functions[arguments.command](*list(map(evaluate, arguments.arguments)))) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment