Skip to content

Commit

Permalink
初始化代码
Browse files Browse the repository at this point in the history
  • Loading branch information
zhanghe committed Nov 18, 2020
0 parents commit 0e7a58d
Show file tree
Hide file tree
Showing 4 changed files with 249 additions and 0 deletions.
78 changes: 78 additions & 0 deletions README.md
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
```
20 changes: 20 additions & 0 deletions setup.py
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']
)
6 changes: 6 additions & 0 deletions wechatrobot/__init__.py
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
145 changes: 145 additions & 0 deletions wechatrobot/wechat_robot.py
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)

0 comments on commit 0e7a58d

Please sign in to comment.