Metadata-Version: 2.4
Name: pywecom-webhook
Version: 1.0.3
Summary: 一个简化企业微信群机器人 webhook 调用的 Python 工具包，提供同步和异步发送消息的功能。
Home-page: https://gitee.com/guolei19850528/pywecom_webhook
Author: guolei
Author-email: 174000902@qq.com
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Requires-Python: >=3.6
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: httpx
Requires-Dist: jsonschema
Requires-Dist: decorator
Requires-Dist: jsonpath-ng
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: license-file
Dynamic: requires-dist
Dynamic: requires-python
Dynamic: summary

# pywecom-webhook

企业微信机器人 Webhook API 的 Python SDK，支持发送文本、Markdown、图片、图文、文件、语音等消息类型，同时提供同步和异步两种调用方式。

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Python Version](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/)
[![Code Style: Black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)

## 功能特性

- ✅ 支持多种消息类型：文本、Markdown、MarkdownV2、图片、图文、文件、语音
- ✅ 基于 Pydantic 2.0 实现数据模型验证
- ✅ 支持 @ 指定用户或 @all
- ✅ 支持文件上传（upload_media）
- ✅ 支持模板卡片消息
- ✅ 同步发送器（Sender）
- ✅ 异步发送器（AsyncSender），支持 async with 语法
- ✅ 基于 httpx 实现，支持同步/异步请求

## 安装

使用 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 AsyncSender, TextContent

async def main():
    # 使用 async with 语法
    async with AsyncSender(key="your_webhook_key") as sender:
        result = await sender.send_text(TextContent(content="Hello, Async World!"))
        print(result)

asyncio.run(main())
```

### 发送带 @ 的消息

```python
from pywecom_webhook import Sender, TextContent

sender = Sender(
    key="your_webhook_key",
    mentioned_list=["user1", "user2"],  # 默认 @ 用户列表
    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"],
    mentioned_mobile_list=["13800000000"]
)
sender.send_text(content)

# 异步方式
await async_sender.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="<font color=\"red\">红色文本</font>\n\n<b>加粗文本</b>"
)
sender.send_markdown_v2(content)
```

### 4. 图片消息

```python
import base64
import hashlib
from pywecom_webhook import ImageContent

with open("image.png", "rb") as f:
    image_data = f.read()

content = ImageContent(
    base64=base64.b64encode(image_data).decode("utf-8"),
    md5=hashlib.md5(image_data).hexdigest()
)
sender.send_image(content)
```

### 5. 图文消息

```python
from pywecom_webhook import NewsArticleContent, NewsArticlesContent

article = NewsArticlesContent(
    articles=[
        NewsArticleContent(
            title="文章标题",
            description="文章描述",
            url="https://example.com",
            pic_url="https://example.com/image.jpg"
        )
    ]
)
sender.send_news([article])
```

### 6. 文件消息

```python
from pywecom_webhook import FileContent

# 先上传文件获取 media_id
media_id = sender.upload_media(
    file_type="file",
    files={"file": ("test.txt", open("test.txt", "rb"), "text/plain")}
)

# 发送文件消息
content = FileContent(media_id=media_id)
sender.send_file(content)

# 异步方式
media_id = await async_sender.upload_media(
    file_type="file",
    files={"file": ("test.txt", open("test.txt", "rb"), "text/plain")}
)
await async_sender.send_file(FileContent(media_id=media_id))
```

### 7. 语音消息

```python
from pywecom_webhook import VoiceContent

# 先上传语音文件获取 media_id
media_id = sender.upload_media(
    file_type="voice",
    files={"file": ("voice.amr", open("voice.amr", "rb"), "audio/amr")}
)

# 发送语音消息
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": "描述"
        },
        "card_action": {
            "type": 1,
            "url": "https://example.com"
        }
    }
}
sender.send_template_card(template_card)
```

## API 文档

### Sender 类（同步）

```python
class Sender(
    base_url: str = "https://qyapi.weixin.qq.com/cgi-bin/webhook",
    key: str = None,
    mentioned_list: list = None,
    mentioned_mobile_list: list = None,
    client_kwargs: dict = None
)
```

### AsyncSender 类（异步）

```python
class AsyncSender(
    base_url: str = "https://qyapi.weixin.qq.com/cgi-bin/webhook",
    key: str = None,
    mentioned_list: list = None,
    mentioned_mobile_list: list = None,
    client_kwargs: dict = None
)
```

**参数说明**：
- `base_url`: Webhook 接口地址，默认为官方地址
- `key`: 群机器人的 Webhook key
- `mentioned_list`: 默认 @ 用户列表
- `mentioned_mobile_list`: 默认 @ 手机号列表
- `client_kwargs`: 传递给 httpx.Client / httpx.AsyncClient 的额外参数

### 发送方法

| 同步方法 | 异步方法 | 说明 |
|---------|---------|------|
| `send_text(content)` | `async send_text(content)` | 发送文本消息 |
| `send_markdown(content)` | `async send_markdown(content)` | 发送 Markdown 消息 |
| `send_markdown_v2(content)` | `async send_markdown_v2(content)` | 发送 MarkdownV2 消息 |
| `send_image(content)` | `async send_image(content)` | 发送图片消息 |
| `send_news(content)` | `async send_news(content)` | 发送图文消息 |
| `send_file(content)` | `async send_file(content)` | 发送文件消息 |
| `send_voice(content)` | `async send_voice(content)` | 发送语音消息 |
| `send_template_card(content)` | `async send_template_card(content)` | 发送模板卡片消息 |
| `upload_media(file_type, **kwargs)` | `async upload_media(file_type, **kwargs)` | 上传媒体文件 |
| `send(**kwargs)` | `async send(**kwargs)` | 直接发送消息（底层方法） |


## 企业微信官方文档

参考企业微信官方文档：[群机器人配置说明](https://developer.work.weixin.qq.com/document/path/91770)

## 许可证

MIT License

## 作者

郭磊 <174000902@qq.com>
