py_wecom_toolkit
📄 文档
📖 项目介绍
py_wecom_toolkit 是一个企业微信(WeCom)API 工具包,旨在为 Python 开发者提供简洁、易用的企业微信 API 调用接口。本库支持企业微信的消息推送(原群机器人)、素材管理等核心功能,采用现代 Python 工具链构建,支持 Python 3.9 及以上版本。
本工具包旨在简化与企业微信 API 的交互,提供统一、规范的接口调用方式,帮助开发者快速集成企业微信相关功能到自己的应用中。
🏗️ 软件架构
py_wecom_toolkit/
├── src/py_wecom_toolkit/
│ ├── __init__.py # 包入口,导出版本、作者等元数据
│ ├── py.typed # PEP 561 类型标记文件
│ ├── server/
│ │ ├── __init__.py
│ │ ├── client.py # access_token 获取客户端(基础客户端)
│ │ │ ├── Client # 同步客户端
27: │ │ │ └── AsyncClient # 异步客户端
29: │ │ ├── exception.py # 异常类定义(Error, ConfigError, NetworkError)
30: │ │ ├── response.py # 响应模型(BaseResponse, AccessTokenResponse)
31: │ │ ├── cache.py # 缓存管理(TokenCache, MemoryCache, DiskCache, RedisCache, build_cache_key)
32: │ │ ├── message/ # 消息发送子模块
33: │ │ │ ├── __init__.py
34: │ │ │ ├── client.py # WeCom 消息客户端(同步/异步)
35: │ │ │ └── msgtype.py # 消息类型模型(TextMessage, MarkdownMessage, 等)
36: │ │ └── material/ # 素材管理子模块
37: │ │ ├── __init__.py
38: │ │ ├── client.py # 素材客户端(同步/异步)
39: │ │ ├── msgtype.py # 素材类型模型(MaterialType, UploadResponse, UploadImgResponse)
40: │ │ └── response.py # 素材响应模型(UploadResponse, UploadImgResponse)
41: └── webhook/ # 消息推送(原群机器人)子模块
42: │ ├── __init__.py
43: │ ├── client.py # Webhook 客户端(同步/异步)
44: │ ├── exception.py # 异常类定义
45: │ ├── msgtype.py # 消息类型模型(TextMsgType, MarkdownMsgType, 等)
46: │ └── response.py # 响应模型(BaseResponse, UploadMediaResponse)
├── tests/
49: │ ├── conftest.py # pytest 测试配置和 fixture
50: │ ├── test_access_token.py # access_token 获取测试
51: │ ├── test_message.py # 应用消息发送测试
52: │ └── test_material.py # 素材管理测试
53: ├── examples/ # 使用示例
54: ├── server/
55: │ ├── access_token.py # access_token 获取示例
56: │ ├── message.py # 应用消息发送示例
57: │ └── material.py # 素材管理示例
58: └── webhook/
59: ├── text.py # 文本消息发送示例
60: ├── markdown.py # markdown 消息发送示例
61: ├── markdown_v2.py # markdown_v2 消息发送示例
62: ├── image.py # 图片消息发送示例
63: ├── news.py # 图文消息发送示例
64: ├── file.py # 文件消息发送示例
65: ├── voice.py # 语音消息发送示例
66: └── template_card.py # 模版卡片消息发送示例
核心模块说明
server 模块 - 企业微信服务端 API
| 模块 | 说明 |
|---|---|
server/client.py |
企业微信 access_token 获取客户端,支持同步和异步调用,自动缓存 access_token |
server/exception.py |
定义基础异常类 Error、ConfigError、NetworkError |
server/response.py |
定义响应模型 BaseResponse、AccessTokenResponse,支持 ok 属性判断 |
server/cache.py |
缓存抽象层,支持内存缓存(MemoryCache)、磁盘缓存(DiskCache)、Redis 缓存(RedisCache) |
server/message/client.py |
企业微信应用消息客户端,支持文本、markdown、图片、图文、文件、语音、模版卡片等消息类型 |
server/message/msgtype.py |
消息类型定义,支持 text、markdown、markdown_v2、image、news、file、voice、template_card |
server/material/client.py |
素材管理客户端,支持上传临时素材、上传图片、下载素材 |
server/material/msgtype.py |
素材类型定义,支持 image、voice、video、file 类型 |
server/material/response.py |
素材响应模型 UploadResponse、UploadImgResponse |
webhook 模块 - 消息推送(原群机器人)
| 模块 | 说明 |
|---|---|
webhook/client.py |
Webhook 客户端,支持文本、markdown、图片、图文、文件、语音、模版卡片等消息类型 |
webhook/exception.py |
定义基础异常类 Error、ConfigError、NetworkError、UploadError |
webhook/msgtype.py |
消息类型定义,支持 text、markdown、markdown_v2、image、news、file、voice、template_card |
webhook/response.py |
定义响应模型 BaseResponse、Response、UploadMediaResponse,支持 ok 属性判断 |
🛠️ 安装教程
方式一:使用 uv 安装(推荐)
uv 是一个极快的 Python 包安装和管理工具,推荐使用:
uv add py_wecom_toolkit
方式二:使用 pip 安装
pip install py_wecom_toolkit
方式三:从源码安装
git clone https://gitee.com/guolei19850528/py_wecom_toolkit.git
cd py_wecom_toolkit
uv sync --all-groups
📖 使用说明
1. server 模块 - 企业微信服务端 API
server 模块提供企业微信服务端 API 的访问功能,包括 access_token 获取、应用消息发送、素材管理等。
1.1 获取 access_token
access_token 是企业微信 API 接口的调用凭证,有效期为 2 小时(7200 秒),请务必缓存。
同步获取:
from py_wecom_toolkit.server.client import Client
from py_wecom_toolkit.server.response import AccessTokenResponse
# 初始化客户端
with Client(corpid="your_corp_id", corpsecret="your_corp_secret") as client:
resp: AccessTokenResponse = client.get_token()
if resp.ok:
print(f"access_token: {resp.access_token}")
print(f"expires_in: {resp.expires_in} 秒")
else:
print(f"获取失败: errcode={resp.errcode}, errmsg={resp.errmsg}")
异步获取:
import asyncio
from py_wecom_toolkit.server.client import AsyncClient
from py_wecom_toolkit.server.response import AccessTokenResponse
async def main():
async with AsyncClient(corpid="your_corp_id", corpsecret="your_corp_secret") as client:
resp: AccessTokenResponse = await client.get_token()
if resp.ok:
print(f"access_token: {resp.access_token}")
print(f"expires_in: {resp.expires_in} 秒")
else:
print(f"获取失败: errcode={resp.errcode}, errmsg={resp.errmsg}")
asyncio.run(main())
1.2 发送应用消息
应用消息发送需要企业应用的 corpid、corpsecret 和 agentid(应用 ID)。
发送文本消息:
同步:
from py_wecom_toolkit.server.message.client import Client as MessageClient
from py_wecom_toolkit.server.message.msgtype import TextMessage
with MessageClient(corpid="your_corp_id", corpsecret="your_corp_secret", agentid=1000035) as client:
msg = TextMessage(
touser="Guolei",
agentid=1000035,
text={"content": "Hello, WeCom!"}
)
resp = client.send(msg)
if resp.ok:
print("消息发送成功")
else:
print(f"发送失败: errcode={resp.errcode}, errmsg={resp.errmsg}")
异步:
import asyncio
from py_wecom_toolkit.server.message.client import AsyncClient as MessageClient
from py_wecom_toolkit.server.message.msgtype import TextMessage
async def main():
async with AsyncMessageClient(corpid="your_corp_id", corpsecret="your_corp_secret", agentid=1000035) as client:
msg = TextMessage(
touser="Guolei",
agentid=1000035,
text={"content": "Hello, WeCom!"}
)
resp = await client.send(msg)
if resp.ok:
print("消息发送成功")
else:
print(f"发送失败: errcode={resp.errcode}, errmsg={resp.errmsg}")
asyncio.run(main())
发送 Markdown 消息:
同步:
from py_wecom_toolkit.server.message.client import Client as MessageClient
from py_wecom_toolkit.server.message.msgtype import MarkdownMessage
with MessageClient(corpid="your_corp_id", corpsecret="your_corp_secret", agentid=1000035) as client:
msg = MarkdownMessage(
touser="Guolei",
agentid=1000035,
markdown={"content": "**加粗**\n*斜体*\n[链接](https://example.com)\n> 引用内容"}
)
resp = client.send(msg)
if resp.ok:
print("Markdown 消息发送成功")
else:
print(f"发送失败: errcode={resp.errcode}, errmsg={resp.errmsg}")
异步:
import asyncio
from py_wecom_toolkit.server.message.client import AsyncClient as MessageClient
from py_wecom_toolkit.server.message.msgtype import MarkdownMessage
async def main():
async with AsyncMessageClient(corpid="your_corp_id", corpsecret="your_corp_secret", agentid=1000035) as client:
msg = MarkdownMessage(
touser="Guolei",
agentid=1000035,
markdown={"content": "**加粗**\n*斜体*\n[链接](https://example.com)\n> 引用内容"}
)
resp = await client.send(msg)
if resp.ok:
print("Markdown 消息发送成功")
else:
print(f"发送失败: errcode={resp.errcode}, errmsg={resp.errmsg}")
asyncio.run(main())
发送 Markdown v2 消息:
同步:
from py_wecom_toolkit.server.message.client import Client as MessageClient
from py_wecom_toolkit.server.message.msgtype import MarkdownV2Message
with MessageClient(corpid="your_corp_id", corpsecret="your_corp_secret", agentid=1000035) as client:
msg = MarkdownV2Message(
touser="Guolei",
agentid=1000035,
markdown_v2={"content": "# 标题\n- 列表项1\n- 列表项2\n| 姓名 | 年龄 |\n| --- | --- |\n| 张三 | 25 |"}
)
resp = client.send(msg)
if resp.ok:
print("Markdown v2 消息发送成功")
else:
print(f"发送失败: errcode={resp.errcode}, errmsg={resp.errmsg}")
异步:
import asyncio
from py_wecom_toolkit.server.message.client import AsyncClient as MessageClient
from py_wecom_toolkit.server.message.msgtype import MarkdownV2Message
async def main():
async with AsyncMessageClient(corpid="your_corp_id", corpsecret="your_corp_secret", agentid=1000035) as client:
msg = MarkdownV2Message(
touser="Guolei",
agentid=1000035,
markdown_v2={"content": "# 标题\n- 列表项1\n- 列表项2\n| 姓名 | 年龄 |\n| --- | --- |\n| 张三 | 25 |"}
)
resp = await client.send(msg)
if resp.ok:
print("Markdown v2 消息发送成功")
else:
print(f"发送失败: errcode={resp.errcode}, errmsg={resp.errmsg}")
asyncio.run(main())
发送图片消息:
同步:
from py_wecom_toolkit.server.message.client import Client as MessageClient
from py_wecom_toolkit.server.message.msgtype import ImageMessage
with MessageClient(corpid="your_corp_id", corpsecret="your_corp_secret", agentid=1000035) as client:
msg = ImageMessage(
touser="Guolei",
agentid=1000035,
image={"base64": "BASE64_ENCODED_IMAGE_DATA", "md5": "MD5_OF_BASE64_DATA"}
)
resp = client.send(msg)
if resp.ok:
print("图片消息发送成功")
else:
print(f"发送失败: errcode={resp.errcode}, errmsg={resp.errmsg}")
异步:
import asyncio
from py_wecom_toolkit.server.message.client import AsyncClient as MessageClient
from py_wecom_toolkit.server.message.msgtype import ImageMessage
async def main():
async with AsyncMessageClient(corpid="your_corp_id", corpsecret="your_corp_secret", agentid=1000035) as client:
msg = ImageMessage(
touser="Guolei",
agentid=1000035,
image={"base64": "BASE64_ENCODED_IMAGE_DATA", "md5": "MD5_OF_BASE64_DATA"}
)
resp = await client.send(msg)
if resp.ok:
print("图片消息发送成功")
else:
print(f"发送失败: errcode={resp.errcode}, errmsg={resp.errmsg}")
asyncio.run(main())
发送图文消息:
同步:
from py_wecom_toolkit.server.message.client import Client as MessageClient
from py_wecom_toolkit.server.message.msgtype import NewsMessage
with MessageClient(corpid="your_corp_id", corpsecret="your_corp_secret", agentid=1000035) as client:
msg = NewsMessage(
touser="Guolei",
agentid=1000035,
news={
"articles": [
{
"title": "中秋节礼品领取",
"description": "今年中秋节公司有豪礼相送",
"url": "https://www.qq.com",
"picurl": "https://res.mail.qq.com/node/ww/wwopenmng/images/independent/doc/test_pic_msg1.png"
}
]
}
)
resp = client.send(msg)
if resp.ok:
print("图文消息发送成功")
else:
print(f"发送失败: errcode={resp.errcode}, errmsg={resp.errmsg}")
异步:
import asyncio
from py_wecom_toolkit.server.message.client import AsyncClient as MessageClient
from py_wecom_toolkit.server.message.msgtype import NewsMessage
async def main():
async with AsyncMessageClient(corpid="your_corp_id", corpsecret="your_corp_secret", agentid=1000035) as client:
msg = NewsMessage(
touser="Guolei",
agentid=1000035,
news={
"articles": [
{
"title": "中秋节礼品领取",
"description": "今年中秋节公司有豪礼相送",
"url": "https://www.qq.com",
"picurl": "https://res.mail.qq.com/node/ww/wwopenmng/images/independent/doc/test_pic_msg1.png"
}
]
}
)
resp = await client.send(msg)
if resp.ok:
print("图文消息发送成功")
else:
print(f"发送失败: errcode={resp.errcode}, errmsg={resp.errmsg}")
asyncio.run(main())
发送文件消息:
同步:
from py_wecom_toolkit.server.message.client import Client as MessageClient
from py_wecom_toolkit.server.message.msgtype import FileMessage
with MessageClient(corpid="your_corp_id", corpsecret="your_corp_secret", agentid=1000035) as client:
msg = FileMessage(
touser="Guolei",
agentid=1000035,
file={"media_id": "MEDIA_ID_123"} # 需要先上传文件获取 media_id
)
resp = client.send(msg)
if resp.ok:
print("文件消息发送成功")
else:
print(f"发送失败: errcode={resp.errcode}, errmsg={resp.errmsg}")
异步:
import asyncio
from py_wecom_toolkit.server.message.client import AsyncClient as MessageClient
from py_wecom_toolkit.server.message.msgtype import FileMessage
async def main():
async with AsyncMessageClient(corpid="your_corp_id", corpsecret="your_corp_secret", agentid=1000035) as client:
msg = FileMessage(
touser="Guolei",
agentid=1000035,
file={"media_id": "MEDIA_ID_123"} # 需要先上传文件获取 media_id
)
resp = await client.send(msg)
if resp.ok:
print("文件消息发送成功")
else:
print(f"发送失败: errcode={resp.errcode}, errmsg={resp.errmsg}")
asyncio.run(main())
发送语音消息:
同步:
from py_wecom_toolkit.server.message.client import Client as MessageClient
from py_wecom_toolkit.server.message.msgtype import VoiceMessage
with MessageClient(corpid="your_corp_id", corpsecret="your_corp_secret", agentid=1000035) as client:
msg = VoiceMessage(
touser="Guolei",
agentid=1000035,
voice={"media_id": "MEDIA_ID_VOICE"} # 需要先上传语音文件获取 media_id
)
resp = client.send(msg)
if resp.ok:
print("语音消息发送成功")
else:
print(f"发送失败: errcode={resp.errcode}, errmsg={resp.errmsg}")
异步:
import asyncio
from py_wecom_toolkit.server.message.client import AsyncClient as MessageClient
from py_wecom_toolkit.server.message.msgtype import VoiceMessage
async def main():
async with AsyncMessageClient(corpid="your_corp_id", corpsecret="your_corp_secret", agentid=1000035) as client:
msg = VoiceMessage(
touser="Guolei",
agentid=1000035,
voice={"media_id": "MEDIA_ID_VOICE"} # 需要先上传语音文件获取 media_id
)
resp = await client.send(msg)
if resp.ok:
print("语音消息发送成功")
else:
print(f"发送失败: errcode={resp.errcode}, errmsg={resp.errmsg}")
asyncio.run(main())
发送模版卡片消息:
同步:
from py_wecom_toolkit.server.message.client import Client as MessageClient
from py_wecom_toolkit.server.message.msgtype import TemplateCardMessage
with MessageClient(corpid="your_corp_id", corpsecret="your_corp_secret", agentid=1000035) as client:
msg = TemplateCardMessage(
touser="Guolei",
agentid=1000035,
template_card={
"card_type": "text_notice",
"main_title": {
"title": "欢迎使用企业微信",
"desc": "您的好友正在邀请您加入企业微信"
},
"emphasis_content": {
"title": "100",
"desc": "数据含义"
},
"card_action": {
"type": 1,
"url": "https://work.weixin.qq.com"
}
}
)
resp = client.send(msg)
if resp.ok:
print("模版卡片消息发送成功")
else:
print(f"发送失败: errcode={resp.errcode}, errmsg={resp.errmsg}")
异步:
import asyncio
from py_wecom_toolkit.server.message.client import AsyncClient as MessageClient
from py_wecom_toolkit.server.message.msgtype import TemplateCardMessage
async def main():
async with AsyncMessageClient(corpid="your_corp_id", corpsecret="your_corp_secret", agentid=1000035) as client:
msg = TemplateCardMessage(
touser="Guolei",
agentid=1000035,
template_card={
"card_type": "text_notice",
"main_title": {
"title": "欢迎使用企业微信",
"desc": "您的好友正在邀请您加入企业微信"
},
"emphasis_content": {
"title": "100",
"desc": "数据含义"
},
"card_action": {
"type": 1,
"url": "https://work.weixin.qq.com"
}
}
)
resp = await client.send(msg)
if resp.ok:
print("模版卡片消息发送成功")
else:
print(f"发送失败: errcode={resp.errcode}, errmsg={resp.errmsg}")
asyncio.run(main())
1.4 素材管理
素材上传适用于需要上传文件、图片、语音等素材到企业微信服务器,获取 media_id 后可用于发送相应类型的消息。
上传文件:
同步:
from py_wecom_toolkit.server.material.client import Client as MaterialClient
from py_wecom_toolkit.server.material.msgtype import MaterialType
with MaterialClient(corpid="your_corp_id", corpsecret="your_corp_secret") as client:
resp = client.upload(
media_type=MaterialType.FILE, # 文件类型:file
file="path/to/your/file.txt", # 本地文件路径
filename="file.txt" # 上传展示的文件名
)
if resp.ok:
print(f"上传成功,media_id: {resp.media_id}")
else:
print(f"上传失败: errcode={resp.errcode}, errmsg={resp.errmsg}")
异步:
import asyncio
from py_wecom_toolkit.server.material.client import AsyncClient as MaterialClient
from py_wecom_toolkit.server.material.msgtype import MaterialType
async def main():
async with AsyncMaterialClient(corpid="your_corp_id", corpsecret="your_corp_secret") as client:
resp = await client.upload(
media_type=MaterialType.FILE, # 文件类型:file
file="path/to/your/file.txt", # 本地文件路径
filename="file.txt" # 上传展示的文件名
)
if resp.ok:
print(f"上传成功,media_id: {resp.media_id}")
else:
print(f"上传失败: errcode={resp.errcode}, errmsg={resp.errmsg}")
asyncio.run(main())
上传图片:
同步:
from py_wecom_toolkit.server.material.client import Client as MaterialClient
with MaterialClient(corpid="your_corp_id", corpsecret="your_corp_secret") as client:
resp = client.upload_img(
file="path/to/your/image.jpg",
filename="image.jpg"
)
if resp.ok:
print(f"图片上传成功,URL: {resp.url}")
else:
print(f"上传失败: errcode={resp.errcode}, errmsg={resp.errmsg}")
异步:
import asyncio
from py_wecom_toolkit.server.material.client import AsyncClient as MaterialClient
async def main():
async with AsyncMaterialClient(corpid="your_corp_id", corpsecret="your_corp_secret") as client:
resp = await client.upload_img(
file="path/to/your/image.jpg",
filename="image.jpg"
)
if resp.ok:
print(f"图片上传成功,URL: {resp.url}")
else:
print(f"上传失败: errcode={resp.errcode}, errmsg={resp.errmsg}")
asyncio.run(main())
下载素材:
同步:
from py_wecom_toolkit.server.material.client import Client as MaterialClient
with MaterialClient(corpid="your_corp_id", corpsecret="your_corp_secret") as client:
data = client.download(media_id="MEDIA_ID_123")
if isinstance(data, bytes):
with open("downloaded_file", "wb") as f:
f.write(data)
print(f"下载成功,文件大小: {len(data)} 字节")
else:
print(f"下载失败")
异步:
import asyncio
from py_wecom_toolkit.server.material.client import AsyncClient as MaterialClient
async def main():
async with AsyncMaterialClient(corpid="your_corp_id", corpsecret="your_corp_secret") as client:
data = await client.download(media_id="MEDIA_ID_123")
if isinstance(data, bytes):
with open("downloaded_file", "wb") as f:
f.write(data)
print(f"下载成功,文件大小: {len(data)} 字节")
else:
print(f"下载失败")
asyncio.run(main())
2. webhook 模块 - 消息推送(原群机器人)
Webhook 消息推送(原群机器人)不需要 corpid 和 corpsecret,只需要 Webhook Key 即可发送消息到指定群组。
发送文本消息:
同步:
from py_wecom_toolkit.webhook.client import Client as WebhookClient
with WebhookClient(key="your_webhook_key") as client:
resp = client.send_text("Hello, WeCom Webhook!")
if resp.ok:
print("文本消息发送成功")
else:
print(f"发送失败: errcode={resp.errcode}, errmsg={resp.errmsg}")
异步:
import asyncio
from py_wecom_toolkit.webhook.client import AsyncClient as WebhookClient
async def main():
async with WebhookClient(key="your_webhook_key") as client:
resp = await client.send_text("Hello, WeCom Webhook!")
if resp.ok:
print("文本消息发送成功")
else:
print(f"发送失败: errcode={resp.errcode}, errmsg={resp.errmsg}")
asyncio.run(main())
发送 Markdown 消息:
同步:
from py_wecom_toolkit.webhook.client import Client as WebhookClient
with WebhookClient(key="your_webhook_key") as client:
resp = client.send_markdown("**加粗文本**\n[链接](https://example.com)\n> 引用内容")
if resp.ok:
print("Markdown 消息发送成功")
else:
print(f"发送失败: errcode={resp.errcode}, errmsg={resp.errmsg}")
异步:
import asyncio
from py_wecom_toolkit.webhook.client import AsyncClient as WebhookClient
async def main():
async with WebhookClient(key="your_webhook_key") as client:
resp = await client.send_markdown("**加粗文本**\n[链接](https://example.com)\n> 引用内容")
if resp.ok:
print("Markdown 消息发送成功")
else:
print(f"发送失败: errcode={resp.errcode}, errmsg={resp.errmsg}")
asyncio.run(main())
发送 Markdown V2 消息:
同步:
from py_wecom_toolkit.webhook.client import Client as WebhookClient
with WebhookClient(key="your_webhook_key") as client:
resp = client.send_markdown_v2("# 标题\n- 列表项1\n- 列表项2")
if resp.ok:
print("Markdown V2 消息发送成功")
else:
print(f"发送失败: errcode={resp.errcode}, errmsg={resp.errmsg}")
异步:
import asyncio
from py_wecom_toolkit.webhook.client import AsyncClient as WebhookClient
async def main():
async with WebhookClient(key="your_webhook_key") as client:
resp = await client.send_markdown_v2("# 标题\n- 列表项1\n- 列表项2")
if resp.ok:
print("Markdown V2 消息发送成功")
else:
print(f"发送失败: errcode={resp.errcode}, errmsg={resp.errmsg}")
asyncio.run(main())
发送图片消息:
同步:
from py_wecom_toolkit.webhook.client import Client as WebhookClient
with WebhookClient(key="your_webhook_key") as client:
resp = client.send_image(base64="BASE64_DATA", md5="MD5_HASH")
if resp.ok:
print("图片消息发送成功")
else:
print(f"发送失败: errcode={resp.errcode}, errmsg={resp.errmsg}")
异步:
import asyncio
from py_wecom_toolkit.webhook.client import AsyncClient as WebhookClient
async def main():
async with WebhookClient(key="your_webhook_key") as client:
resp = await client.send_image(base64="BASE64_DATA", md5="MD5_HASH")
if resp.ok:
print("图片消息发送成功")
else:
print(f"发送失败: errcode={resp.errcode}, errmsg={resp.errmsg}")
asyncio.run(main())
发送图文消息:
同步:
from py_wecom_toolkit.webhook.client import Client as WebhookClient
with WebhookClient(key="your_webhook_key") as client:
resp = client.send_news(
articles=[
{
"title": "图文标题",
"description": "图文描述",
"url": "https://example.com",
"picurl": "https://example.com/pic.png"
}
]
)
if resp.ok:
print("图文消息发送成功")
else:
print(f"发送失败: errcode={resp.errcode}, errmsg={resp.errmsg}")
异步:
import asyncio
from py_wecom_toolkit.webhook.client import AsyncClient as WebhookClient
async def main():
async with WebhookClient(key="your_webhook_key") as client:
resp = await client.send_news(
articles=[
{
"title": "图文标题",
"description": "图文描述",
"url": "https://example.com",
"picurl": "https://example.com/pic.png"
}
]
)
if resp.ok:
print("图文消息发送成功")
else:
print(f"发送失败: errcode={resp.errcode}, errmsg={resp.errmsg}")
asyncio.run(main())
发送文件消息:
同步:
from py_wecom_toolkit.webhook.client import Client as WebhookClient
with WebhookClient(key="your_webhook_key") as client:
resp = client.send_file(media_id="MEDIA_ID_123")
if resp.ok:
print("文件消息发送成功")
else:
print(f"发送失败: errcode={resp.errcode}, errmsg={resp.errmsg}")
异步:
import asyncio
from py_wecom_toolkit.webhook.client import AsyncClient as WebhookClient
async def main():
async with WebhookClient(key="your_webhook_key") as client:
resp = await client.send_file(media_id="MEDIA_ID_123")
if resp.ok:
print("文件消息发送成功")
else:
print(f"发送失败: errcode={resp.errcode}, errmsg={resp.errmsg}")
asyncio.run(main())
发送语音消息:
同步:
from py_wecom_toolkit.webhook.client import Client as WebhookClient
with WebhookClient(key="your_webhook_key") as client:
resp = client.send_voice(media_id="MEDIA_ID_VOICE")
if resp.ok:
print("语音消息发送成功")
else:
print(f"发送失败: errcode={resp.errcode}, errmsg={resp.errmsg}")
异步:
import asyncio
from py_wecom_toolkit.webhook.client import AsyncClient as WebhookClient
async def main():
async with WebhookClient(key="your_webhook_key") as client:
resp = await client.send_voice(media_id="MEDIA_ID_VOICE")
if resp.ok:
print("语音消息发送成功")
else:
print(f"发送失败: errcode={resp.errcode}, errmsg={resp.errmsg}")
asyncio.run(main())
发送模版卡片消息:
同步:
from py_wecom_toolkit.webhook.client import Client as WebhookClient
with WebhookClient(key="your_webhook_key") as client:
resp = client.send_template_card(
card_type="text_notice",
main_title_title="欢迎使用企业微信",
main_title_desc="您的好友正在邀请您加入企业微信",
card_action_type=1,
card_action_url="https://work.weixin.qq.com"
)
if resp.ok:
print("模版卡片消息发送成功")
else:
print(f"发送失败: errcode={resp.errcode}, errmsg={resp.errmsg}")
异步:
import asyncio
from py_wecom_toolkit.webhook.client import AsyncClient as WebhookClient
async def main():
async with WebhookClient(key="your_webhook_key") as client:
resp = await client.send_template_card(
card_type="text_notice",
main_title_title="欢迎使用企业微信",
main_title_desc="您的好友正在邀请您加入企业微信",
card_action_type=1,
card_action_url="https://work.weixin.qq.com"
)
if resp.ok:
print("模版卡片消息发送成功")
else:
print(f"发送失败: errcode={resp.errcode}, errmsg={resp.errmsg}")
asyncio.run(main())
🤝 贡献指南
欢迎为 py_wecom_toolkit 贡献代码!如果您想贡献,请按照以下步骤:
- Fork 本仓库
- 创建您的特性分支:
git checkout -b feature/your-feature - 提交您的更改:
git commit -m 'Add some feature' - 推送到分支:
git push origin feature/your-feature - 提交一个拉取请求
请确保提交的代码符合代码风格规范,并通过所有测试用例。
👨💻 作者信息
- 姓名: 郭磊
- 邮箱: 174000902@qq.com
📄 许可证
本项目基于 MIT 许可证 开源。
Metadata
Release files for py-wecom-toolkit 4.0.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| py_wecom_toolkit-4.0.1.tar.gz | 22.0 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| py_wecom_toolkit-4.0.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 29.6 kB
Release files / py_wecom_toolkit-4.0.1.tar.gz
| Download URL | py_wecom_toolkit-4.0.1.tar.gz |
|---|---|
| Size | 22.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
54352a27e90c906f0e1d8e74ed2b40927170f4270ce7a4ca940d4f01d02f2db0
|
|
BLAKE2b-256 checksum How to use checksums |
f28db87d84816335c5b0c600d67386adaaeb9083ca1207ce7798f157cc9fffd4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.6
|
Release files / py_wecom_toolkit-4.0.1-py3-none-any.whl
| Download URL | py_wecom_toolkit-4.0.1-py3-none-any.whl |
|---|---|
| Size | 7.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a6604c38eb3dfc48b43aa0d71a7cf52577b6214831b512a65fbaa0456e777afc
|
|
BLAKE2b-256 checksum How to use checksums |
170d7177f85bc6daca8dad31ded88d142d80512ecc995e04f51078d6c57ca974
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.6
|
Security for py-wecom-toolkit 4.0.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.