wps-webhook-bot 0.1.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- wps_webhook_bot-0.1.1/LICENSE +21 -0
- wps_webhook_bot-0.1.1/PKG-INFO +99 -0
- wps_webhook_bot-0.1.1/README.md +73 -0
- wps_webhook_bot-0.1.1/pyproject.toml +38 -0
- wps_webhook_bot-0.1.1/setup.cfg +4 -0
- wps_webhook_bot-0.1.1/src/wps_webhook_bot/__init__.py +7 -0
- wps_webhook_bot-0.1.1/src/wps_webhook_bot/bot.py +200 -0
- wps_webhook_bot-0.1.1/src/wps_webhook_bot/py.typed +0 -0
- wps_webhook_bot-0.1.1/src/wps_webhook_bot.egg-info/PKG-INFO +99 -0
- wps_webhook_bot-0.1.1/src/wps_webhook_bot.egg-info/SOURCES.txt +11 -0
- wps_webhook_bot-0.1.1/src/wps_webhook_bot.egg-info/dependency_links.txt +1 -0
- wps_webhook_bot-0.1.1/src/wps_webhook_bot.egg-info/requires.txt +1 -0
- wps_webhook_bot-0.1.1/src/wps_webhook_bot.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 wps-webhook-bot developers
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: wps-webhook-bot
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: WPS 协作(xz.wps.cn)群机器人 Webhook 通知 SDK,支持文本 / Markdown / 卡片三种消息格式
|
|
5
|
+
Author-email: wps-webhook-bot developers <wps-webhook-bot@example.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Documentation, http://open.wps.cn/documents/app-integration-dev/guide/robot/webhook
|
|
8
|
+
Keywords: wps,webhook,bot,robot,notification,协作机器人
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Topic :: Communications :: Chat
|
|
20
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
21
|
+
Requires-Python: >=3.8
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Requires-Dist: requests>=2.20
|
|
25
|
+
Dynamic: license-file
|
|
26
|
+
|
|
27
|
+
# wps-webhook-bot
|
|
28
|
+
|
|
29
|
+
WPS 协作(xz.wps.cn)群机器人 Webhook 通知 SDK,支持 **文本 / Markdown / 卡片** 三种消息格式。
|
|
30
|
+
|
|
31
|
+
协议参考:[WPS 开放平台 - webhook 机器人](http://open.wps.cn/documents/app-integration-dev/guide/robot/webhook)
|
|
32
|
+
|
|
33
|
+
## 安装
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
pip install wps-webhook-bot
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## 快速开始
|
|
40
|
+
|
|
41
|
+
在 WPS 协作群聊中添加自定义机器人,复制 Webhook 地址(形如 `https://xz.wps.cn/api/v1/webhook/send?key=xxxx`),然后:
|
|
42
|
+
|
|
43
|
+
```python
|
|
44
|
+
from wps_webhook_bot import WebhookBot
|
|
45
|
+
|
|
46
|
+
bot = WebhookBot("https://xz.wps.cn/api/v1/webhook/send?key=YOUR_KEY")
|
|
47
|
+
|
|
48
|
+
# 1. 文本消息(支持 @ 指定成员 / 所有人)
|
|
49
|
+
bot.send_text("部署完成", at_all=True)
|
|
50
|
+
bot.send_text("请查收报告", at_user_ids=["17856"], at_emails=["somebody@wps.cn"])
|
|
51
|
+
|
|
52
|
+
# 2. Markdown 消息(标题/加粗/引用/颜色/链接)
|
|
53
|
+
bot.send_markdown(
|
|
54
|
+
"### 构建通知\n"
|
|
55
|
+
"> 分支:main\n\n"
|
|
56
|
+
"状态:<font color='#07C160'>成功</font> "
|
|
57
|
+
"[查看详情](https://xz.wps.cn)"
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
# 3. 卡片消息(主/副标题 + 组件 + 整卡跳转)
|
|
61
|
+
bot.send_card(
|
|
62
|
+
title="nightly 构建 #123 完成",
|
|
63
|
+
subtitle="2026-08-26",
|
|
64
|
+
elements=[
|
|
65
|
+
WebhookBot.text_element("**通过率**:<font color='#07C160'>100%</font>"),
|
|
66
|
+
WebhookBot.hr_element(),
|
|
67
|
+
WebhookBot.text_element("耗时:3 分 25 秒", markdown=False),
|
|
68
|
+
],
|
|
69
|
+
link="https://xz.wps.cn",
|
|
70
|
+
)
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## API 一览
|
|
74
|
+
|
|
75
|
+
| 方法 | 说明 |
|
|
76
|
+
|---|---|
|
|
77
|
+
| `send_text(content, at_user_ids=None, at_emails=None, at_all=False)` | 文本消息,支持 `<at>` 标签 @ 人 |
|
|
78
|
+
| `send_markdown(text, at_user_ids=None, at_emails=None, at_all=False)` | Markdown 消息 |
|
|
79
|
+
| `send_card(title, subtitle="", elements=None, link="", pc_url="", ios_url="", android_url="")` | 卡片消息,支持分端跳转链接 |
|
|
80
|
+
| `WebhookBot.text_element(text, markdown=True)` | 构造卡片文本组件 |
|
|
81
|
+
| `WebhookBot.hr_element()` | 构造卡片分割线组件 |
|
|
82
|
+
|
|
83
|
+
发送失败会抛出 `WebhookBotError`,异常信息中包含服务端返回内容,便于排查。
|
|
84
|
+
|
|
85
|
+
## Markdown 语法子集
|
|
86
|
+
|
|
87
|
+
标题(`#` ~ `######`)、加粗(`**`)、斜体(`*` / `_`)、引用(`>`)、链接(`[文字](url)`)、
|
|
88
|
+
颜色(`<font color='#FF0000'>文字</font>`)、@人(`<at user_id="12345">姓名</at>`)。
|
|
89
|
+
换行使用「双空格 + `\n`」或「`\n\n`」。
|
|
90
|
+
|
|
91
|
+
## 平台限制
|
|
92
|
+
|
|
93
|
+
- 每个机器人发送频率不超过 **20 条/分钟**
|
|
94
|
+
- 每条消息不超过 **5000 个字符**
|
|
95
|
+
- 卡片组件总数不超过 20 个;Webhook 卡片暂不支持回传型交互组件(回传按钮、列表选择器、日期选择器、输入框)
|
|
96
|
+
|
|
97
|
+
## License
|
|
98
|
+
|
|
99
|
+
MIT
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# wps-webhook-bot
|
|
2
|
+
|
|
3
|
+
WPS 协作(xz.wps.cn)群机器人 Webhook 通知 SDK,支持 **文本 / Markdown / 卡片** 三种消息格式。
|
|
4
|
+
|
|
5
|
+
协议参考:[WPS 开放平台 - webhook 机器人](http://open.wps.cn/documents/app-integration-dev/guide/robot/webhook)
|
|
6
|
+
|
|
7
|
+
## 安装
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pip install wps-webhook-bot
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## 快速开始
|
|
14
|
+
|
|
15
|
+
在 WPS 协作群聊中添加自定义机器人,复制 Webhook 地址(形如 `https://xz.wps.cn/api/v1/webhook/send?key=xxxx`),然后:
|
|
16
|
+
|
|
17
|
+
```python
|
|
18
|
+
from wps_webhook_bot import WebhookBot
|
|
19
|
+
|
|
20
|
+
bot = WebhookBot("https://xz.wps.cn/api/v1/webhook/send?key=YOUR_KEY")
|
|
21
|
+
|
|
22
|
+
# 1. 文本消息(支持 @ 指定成员 / 所有人)
|
|
23
|
+
bot.send_text("部署完成", at_all=True)
|
|
24
|
+
bot.send_text("请查收报告", at_user_ids=["17856"], at_emails=["somebody@wps.cn"])
|
|
25
|
+
|
|
26
|
+
# 2. Markdown 消息(标题/加粗/引用/颜色/链接)
|
|
27
|
+
bot.send_markdown(
|
|
28
|
+
"### 构建通知\n"
|
|
29
|
+
"> 分支:main\n\n"
|
|
30
|
+
"状态:<font color='#07C160'>成功</font> "
|
|
31
|
+
"[查看详情](https://xz.wps.cn)"
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
# 3. 卡片消息(主/副标题 + 组件 + 整卡跳转)
|
|
35
|
+
bot.send_card(
|
|
36
|
+
title="nightly 构建 #123 完成",
|
|
37
|
+
subtitle="2026-08-26",
|
|
38
|
+
elements=[
|
|
39
|
+
WebhookBot.text_element("**通过率**:<font color='#07C160'>100%</font>"),
|
|
40
|
+
WebhookBot.hr_element(),
|
|
41
|
+
WebhookBot.text_element("耗时:3 分 25 秒", markdown=False),
|
|
42
|
+
],
|
|
43
|
+
link="https://xz.wps.cn",
|
|
44
|
+
)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## API 一览
|
|
48
|
+
|
|
49
|
+
| 方法 | 说明 |
|
|
50
|
+
|---|---|
|
|
51
|
+
| `send_text(content, at_user_ids=None, at_emails=None, at_all=False)` | 文本消息,支持 `<at>` 标签 @ 人 |
|
|
52
|
+
| `send_markdown(text, at_user_ids=None, at_emails=None, at_all=False)` | Markdown 消息 |
|
|
53
|
+
| `send_card(title, subtitle="", elements=None, link="", pc_url="", ios_url="", android_url="")` | 卡片消息,支持分端跳转链接 |
|
|
54
|
+
| `WebhookBot.text_element(text, markdown=True)` | 构造卡片文本组件 |
|
|
55
|
+
| `WebhookBot.hr_element()` | 构造卡片分割线组件 |
|
|
56
|
+
|
|
57
|
+
发送失败会抛出 `WebhookBotError`,异常信息中包含服务端返回内容,便于排查。
|
|
58
|
+
|
|
59
|
+
## Markdown 语法子集
|
|
60
|
+
|
|
61
|
+
标题(`#` ~ `######`)、加粗(`**`)、斜体(`*` / `_`)、引用(`>`)、链接(`[文字](url)`)、
|
|
62
|
+
颜色(`<font color='#FF0000'>文字</font>`)、@人(`<at user_id="12345">姓名</at>`)。
|
|
63
|
+
换行使用「双空格 + `\n`」或「`\n\n`」。
|
|
64
|
+
|
|
65
|
+
## 平台限制
|
|
66
|
+
|
|
67
|
+
- 每个机器人发送频率不超过 **20 条/分钟**
|
|
68
|
+
- 每条消息不超过 **5000 个字符**
|
|
69
|
+
- 卡片组件总数不超过 20 个;Webhook 卡片暂不支持回传型交互组件(回传按钮、列表选择器、日期选择器、输入框)
|
|
70
|
+
|
|
71
|
+
## License
|
|
72
|
+
|
|
73
|
+
MIT
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "wps-webhook-bot"
|
|
7
|
+
version = "0.1.1"
|
|
8
|
+
description = "WPS 协作(xz.wps.cn)群机器人 Webhook 通知 SDK,支持文本 / Markdown / 卡片三种消息格式"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.8"
|
|
11
|
+
license = { text = "MIT" }
|
|
12
|
+
authors = [
|
|
13
|
+
{ name = "wps-webhook-bot developers", email = "wps-webhook-bot@example.com" },
|
|
14
|
+
]
|
|
15
|
+
keywords = ["wps", "webhook", "bot", "robot", "notification", "协作机器人"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 4 - Beta",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"License :: OSI Approved :: MIT License",
|
|
20
|
+
"Operating System :: OS Independent",
|
|
21
|
+
"Programming Language :: Python :: 3",
|
|
22
|
+
"Programming Language :: Python :: 3.8",
|
|
23
|
+
"Programming Language :: Python :: 3.9",
|
|
24
|
+
"Programming Language :: Python :: 3.10",
|
|
25
|
+
"Programming Language :: Python :: 3.11",
|
|
26
|
+
"Programming Language :: Python :: 3.12",
|
|
27
|
+
"Topic :: Communications :: Chat",
|
|
28
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
29
|
+
]
|
|
30
|
+
dependencies = [
|
|
31
|
+
"requests>=2.20",
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
[project.urls]
|
|
35
|
+
Documentation = "http://open.wps.cn/documents/app-integration-dev/guide/robot/webhook"
|
|
36
|
+
|
|
37
|
+
[tool.setuptools.packages.find]
|
|
38
|
+
where = ["src"]
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
WPS 协作机器人 Webhook 通知 SDK
|
|
4
|
+
================================
|
|
5
|
+
|
|
6
|
+
适用于 WPS 协作(xz.wps.cn)群机器人 Webhook,支持三种消息格式:
|
|
7
|
+
1. 文本消息 :meth:`WebhookBot.send_text`
|
|
8
|
+
2. Markdown :meth:`WebhookBot.send_markdown`
|
|
9
|
+
3. 卡片消息 :meth:`WebhookBot.send_card`
|
|
10
|
+
|
|
11
|
+
协议文档:http://open.wps.cn/documents/app-integration-dev/guide/robot/webhook
|
|
12
|
+
|
|
13
|
+
平台限制:
|
|
14
|
+
- 每个机器人发送频率不超过 20 条/分钟
|
|
15
|
+
- 每条消息不超过 5000 个字符
|
|
16
|
+
- Webhook 卡片不支持回传型交互组件(回传按钮、列表选择器、日期选择器、输入框)
|
|
17
|
+
|
|
18
|
+
使用示例:
|
|
19
|
+
>>> bot = WebhookBot("https://xz.wps.cn/api/v1/webhook/send?key=YOUR_KEY")
|
|
20
|
+
>>> bot.send_text("部署完成", at_all=True)
|
|
21
|
+
>>> bot.send_markdown("### 构建通知\\n状态:**成功**")
|
|
22
|
+
>>> bot.send_card(
|
|
23
|
+
... title="nightly 构建 #123 完成",
|
|
24
|
+
... subtitle="2026-08-26",
|
|
25
|
+
... elements=[WebhookBot.text_element("**通过率**:100%")],
|
|
26
|
+
... link="https://xz.wps.cn",
|
|
27
|
+
... )
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
import json
|
|
31
|
+
from typing import Dict, Optional, Sequence, Union
|
|
32
|
+
|
|
33
|
+
import requests
|
|
34
|
+
|
|
35
|
+
__all__ = ["WebhookBot", "WebhookBotError"]
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class WebhookBotError(Exception):
|
|
39
|
+
"""机器人消息发送失败时抛出。"""
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class WebhookBot:
|
|
43
|
+
"""WPS 协作机器人 Webhook 客户端。"""
|
|
44
|
+
|
|
45
|
+
def __init__(self, webhook_url: str, timeout: int = 10):
|
|
46
|
+
"""
|
|
47
|
+
:param webhook_url: 机器人 Webhook 完整地址(含 key)
|
|
48
|
+
:param timeout: 请求超时时间(秒)
|
|
49
|
+
"""
|
|
50
|
+
if not webhook_url:
|
|
51
|
+
raise ValueError("webhook_url 不能为空")
|
|
52
|
+
self.webhook_url = webhook_url
|
|
53
|
+
self.timeout = timeout
|
|
54
|
+
|
|
55
|
+
# ------------------------------------------------------------------
|
|
56
|
+
# 内部方法
|
|
57
|
+
# ------------------------------------------------------------------
|
|
58
|
+
def _post(self, payload: dict) -> dict:
|
|
59
|
+
"""发送 POST 请求并统一处理响应。"""
|
|
60
|
+
try:
|
|
61
|
+
resp = requests.post(
|
|
62
|
+
self.webhook_url,
|
|
63
|
+
data=json.dumps(payload, ensure_ascii=False).encode("utf-8"),
|
|
64
|
+
headers={"Content-Type": "application/json; charset=utf-8"},
|
|
65
|
+
timeout=self.timeout,
|
|
66
|
+
)
|
|
67
|
+
except requests.RequestException as exc:
|
|
68
|
+
raise WebhookBotError(f"网络请求失败: {exc}") from exc
|
|
69
|
+
|
|
70
|
+
try:
|
|
71
|
+
data = resp.json()
|
|
72
|
+
except ValueError:
|
|
73
|
+
raise WebhookBotError(
|
|
74
|
+
f"响应不是合法 JSON (HTTP {resp.status_code}): {resp.text[:200]}"
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
# 成功响应为 {"result": "ok"}
|
|
78
|
+
if data.get("result") != "ok":
|
|
79
|
+
raise WebhookBotError(f"发送失败: {data}")
|
|
80
|
+
return data
|
|
81
|
+
|
|
82
|
+
# ------------------------------------------------------------------
|
|
83
|
+
# 1. 文本消息
|
|
84
|
+
# ------------------------------------------------------------------
|
|
85
|
+
def send_text(
|
|
86
|
+
self,
|
|
87
|
+
content: str,
|
|
88
|
+
at_user_ids: Optional[Sequence[Union[str, int]]] = None,
|
|
89
|
+
at_emails: Optional[Sequence[str]] = None,
|
|
90
|
+
at_all: bool = False,
|
|
91
|
+
) -> dict:
|
|
92
|
+
"""
|
|
93
|
+
发送文本消息。
|
|
94
|
+
|
|
95
|
+
:param content: 文本内容(消息总长度不超过 5000 字符)
|
|
96
|
+
:param at_user_ids: 需要 @ 的用户 id 列表,如 ``["17856"]``
|
|
97
|
+
:param at_emails: 需要 @ 的用户邮箱列表,如 ``["somebody@wps.cn"]``
|
|
98
|
+
:param at_all: 是否 @ 所有人
|
|
99
|
+
"""
|
|
100
|
+
tags = "".join(f'<at user_id="{uid}"></at>' for uid in (at_user_ids or []))
|
|
101
|
+
tags += "".join(f'<at email="{mail}"></at>' for mail in (at_emails or []))
|
|
102
|
+
if at_all:
|
|
103
|
+
tags += '<at user_id="-1">所有人</at>'
|
|
104
|
+
return self._post({"msgtype": "text", "text": {"content": content + tags}})
|
|
105
|
+
|
|
106
|
+
# ------------------------------------------------------------------
|
|
107
|
+
# 2. Markdown 消息
|
|
108
|
+
# ------------------------------------------------------------------
|
|
109
|
+
def send_markdown(
|
|
110
|
+
self,
|
|
111
|
+
text: str,
|
|
112
|
+
at_user_ids: Optional[Sequence[Union[str, int]]] = None,
|
|
113
|
+
at_emails: Optional[Sequence[str]] = None,
|
|
114
|
+
at_all: bool = False,
|
|
115
|
+
) -> dict:
|
|
116
|
+
"""
|
|
117
|
+
发送 Markdown 消息。
|
|
118
|
+
|
|
119
|
+
支持的语法子集:标题(# ~ ######)、加粗(**)、斜体(* / _)、引用(>)、
|
|
120
|
+
链接([文字](url))、颜色(<font color='#FF0000'>文字</font>)、
|
|
121
|
+
@人(<at user_id="12345">姓名</at>)。换行可用“双空格+\\n”或“\\n\\n”。
|
|
122
|
+
|
|
123
|
+
:param text: Markdown 内容
|
|
124
|
+
:param at_user_ids: 需要 @ 的用户 id 列表
|
|
125
|
+
:param at_emails: 需要 @ 的用户邮箱列表
|
|
126
|
+
:param at_all: 是否 @ 所有人
|
|
127
|
+
"""
|
|
128
|
+
tags = "".join(f'<at user_id="{uid}"></at>' for uid in (at_user_ids or []))
|
|
129
|
+
tags += "".join(f'<at email="{mail}"></at>' for mail in (at_emails or []))
|
|
130
|
+
if at_all:
|
|
131
|
+
tags += '<at user_id="-1">所有人</at>'
|
|
132
|
+
return self._post({"msgtype": "markdown", "markdown": {"text": text + tags}})
|
|
133
|
+
|
|
134
|
+
# ------------------------------------------------------------------
|
|
135
|
+
# 3. 卡片消息
|
|
136
|
+
# ------------------------------------------------------------------
|
|
137
|
+
@staticmethod
|
|
138
|
+
def text_element(text: str, markdown: bool = True) -> dict:
|
|
139
|
+
"""构造卡片文本组件。markdown=True 时使用 markdown 渲染,否则纯文本。"""
|
|
140
|
+
return {
|
|
141
|
+
"tag": "text",
|
|
142
|
+
"content": {"type": "markdown" if markdown else "plainText", "text": text},
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
@staticmethod
|
|
146
|
+
def hr_element() -> dict:
|
|
147
|
+
"""构造卡片分割线组件。"""
|
|
148
|
+
return {"tag": "hr"}
|
|
149
|
+
|
|
150
|
+
def send_card(
|
|
151
|
+
self,
|
|
152
|
+
title: str,
|
|
153
|
+
subtitle: str = "",
|
|
154
|
+
elements: Optional[Sequence[dict]] = None,
|
|
155
|
+
link: str = "",
|
|
156
|
+
pc_url: str = "",
|
|
157
|
+
ios_url: str = "",
|
|
158
|
+
android_url: str = "",
|
|
159
|
+
header_template: str = "",
|
|
160
|
+
) -> dict:
|
|
161
|
+
"""
|
|
162
|
+
发送卡片消息。
|
|
163
|
+
|
|
164
|
+
:param title: 卡片主标题(必填)
|
|
165
|
+
:param subtitle: 卡片副标题
|
|
166
|
+
:param elements: 卡片组件列表,可用 :meth:`text_element` / :meth:`hr_element`
|
|
167
|
+
构造,组件总数不超过 20 个
|
|
168
|
+
:param link: 卡片整体点击跳转的默认链接
|
|
169
|
+
:param pc_url: PC 端跳转链接(不设置时使用 link,下同)
|
|
170
|
+
:param ios_url: iOS 端跳转链接
|
|
171
|
+
:param android_url: Android 端跳转链接
|
|
172
|
+
:param header_template: 卡片头部主题色,如 ``"red"`` 可让头部显示为红色。
|
|
173
|
+
该字段未出现在官方协议文档中(实测有效),可用值取决于
|
|
174
|
+
服务端支持情况,传入空字符串表示不设置(默认头部样式)。
|
|
175
|
+
"""
|
|
176
|
+
header: Dict[str, object] = {
|
|
177
|
+
"title": {
|
|
178
|
+
"tag": "text",
|
|
179
|
+
"content": {"type": "plainText", "text": title},
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
if header_template:
|
|
183
|
+
header["template"] = header_template
|
|
184
|
+
card: Dict[str, object] = {
|
|
185
|
+
"header": header,
|
|
186
|
+
"elements": list(elements) if elements else [],
|
|
187
|
+
}
|
|
188
|
+
if subtitle:
|
|
189
|
+
card["header"]["subtitle"] = {
|
|
190
|
+
"tag": "text",
|
|
191
|
+
"content": {"type": "plainText", "text": subtitle},
|
|
192
|
+
}
|
|
193
|
+
if link or pc_url or ios_url or android_url:
|
|
194
|
+
card["link"] = {
|
|
195
|
+
"url": link,
|
|
196
|
+
"pc_url": pc_url,
|
|
197
|
+
"ios_url": ios_url,
|
|
198
|
+
"android_url": android_url,
|
|
199
|
+
}
|
|
200
|
+
return self._post({"msgtype": "card", "card": card})
|
|
File without changes
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: wps-webhook-bot
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: WPS 协作(xz.wps.cn)群机器人 Webhook 通知 SDK,支持文本 / Markdown / 卡片三种消息格式
|
|
5
|
+
Author-email: wps-webhook-bot developers <wps-webhook-bot@example.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Documentation, http://open.wps.cn/documents/app-integration-dev/guide/robot/webhook
|
|
8
|
+
Keywords: wps,webhook,bot,robot,notification,协作机器人
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Topic :: Communications :: Chat
|
|
20
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
21
|
+
Requires-Python: >=3.8
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Requires-Dist: requests>=2.20
|
|
25
|
+
Dynamic: license-file
|
|
26
|
+
|
|
27
|
+
# wps-webhook-bot
|
|
28
|
+
|
|
29
|
+
WPS 协作(xz.wps.cn)群机器人 Webhook 通知 SDK,支持 **文本 / Markdown / 卡片** 三种消息格式。
|
|
30
|
+
|
|
31
|
+
协议参考:[WPS 开放平台 - webhook 机器人](http://open.wps.cn/documents/app-integration-dev/guide/robot/webhook)
|
|
32
|
+
|
|
33
|
+
## 安装
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
pip install wps-webhook-bot
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## 快速开始
|
|
40
|
+
|
|
41
|
+
在 WPS 协作群聊中添加自定义机器人,复制 Webhook 地址(形如 `https://xz.wps.cn/api/v1/webhook/send?key=xxxx`),然后:
|
|
42
|
+
|
|
43
|
+
```python
|
|
44
|
+
from wps_webhook_bot import WebhookBot
|
|
45
|
+
|
|
46
|
+
bot = WebhookBot("https://xz.wps.cn/api/v1/webhook/send?key=YOUR_KEY")
|
|
47
|
+
|
|
48
|
+
# 1. 文本消息(支持 @ 指定成员 / 所有人)
|
|
49
|
+
bot.send_text("部署完成", at_all=True)
|
|
50
|
+
bot.send_text("请查收报告", at_user_ids=["17856"], at_emails=["somebody@wps.cn"])
|
|
51
|
+
|
|
52
|
+
# 2. Markdown 消息(标题/加粗/引用/颜色/链接)
|
|
53
|
+
bot.send_markdown(
|
|
54
|
+
"### 构建通知\n"
|
|
55
|
+
"> 分支:main\n\n"
|
|
56
|
+
"状态:<font color='#07C160'>成功</font> "
|
|
57
|
+
"[查看详情](https://xz.wps.cn)"
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
# 3. 卡片消息(主/副标题 + 组件 + 整卡跳转)
|
|
61
|
+
bot.send_card(
|
|
62
|
+
title="nightly 构建 #123 完成",
|
|
63
|
+
subtitle="2026-08-26",
|
|
64
|
+
elements=[
|
|
65
|
+
WebhookBot.text_element("**通过率**:<font color='#07C160'>100%</font>"),
|
|
66
|
+
WebhookBot.hr_element(),
|
|
67
|
+
WebhookBot.text_element("耗时:3 分 25 秒", markdown=False),
|
|
68
|
+
],
|
|
69
|
+
link="https://xz.wps.cn",
|
|
70
|
+
)
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## API 一览
|
|
74
|
+
|
|
75
|
+
| 方法 | 说明 |
|
|
76
|
+
|---|---|
|
|
77
|
+
| `send_text(content, at_user_ids=None, at_emails=None, at_all=False)` | 文本消息,支持 `<at>` 标签 @ 人 |
|
|
78
|
+
| `send_markdown(text, at_user_ids=None, at_emails=None, at_all=False)` | Markdown 消息 |
|
|
79
|
+
| `send_card(title, subtitle="", elements=None, link="", pc_url="", ios_url="", android_url="")` | 卡片消息,支持分端跳转链接 |
|
|
80
|
+
| `WebhookBot.text_element(text, markdown=True)` | 构造卡片文本组件 |
|
|
81
|
+
| `WebhookBot.hr_element()` | 构造卡片分割线组件 |
|
|
82
|
+
|
|
83
|
+
发送失败会抛出 `WebhookBotError`,异常信息中包含服务端返回内容,便于排查。
|
|
84
|
+
|
|
85
|
+
## Markdown 语法子集
|
|
86
|
+
|
|
87
|
+
标题(`#` ~ `######`)、加粗(`**`)、斜体(`*` / `_`)、引用(`>`)、链接(`[文字](url)`)、
|
|
88
|
+
颜色(`<font color='#FF0000'>文字</font>`)、@人(`<at user_id="12345">姓名</at>`)。
|
|
89
|
+
换行使用「双空格 + `\n`」或「`\n\n`」。
|
|
90
|
+
|
|
91
|
+
## 平台限制
|
|
92
|
+
|
|
93
|
+
- 每个机器人发送频率不超过 **20 条/分钟**
|
|
94
|
+
- 每条消息不超过 **5000 个字符**
|
|
95
|
+
- 卡片组件总数不超过 20 个;Webhook 卡片暂不支持回传型交互组件(回传按钮、列表选择器、日期选择器、输入框)
|
|
96
|
+
|
|
97
|
+
## License
|
|
98
|
+
|
|
99
|
+
MIT
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
src/wps_webhook_bot/__init__.py
|
|
5
|
+
src/wps_webhook_bot/bot.py
|
|
6
|
+
src/wps_webhook_bot/py.typed
|
|
7
|
+
src/wps_webhook_bot.egg-info/PKG-INFO
|
|
8
|
+
src/wps_webhook_bot.egg-info/SOURCES.txt
|
|
9
|
+
src/wps_webhook_bot.egg-info/dependency_links.txt
|
|
10
|
+
src/wps_webhook_bot.egg-info/requires.txt
|
|
11
|
+
src/wps_webhook_bot.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
requests>=2.20
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
wps_webhook_bot
|