# pywecom_webhook
**Repository Path**: guolei19850528/pywecom_webhook
## Basic Information
- **Project Name**: pywecom_webhook
- **Description**: 企业微信机器人 Webhook API 的 Python SDK,支持发送文本、Markdown、图片、图文、文件、语音等消息类型,同时提供同步和异步两种调用方式。
- **Primary Language**: Python
- **License**: MIT
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2026-06-12
- **Last Updated**: 2026-06-16
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# pywecom-webhook
企业微信机器人 Webhook API 的 Python SDK,支持发送文本、Markdown、图片、图文、文件、语音等消息类型,同时提供同步和异步两种调用方式。
[](https://opensource.org/licenses/MIT)
[](https://www.python.org/)
## 功能特性
- ✅ 支持多种消息类型:文本、Markdown、MarkdownV2、图片、图文、文件、语音、模板卡片
- ✅ 基于 Pydantic 实现数据模型验证,确保数据格式正确性
- ✅ 支持 @ 指定用户或 @all 功能
- ✅ 支持文件上传(upload_media)获取 media_id
- ✅ 同一个 Sender 类支持同步和异步两种调用方式
- ✅ 基于 httpx 实现,支持同步/异步 HTTP 请求
## 安装
### 使用 pip 安装
```bash
pip install pywecom-webhook
```
### 从源码安装
```bash
git clone https://gitee.com/guolei19850528/pywecom_webhook.git
cd pywecom-webhook
pip install .
```
## 快速开始
### 同步发送消息
```python
from pywecom_webhook import Sender, TextContent
# 创建 Sender 实例(默认同步模式)
sender = Sender(key="your_webhook_key")
# 发送文本消息
result = sender.send_text(TextContent(content="Hello, World!"))
print(result)
```
### 异步发送消息
```python
import asyncio
from pywecom_webhook import Sender, TextContent
async def main():
# 创建异步 Sender 实例
sender = Sender(key="your_webhook_key", use_async_client=True)
# 发送文本消息
result = await sender.async_send_text(TextContent(content="Hello, Async World!"))
print(result)
asyncio.run(main())
```
### 发送带 @ 的消息
```python
from pywecom_webhook import Sender, TextContent
# 创建 Sender 实例,设置默认 @ 用户列表
sender = Sender(
key="your_webhook_key",
mentioned_list=["user1", "user2"], # 默认 @ 用户 ID 列表
mentioned_mobile_list=["13800000000"] # 默认 @ 手机号列表
)
# 发送带 @ 的文本消息
result = sender.send_text(
TextContent(
content="重要通知:系统即将维护",
mentioned_list=["@all"], # @ 所有人
mentioned_mobile_list=["13900000000"] # @ 指定手机号用户
)
)
```
## 消息类型示例
### 1. 文本消息
```python
from pywecom_webhook import TextContent
content = TextContent(
content="这是一条普通文本消息",
mentioned_list=["user_id_1", "user_id_2"],
mentioned_mobile_list=["13800000000"]
)
sender.send_text(content)
# 异步方式
await sender.async_send_text(content)
```
### 2. Markdown 消息
```python
from pywecom_webhook import MarkdownContent
content = MarkdownContent(
content="""## 标题
**加粗文本**
*斜体文本*
> 引用文本
[链接](https://example.com)
"""
)
sender.send_markdown(content)
```
### 3. MarkdownV2 消息
```python
from pywecom_webhook import MarkdownV2Content
content = MarkdownV2Content(
content="红色文本\n\n加粗文本"
)
sender.send_markdown_v2(content)
```
### 4. 图片消息
```python
from pywecom_webhook import ImageContent
from pywecom_webhook.utils import image_to_base64_and_md5
# 使用工具函数转换图片
base64_str, md5_str = image_to_base64_and_md5("image.png")
content = ImageContent(
base64=base64_str,
md5=md5_str
)
sender.send_image(content)
```
### 5. 图文消息
```python
from pywecom_webhook import NewsArticleContent
articles = [
NewsArticleContent(
title="文章标题",
description="文章描述",
url="https://example.com",
pic_url="https://example.com/image.jpg"
)
]
sender.send_news(articles)
```
### 6. 文件消息
```python
from pywecom_webhook import FileContent
# 先上传文件获取 media_id
response = sender.upload_media(
file_type="file",
files={"file": ("test.txt", open("test.txt", "rb"), "text/plain")}
)
media_id = response.json().get("media_id")
# 发送文件消息
content = FileContent(media_id=media_id)
sender.send_file(content)
```
### 7. 语音消息
```python
from pywecom_webhook import VoiceContent
# 先上传语音文件获取 media_id
response = sender.upload_media(
file_type="voice",
files={"file": ("voice.amr", open("voice.amr", "rb"), "audio/amr")}
)
media_id = response.json().get("media_id")
# 发送语音消息
content = VoiceContent(media_id=media_id)
sender.send_voice(content)
```
### 8. 模板卡片消息
```python
template_card = {
"msgtype": "template_card",
"template_card": {
"card_type": "text_notice",
"source": {
"icon_url": "https://example.com/icon.png",
"desc": "通知来源"
},
"main_title": {
"title": "系统维护通知",
"desc": "预计维护时间:2024-01-01 00:00-02:00"
},
"card_action": {
"type": 1,
"url": "https://example.com/maintenance"
}
}
}
sender.send_template_card(template_card)
```
## API 文档
### Sender 类
```python
class Sender(
base_url: HttpUrl = "https://qyapi.weixin.qq.com/cgi-bin/webhook/",
key: str = None,
mentioned_list: Optional[list] = None,
mentioned_mobile_list: Optional[list] = None,
client_kwargs: dict = None,
use_async_client: bool = False
)
```
**参数说明**:
| 参数 | 类型 | 说明 |
|------|------|------|
| `base_url` | HttpUrl | Webhook 接口地址,默认为官方地址 |
| `key` | str | 群机器人的 Webhook key |
| `mentioned_list` | Optional[list] | 默认 @ 用户 ID 列表 |
| `mentioned_mobile_list` | Optional[list] | 默认 @ 用户手机号列表 |
| `client_kwargs` | dict | 传递给 httpx.Client 的额外参数 |
| `use_async_client` | bool | 是否使用异步客户端,默认为 False |
### 发送方法
| 同步方法 | 异步方法 | 说明 |
|---------|---------|------|
| `send_text(content)` | `async async_send_text(content)` | 发送文本消息 |
| `send_markdown(content)` | `async async_send_markdown(content)` | 发送 Markdown 消息 |
| `send_markdown_v2(content)` | `async async_send_markdown_v2(content)` | 发送 MarkdownV2 消息 |
| `send_image(content)` | `async async_send_image(content)` | 发送图片消息 |
| `send_news(content)` | `async async_send_news(content)` | 发送图文消息 |
| `send_file(content)` | `async async_send_file(content)` | 发送文件消息 |
| `send_voice(content)` | `async async_send_voice(content)` | 发送语音消息 |
| `send_template_card(content)` | `async async_send_template_card(content)` | 发送模板卡片消息 |
| `upload_media(file_type, **kwargs)` | `async async_upload_media(file_type, **kwargs)` | 上传媒体文件 |
## 工具函数
### image_to_base64_and_md5
将图片文件转换为 Base64 编码和 MD5 校验值。
```python
from pywecom_webhook.utils import image_to_base64_and_md5
base64_str, md5_str = image_to_base64_and_md5("image.png")
```
### get_send_result
判断消息发送是否成功。
```python
from pywecom_webhook.utils import get_send_result
result = sender.send_text(TextContent(content="Hello"))
success = get_send_result(result)
```
### get_upload_result
从上传媒体文件的响应中提取 media_id。
```python
from pywecom_webhook.utils import get_upload_result
response = sender.upload_media(file_type="file", files={"file": ("test.txt", open("test.txt", "rb"))})
media_id = get_upload_result(response)
```
## 企业微信官方文档
参考企业微信官方文档:[群机器人配置说明](https://developer.work.weixin.qq.com/document/path/91770)
## 许可证
MIT License
## 作者
郭磊 <174000902@qq.com>
## 项目主页
[https://gitee.com/guolei19850528/pywecom_webhook](https://gitee.com/guolei19850528/pywecom_webhook)