-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
zhanghe
committed
Nov 18, 2020
0 parents
commit 0e7a58d
Showing
4 changed files
with
249 additions
and
0 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
# 功能 | ||
|
||
- 发送消息到企业微信机器人。 | ||
- 支持所有企业微信机器人消息类型。 | ||
- [企业微信机器人](https://work.weixin.qq.com/api/doc/90000/90136/91770) | ||
|
||
# 安装 | ||
|
||
```bash | ||
1. 安装该模块 | ||
pip install wechatrobot | ||
``` | ||
|
||
# 使用 | ||
|
||
- 获取微信机器人的 `key` | ||
|
||
创建机器人时,会返回一个 `webhook` 的地址,如 `https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=5cb94c2b-1238-4414-b830-a521523d7a`,则 `key` 为 `5cb94c2b-1238-4414-b830-a521523d7a` | ||
|
||
* 使用 | ||
|
||
```python | ||
key = '5cb94c2b-1238-4414-b830-a521523d7a' | ||
|
||
import wechatrobot | ||
wxrobot = wechatrobot.WechatRobot(key) | ||
``` | ||
|
||
* 发送文本消息 | ||
|
||
```python | ||
# 签名 | ||
wxrobot.send_text(content, at_mobiles=None) | ||
|
||
# content 为要发送的文本内容 | ||
# at_mobiles 需要 @ 人的手机号,可以是列表或字符串。如果要 @所有人,则设置 at_mobiles='all'。@ 多个人时,指定 at_mobiles=['18600000000', '18600000001'] | ||
``` | ||
|
||
* 发送 `markdown` 消息 | ||
|
||
```python | ||
# 签名 | ||
wxrobot.send_markdown(contents) | ||
|
||
# contents 为可迭代对象,如列表、元组等。每一行为一个 markdown格式的字符串。 | ||
# 支持的格式参考:https://work.weixin.qq.com/api/doc/90000/90136/91770#markdown%E7%B1%BB%E5%9E%8B | ||
``` | ||
|
||
* 发送图片 | ||
|
||
```python | ||
# 签名 | ||
wxrobot.send_image(image_path) | ||
|
||
# image_path 支持 HTTP、HTTPS、FTP,互联网上的图片URL。也支持本地的图片路径。 | ||
# 如 wxrobot.send_image('https://img1.maka.im/template/T_G29KRHKN_t1.jpg') | ||
``` | ||
|
||
* 发送图文类型 | ||
|
||
```python | ||
# 签名 | ||
wxrobot.send_news(news_title, jump_url, picurl=None, news_description=None) | ||
|
||
# news_title 消息标题 | ||
# jump_url 跳转url | ||
# picurl 图片的url | ||
# news_description 消息描述 | ||
``` | ||
|
||
* 发送文件 | ||
|
||
```python | ||
# 签名 | ||
wxrobot.send_file(file_path) | ||
|
||
# file_path 要创建的本地文件路径。大小不能超过20M | ||
``` |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
|
||
from setuptools import setup, find_packages | ||
|
||
with open('README.md') as f: | ||
long_description = f.read() | ||
|
||
setup( | ||
name='wechatrobot', | ||
version='1.0.2', | ||
keywords='wechat, robot, wechatrobot, wechat-robot, wechat-webhook', | ||
description='send message to wechat robot', | ||
long_description=long_description, | ||
long_description_content_type='text/markdown', | ||
author='zhanghe', | ||
author_email='[email protected]', | ||
url='https://github.com/x-hezhang/wechat-robot', | ||
license='GNU GPLv3', | ||
packages=find_packages(), | ||
install_requires=['requests'] | ||
) |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# coding: utf-8 | ||
|
||
__author__ = 'zhanghe' | ||
__version__ = '1.0.2' | ||
|
||
from .wechat_robot import WechatRobot |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
import json | ||
import requests | ||
import hashlib | ||
import base64 | ||
from pathlib import Path | ||
|
||
|
||
class FileUploadError(Exception): pass | ||
|
||
|
||
class WechatRobot: | ||
def __init__(self, robot_key): | ||
self.key = robot_key | ||
self.webhook_address = 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=' + self.key | ||
|
||
def _do_request(self, data): | ||
headers = { | ||
'Content-Type': 'application/json; charset=utf-8' | ||
} | ||
|
||
resp = requests.post(self.webhook_address, headers=headers, data=json.dumps(data)) | ||
return resp.json() | ||
|
||
@staticmethod | ||
def _for_image(image_path): | ||
support_url_prefix = ('http://', 'https://', 'ftp://') | ||
remote = False | ||
|
||
for i in support_url_prefix: | ||
if image_path.startswith(i): | ||
remote = True | ||
break | ||
|
||
if remote: | ||
r = requests.get(image_path) | ||
if r.ok: | ||
b64_value = base64.b64encode(r.content).decode('utf-8') | ||
md5_value = hashlib.md5(r.content).hexdigest() | ||
return b64_value, md5_value | ||
else: | ||
return None, None | ||
else: | ||
with open(image_path, 'rb') as f: | ||
content = f.read() | ||
b64_value = base64.b64encode(content).decode('utf-8') | ||
md5_value = hashlib.md5(content).hexdigest() | ||
return b64_value, md5_value | ||
|
||
def send_text(self, content, at_mobiles=None): | ||
at_mobiles_list = [] | ||
if at_mobiles: | ||
if isinstance(at_mobiles, str): | ||
if at_mobiles.lower() == 'all': | ||
at_mobiles_list.append('@all') | ||
else: | ||
at_mobiles_list.append(at_mobiles) | ||
else: | ||
at_mobiles_list = list(at_mobiles) | ||
|
||
data = { | ||
'msgtype': 'text', | ||
'text': { | ||
'content': content, | ||
'mentioned_mobile_list': at_mobiles_list | ||
} | ||
} | ||
|
||
return self._do_request(data) | ||
|
||
def send_markdown(self, contents): | ||
send_contents = '' | ||
for content in contents: | ||
if content.startswith('>'): | ||
send_contents += '\n' + content | ||
else: | ||
send_contents += '\n\n' + content | ||
|
||
data = { | ||
'msgtype': 'markdown', | ||
'markdown': { | ||
'content': send_contents | ||
} | ||
} | ||
return self._do_request(data) | ||
|
||
def send_image(self, image_path): | ||
image_base64, image_md5 = self._for_image(image_path) | ||
data = { | ||
'msgtype': 'image', | ||
'image': { | ||
'base64': image_base64, | ||
'md5': image_md5 | ||
} | ||
} | ||
return self._do_request(data) | ||
|
||
def send_news(self, news_title, jump_url, picurl=None, news_description=None): | ||
data = { | ||
'msgtype': 'news', | ||
'news': { | ||
'articles': [ | ||
{ | ||
'title': news_title, | ||
'url': jump_url, | ||
'description': news_description, | ||
'picurl': picurl | ||
} | ||
] | ||
} | ||
} | ||
|
||
return self._do_request(data) | ||
|
||
def _put_file(self, file_path): | ||
path = Path(file_path) | ||
print(path.name) | ||
if not path.exists(): | ||
raise FileNotFoundError('the file <{}> not found'.format(file_path)) | ||
|
||
put_file_address = 'https://qyapi.weixin.qq.com/cgi-bin/webhook/upload_media?key={}&type=file'.format(self.key) | ||
headers = { | ||
'Content-Type': 'application/octet-stream', | ||
'Content-Disposition': 'form-data; name="media"; filename={}; filelength={}'.format(path.name, | ||
path.stat().st_size) | ||
} | ||
|
||
resp = requests.post(put_file_address, | ||
files=[('media', (path.name, open(file_path, 'rb'), 'application/octet-stream'))]) | ||
return resp.json() | ||
|
||
def send_file(self, file_path): | ||
resp = self._put_file(file_path) | ||
if resp['errcode'] == 0: | ||
media_id = resp['media_id'] | ||
else: | ||
raise FileUploadError(resp) | ||
data = { | ||
'msgtype': 'file', | ||
'file': { | ||
'media_id': media_id | ||
} | ||
} | ||
|
||
return self._do_request(data) | ||
|