Skip to content

Instantly share code, notes, and snippets.

@BruceZhang1993
Created November 30, 2019 06:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save BruceZhang1993/96fe893e58848f09af396a7f79dca260 to your computer and use it in GitHub Desktop.
Save BruceZhang1993/96fe893e58848f09af396a7f79dca260 to your computer and use it in GitHub Desktop.
钉钉 WebHook 机器人的 Python 实现
#!/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 += '&timestamp=%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