perk-pushplus-sdk 1.2.1__tar.gz → 1.2.2__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.
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/PKG-INFO +16 -2
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/README.md +15 -1
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/pyproject.toml +1 -1
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/__init__.py +13 -1
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/api/__init__.py +2 -0
- perk_pushplus_sdk-1.2.2/src/perk_pushplus/api/qqbot.py +89 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/client.py +2 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/enums.py +2 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/models/__init__.py +14 -0
- perk_pushplus_sdk-1.2.2/src/perk_pushplus/models/open_qqbot.py +107 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/models/open_user.py +1 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus_sdk.egg-info/PKG-INFO +16 -2
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus_sdk.egg-info/SOURCES.txt +2 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/tests/test_open_api.py +54 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/setup.cfg +0 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/access_key.py +0 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/api/access_key.py +0 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/api/base.py +0 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/api/channel.py +0 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/api/clawbot.py +0 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/api/doc.py +0 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/api/excel.py +0 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/api/form.py +0 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/api/friend.py +0 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/api/image.py +0 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/api/message.py +0 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/api/message_token.py +0 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/api/open_message.py +0 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/api/pre.py +0 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/api/setting.py +0 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/api/topic.py +0 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/api/topic_user.py +0 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/api/user.py +0 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/api/webhook.py +0 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/callback_parser.py +0 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/config.py +0 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/exceptions.py +0 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/http.py +0 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/models/base.py +0 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/models/callback.py +0 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/models/open_access.py +0 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/models/open_channel.py +0 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/models/open_clawbot.py +0 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/models/open_doc.py +0 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/models/open_form.py +0 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/models/open_friend.py +0 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/models/open_image.py +0 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/models/open_message.py +0 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/models/open_pre.py +0 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/models/open_setting.py +0 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/models/open_token.py +0 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/models/open_topic.py +0 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/models/open_webhook.py +0 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/models/send.py +0 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/multipart.py +0 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/py.typed +0 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/rate_limit.py +0 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus_sdk.egg-info/dependency_links.txt +0 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus_sdk.egg-info/requires.txt +0 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus_sdk.egg-info/top_level.txt +0 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/tests/test_enums_and_exceptions.py +0 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/tests/test_image_api.py +0 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/tests/test_message_api.py +0 -0
- {perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/tests/test_models.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: perk-pushplus-sdk
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.2
|
|
4
4
|
Summary: pushplus(推送加) 官方接口的 Python SDK,覆盖消息发送接口与全部开放接口。
|
|
5
5
|
Author: perk-net
|
|
6
6
|
License: Apache-2.0
|
|
@@ -35,7 +35,7 @@ Requires-Dist: responses>=0.23; extra == "dev"
|
|
|
35
35
|
[pushplus(推送加)](https://www.pushplus.plus) 官方接口的 Python SDK,覆盖 **消息接口** 与 **全部开放接口**。
|
|
36
36
|
|
|
37
37
|
- **消息接口**(`/send`、`/batchSend`):单渠道 + 多渠道发送,含 Builder API。
|
|
38
|
-
- **开放接口**(`/api/open/...` 与 `/push/api/open/...`):用户、消息、消息 token、群组、群组用户、好友、webhook、渠道、ClawBot
|
|
38
|
+
- **开放接口**(`/api/open/...` 与 `/push/api/open/...`):用户、消息、消息 token、群组、群组用户、好友、webhook、渠道、ClawBot、QQ 机器人、功能设置、预处理信息、图片服务、push 表单、push 文档、push 表格。
|
|
39
39
|
- **AccessKey 自动管理**:缓存 + 过期前自动刷新;`code=401` 自动刷新并重试一次。
|
|
40
40
|
- **本地限流守卫**:命中 `code=900` 后按 token 短路同 token 后续发送,避免被服务端长期封禁。
|
|
41
41
|
- **回调解析**:`message_complate`、`add_topic_user`、`add_friend` 三类回调统一解析。
|
|
@@ -168,6 +168,20 @@ topic_blacklist = client.topic_user.blacklist_list(TopicUserListQuery.of(1, 20,
|
|
|
168
168
|
# webhook 渠道
|
|
169
169
|
webhooks = client.webhook.list()
|
|
170
170
|
|
|
171
|
+
# QQ 机器人:绑定 -> 认领群 -> 建配置 -> 发到群
|
|
172
|
+
from perk_pushplus import QqBotSaveRequest
|
|
173
|
+
link = client.qq_bot.get_bind_link() # link.url 生成二维码,或私聊发送 link.bindCode
|
|
174
|
+
bind = client.qq_bot.bot_info() # bind.isBind == 1 表示已绑定
|
|
175
|
+
qq_groups = client.qq_bot.group_list()
|
|
176
|
+
client.qq_bot.add(QqBotSaveRequest(qqName="运维告警群", qqCode="ops-group", qqGroupId=qq_groups[0].id))
|
|
177
|
+
client.send(SendRequest(
|
|
178
|
+
title="服务告警",
|
|
179
|
+
content="订单服务响应超时",
|
|
180
|
+
channel=Channel.QQ,
|
|
181
|
+
option="ops-group", # 不传 option 则发给自己
|
|
182
|
+
template=Template.TXT,
|
|
183
|
+
))
|
|
184
|
+
|
|
171
185
|
# 设置
|
|
172
186
|
client.setting.change_is_send(1) # 启用发送
|
|
173
187
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
[pushplus(推送加)](https://www.pushplus.plus) 官方接口的 Python SDK,覆盖 **消息接口** 与 **全部开放接口**。
|
|
4
4
|
|
|
5
5
|
- **消息接口**(`/send`、`/batchSend`):单渠道 + 多渠道发送,含 Builder API。
|
|
6
|
-
- **开放接口**(`/api/open/...` 与 `/push/api/open/...`):用户、消息、消息 token、群组、群组用户、好友、webhook、渠道、ClawBot
|
|
6
|
+
- **开放接口**(`/api/open/...` 与 `/push/api/open/...`):用户、消息、消息 token、群组、群组用户、好友、webhook、渠道、ClawBot、QQ 机器人、功能设置、预处理信息、图片服务、push 表单、push 文档、push 表格。
|
|
7
7
|
- **AccessKey 自动管理**:缓存 + 过期前自动刷新;`code=401` 自动刷新并重试一次。
|
|
8
8
|
- **本地限流守卫**:命中 `code=900` 后按 token 短路同 token 后续发送,避免被服务端长期封禁。
|
|
9
9
|
- **回调解析**:`message_complate`、`add_topic_user`、`add_friend` 三类回调统一解析。
|
|
@@ -136,6 +136,20 @@ topic_blacklist = client.topic_user.blacklist_list(TopicUserListQuery.of(1, 20,
|
|
|
136
136
|
# webhook 渠道
|
|
137
137
|
webhooks = client.webhook.list()
|
|
138
138
|
|
|
139
|
+
# QQ 机器人:绑定 -> 认领群 -> 建配置 -> 发到群
|
|
140
|
+
from perk_pushplus import QqBotSaveRequest
|
|
141
|
+
link = client.qq_bot.get_bind_link() # link.url 生成二维码,或私聊发送 link.bindCode
|
|
142
|
+
bind = client.qq_bot.bot_info() # bind.isBind == 1 表示已绑定
|
|
143
|
+
qq_groups = client.qq_bot.group_list()
|
|
144
|
+
client.qq_bot.add(QqBotSaveRequest(qqName="运维告警群", qqCode="ops-group", qqGroupId=qq_groups[0].id))
|
|
145
|
+
client.send(SendRequest(
|
|
146
|
+
title="服务告警",
|
|
147
|
+
content="订单服务响应超时",
|
|
148
|
+
channel=Channel.QQ,
|
|
149
|
+
option="ops-group", # 不传 option 则发给自己
|
|
150
|
+
template=Template.TXT,
|
|
151
|
+
))
|
|
152
|
+
|
|
139
153
|
# 设置
|
|
140
154
|
client.setting.change_is_send(1) # 启用发送
|
|
141
155
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "perk-pushplus-sdk"
|
|
7
|
-
version = "1.2.
|
|
7
|
+
version = "1.2.2"
|
|
8
8
|
description = "pushplus(推送加) 官方接口的 Python SDK,覆盖消息发送接口与全部开放接口。"
|
|
9
9
|
readme = { file = "README.md", content-type = "text/markdown" }
|
|
10
10
|
requires-python = ">=3.8"
|
|
@@ -84,6 +84,12 @@ from .models import (
|
|
|
84
84
|
PreItem,
|
|
85
85
|
PreSaveRequest,
|
|
86
86
|
PreTestRequest,
|
|
87
|
+
QqBotBindInfo,
|
|
88
|
+
QqBotBindLink,
|
|
89
|
+
QqBotInfo,
|
|
90
|
+
QqBotItem,
|
|
91
|
+
QqBotSaveRequest,
|
|
92
|
+
QqGroupItem,
|
|
87
93
|
SendCount,
|
|
88
94
|
SendMessageResult,
|
|
89
95
|
SendRequest,
|
|
@@ -108,7 +114,7 @@ from .models import (
|
|
|
108
114
|
)
|
|
109
115
|
from .rate_limit import RateLimitGuard
|
|
110
116
|
|
|
111
|
-
__version__ = "1.2.
|
|
117
|
+
__version__ = "1.2.2"
|
|
112
118
|
|
|
113
119
|
__all__ = [
|
|
114
120
|
"__version__",
|
|
@@ -175,6 +181,12 @@ __all__ = [
|
|
|
175
181
|
"ClawBotQrCode",
|
|
176
182
|
"ClawBotInfo",
|
|
177
183
|
"ClawBotMessage",
|
|
184
|
+
"QqBotBindLink",
|
|
185
|
+
"QqBotInfo",
|
|
186
|
+
"QqBotBindInfo",
|
|
187
|
+
"QqGroupItem",
|
|
188
|
+
"QqBotItem",
|
|
189
|
+
"QqBotSaveRequest",
|
|
178
190
|
"UserDefaultItem",
|
|
179
191
|
"UserDefaultDetail",
|
|
180
192
|
"UserDefaultSaveRequest",
|
|
@@ -12,6 +12,7 @@ from .message import MessageApi
|
|
|
12
12
|
from .message_token import MessageTokenApi
|
|
13
13
|
from .open_message import OpenMessageApi
|
|
14
14
|
from .pre import PreApi
|
|
15
|
+
from .qqbot import QqBotApi
|
|
15
16
|
from .setting import SettingApi
|
|
16
17
|
from .topic import TopicApi
|
|
17
18
|
from .topic_user import TopicUserApi
|
|
@@ -32,6 +33,7 @@ __all__ = [
|
|
|
32
33
|
"WebhookApi",
|
|
33
34
|
"ChannelApi",
|
|
34
35
|
"ClawBotApi",
|
|
36
|
+
"QqBotApi",
|
|
35
37
|
"SettingApi",
|
|
36
38
|
"PreApi",
|
|
37
39
|
"ImageApi",
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"""开放接口 - QQ 机器人(文档「九. QQ机器人接口」)。"""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from dataclasses import replace
|
|
5
|
+
from typing import List, Optional
|
|
6
|
+
|
|
7
|
+
from ..models import (
|
|
8
|
+
PageQuery,
|
|
9
|
+
PageResult,
|
|
10
|
+
QqBotBindInfo,
|
|
11
|
+
QqBotBindLink,
|
|
12
|
+
QqBotItem,
|
|
13
|
+
QqBotSaveRequest,
|
|
14
|
+
QqGroupItem,
|
|
15
|
+
)
|
|
16
|
+
from .base import OpenAbstractApi
|
|
17
|
+
|
|
18
|
+
SEND_TYPE_QQ_GROUP = 2
|
|
19
|
+
"""发送到 QQ 群,目前渠道配置仅支持该类型。"""
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class QqBotApi(OpenAbstractApi):
|
|
23
|
+
"""QQ 机器人绑定与渠道配置相关接口。"""
|
|
24
|
+
|
|
25
|
+
def get_bind_link(self, refresh: bool = False) -> QqBotBindLink:
|
|
26
|
+
"""获取绑定链接与绑定码;``refresh=True`` 时旧绑定码失效并重新生成。"""
|
|
27
|
+
|
|
28
|
+
path = "/api/open/qqBot/getBindLink"
|
|
29
|
+
if refresh:
|
|
30
|
+
path = self.append_query(path, {"refresh": "true"})
|
|
31
|
+
return self.execute_open("GET", path, None, QqBotBindLink)
|
|
32
|
+
|
|
33
|
+
def bot_info(self) -> QqBotBindInfo:
|
|
34
|
+
"""查询绑定状态。"""
|
|
35
|
+
|
|
36
|
+
return self.execute_open(
|
|
37
|
+
"GET", "/api/open/qqBot/botInfo", None, QqBotBindInfo
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
def unbind(self) -> None:
|
|
41
|
+
"""解绑 QQ 机器人。"""
|
|
42
|
+
|
|
43
|
+
self.execute_open("GET", "/api/open/qqBot/unbind", None, None)
|
|
44
|
+
|
|
45
|
+
def group_list(self) -> List[QqGroupItem]:
|
|
46
|
+
"""获取机器人已加入的 QQ 群列表。"""
|
|
47
|
+
|
|
48
|
+
result = self.execute_open(
|
|
49
|
+
"GET", "/api/open/qqBot/groupList", None, List[QqGroupItem]
|
|
50
|
+
)
|
|
51
|
+
return result or []
|
|
52
|
+
|
|
53
|
+
def list(self, query: Optional[PageQuery] = None) -> PageResult[QqBotItem]:
|
|
54
|
+
"""获取 QQ 机器人渠道配置列表。"""
|
|
55
|
+
|
|
56
|
+
body = query if query is not None else PageQuery()
|
|
57
|
+
result = self.execute_open(
|
|
58
|
+
"POST", "/api/open/qqBot/list", body, PageResult[QqBotItem]
|
|
59
|
+
)
|
|
60
|
+
return result or PageResult(list=[])
|
|
61
|
+
|
|
62
|
+
def add(self, request: QqBotSaveRequest) -> None:
|
|
63
|
+
"""新增渠道配置,用于把消息发送到指定 QQ 群;发给自己无需创建配置。"""
|
|
64
|
+
|
|
65
|
+
self.execute_open(
|
|
66
|
+
"POST", "/api/open/qqBot/add", _with_default_send_type(request), None
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
def edit(self, request: QqBotSaveRequest) -> None:
|
|
70
|
+
"""修改渠道配置;配置编码不可修改。"""
|
|
71
|
+
|
|
72
|
+
self.execute_open(
|
|
73
|
+
"POST", "/api/open/qqBot/edit", _with_default_send_type(request), None
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
def delete(self, config_id: int) -> None:
|
|
77
|
+
"""删除渠道配置。"""
|
|
78
|
+
|
|
79
|
+
path = self.append_query("/api/open/qqBot/delete", {"id": int(config_id)})
|
|
80
|
+
self.execute_open("DELETE", path, None, None)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def _with_default_send_type(request: QqBotSaveRequest) -> QqBotSaveRequest:
|
|
84
|
+
if request is None or request.sendType is not None:
|
|
85
|
+
return request
|
|
86
|
+
return replace(request, sendType=SEND_TYPE_QQ_GROUP)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
__all__ = ["QqBotApi", "SEND_TYPE_QQ_GROUP"]
|
|
@@ -15,6 +15,7 @@ from .api import (
|
|
|
15
15
|
MessageTokenApi,
|
|
16
16
|
OpenMessageApi,
|
|
17
17
|
PreApi,
|
|
18
|
+
QqBotApi,
|
|
18
19
|
SettingApi,
|
|
19
20
|
TopicApi,
|
|
20
21
|
TopicUserApi,
|
|
@@ -76,6 +77,7 @@ class PushPlusClient:
|
|
|
76
77
|
self.webhook = WebhookApi(config, self.http_requester, self.access_key_manager)
|
|
77
78
|
self.channel = ChannelApi(config, self.http_requester, self.access_key_manager)
|
|
78
79
|
self.claw_bot = ClawBotApi(config, self.http_requester, self.access_key_manager)
|
|
80
|
+
self.qq_bot = QqBotApi(config, self.http_requester, self.access_key_manager)
|
|
79
81
|
self.setting = SettingApi(config, self.http_requester, self.access_key_manager)
|
|
80
82
|
self.pre = PreApi(config, self.http_requester, self.access_key_manager)
|
|
81
83
|
self.image = ImageApi(config, self.http_requester, self.access_key_manager)
|
|
@@ -36,6 +36,14 @@ from .open_friend import FriendBlacklistItem, FriendItem, FriendQrCode
|
|
|
36
36
|
from .open_webhook import WebhookItem, WebhookSaveRequest
|
|
37
37
|
from .open_channel import CpItem, MailDetail, MailItem, MpItem
|
|
38
38
|
from .open_clawbot import ClawBotInfo, ClawBotMessage, ClawBotQrCode
|
|
39
|
+
from .open_qqbot import (
|
|
40
|
+
QqBotBindInfo,
|
|
41
|
+
QqBotBindLink,
|
|
42
|
+
QqBotInfo,
|
|
43
|
+
QqBotItem,
|
|
44
|
+
QqBotSaveRequest,
|
|
45
|
+
QqGroupItem,
|
|
46
|
+
)
|
|
39
47
|
from .open_setting import UserDefaultDetail, UserDefaultItem, UserDefaultSaveRequest
|
|
40
48
|
from .open_pre import PreDetail, PreItem, PreSaveRequest, PreTestRequest
|
|
41
49
|
from .open_image import ImageItem, ImageUploadResult, ImageUploadToken
|
|
@@ -97,6 +105,12 @@ __all__ = [
|
|
|
97
105
|
"ClawBotQrCode",
|
|
98
106
|
"ClawBotInfo",
|
|
99
107
|
"ClawBotMessage",
|
|
108
|
+
"QqBotBindLink",
|
|
109
|
+
"QqBotInfo",
|
|
110
|
+
"QqBotBindInfo",
|
|
111
|
+
"QqGroupItem",
|
|
112
|
+
"QqBotItem",
|
|
113
|
+
"QqBotSaveRequest",
|
|
100
114
|
"UserDefaultItem",
|
|
101
115
|
"UserDefaultDetail",
|
|
102
116
|
"UserDefaultSaveRequest",
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"""开放接口 - QQ 机器人模型。"""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
from typing import List, Optional
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@dataclass
|
|
9
|
+
class QqBotBindLink:
|
|
10
|
+
"""QQ 机器人绑定链接与绑定码。"""
|
|
11
|
+
|
|
12
|
+
url: Optional[str] = None
|
|
13
|
+
"""带参分享链接,用于生成扫码二维码;已绑定用户再次获取时可能为空。"""
|
|
14
|
+
bindCode: Optional[str] = None
|
|
15
|
+
"""绑定码。已是好友时扫码收不到加好友事件,需私聊发送该码;认领 QQ 群也用此码。"""
|
|
16
|
+
expireSeconds: Optional[int] = None
|
|
17
|
+
"""有效期秒数,默认 300。"""
|
|
18
|
+
botAppId: Optional[str] = None
|
|
19
|
+
"""为当前用户分配的官方机器人 appId。"""
|
|
20
|
+
botName: Optional[str] = None
|
|
21
|
+
botAvatar: Optional[str] = None
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@dataclass
|
|
25
|
+
class QqBotInfo:
|
|
26
|
+
"""QQ 机器人详情。"""
|
|
27
|
+
|
|
28
|
+
botId: Optional[str] = None
|
|
29
|
+
username: Optional[str] = None
|
|
30
|
+
avatar: Optional[str] = None
|
|
31
|
+
appId: Optional[str] = None
|
|
32
|
+
shareUrl: Optional[str] = None
|
|
33
|
+
"""官方分享链接,可用于拉机器人进群。"""
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@dataclass
|
|
37
|
+
class QqBotBindInfo:
|
|
38
|
+
"""QQ 机器人绑定状态。"""
|
|
39
|
+
|
|
40
|
+
isBind: Optional[int] = None
|
|
41
|
+
"""0-未绑定,1-已绑定。"""
|
|
42
|
+
receiveStatus: Optional[int] = None
|
|
43
|
+
"""1-可接收,0-用户已关闭单聊接收。"""
|
|
44
|
+
createTime: Optional[str] = None
|
|
45
|
+
botInfo: Optional[QqBotInfo] = None
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@dataclass
|
|
49
|
+
class QqGroupItem:
|
|
50
|
+
"""机器人已加入的 QQ 群。"""
|
|
51
|
+
|
|
52
|
+
id: Optional[int] = None
|
|
53
|
+
"""群编号;新增渠道配置时作为 ``qqGroupId`` 使用。"""
|
|
54
|
+
groupOpenId: Optional[str] = None
|
|
55
|
+
groupRemark: Optional[str] = None
|
|
56
|
+
status: Optional[int] = None
|
|
57
|
+
"""1-在群,2-群消息接收关闭。"""
|
|
58
|
+
groupName: Optional[str] = None
|
|
59
|
+
"""群名称,接口未授权时为空。"""
|
|
60
|
+
groupFingerMemo: Optional[str] = None
|
|
61
|
+
groupClassText: Optional[str] = None
|
|
62
|
+
groupTags: Optional[List[str]] = None
|
|
63
|
+
groupMemberNum: Optional[int] = None
|
|
64
|
+
createTime: Optional[str] = None
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
@dataclass
|
|
68
|
+
class QqBotItem:
|
|
69
|
+
"""QQ 机器人渠道配置列表项。"""
|
|
70
|
+
|
|
71
|
+
id: Optional[int] = None
|
|
72
|
+
qqName: Optional[str] = None
|
|
73
|
+
qqCode: Optional[str] = None
|
|
74
|
+
"""配置编码;发送消息时作为 ``option`` 传入。"""
|
|
75
|
+
sendType: Optional[int] = None
|
|
76
|
+
"""2-发到 QQ 群。"""
|
|
77
|
+
qqGroupId: Optional[int] = None
|
|
78
|
+
groupRemark: Optional[str] = None
|
|
79
|
+
groupOpenId: Optional[str] = None
|
|
80
|
+
groupName: Optional[str] = None
|
|
81
|
+
updateTime: Optional[str] = None
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
@dataclass
|
|
85
|
+
class QqBotSaveRequest:
|
|
86
|
+
"""新增/修改 QQ 机器人渠道配置请求。"""
|
|
87
|
+
|
|
88
|
+
id: Optional[int] = None
|
|
89
|
+
"""修改时必填。"""
|
|
90
|
+
qqName: Optional[str] = None
|
|
91
|
+
"""配置名称,必填,最多 64 个字符。"""
|
|
92
|
+
qqCode: Optional[str] = None
|
|
93
|
+
"""配置编码,新增必填;仅支持字母、数字、下划线和中划线,创建后不可修改。"""
|
|
94
|
+
sendType: Optional[int] = None
|
|
95
|
+
"""发送类型;留空时 SDK 自动填 2(发到 QQ 群)。"""
|
|
96
|
+
qqGroupId: Optional[int] = None
|
|
97
|
+
"""QQ 群编号,必填,取自 ``group_list`` 返回的 ``id``。"""
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
__all__ = [
|
|
101
|
+
"QqBotBindLink",
|
|
102
|
+
"QqBotInfo",
|
|
103
|
+
"QqBotBindInfo",
|
|
104
|
+
"QqGroupItem",
|
|
105
|
+
"QqBotItem",
|
|
106
|
+
"QqBotSaveRequest",
|
|
107
|
+
]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: perk-pushplus-sdk
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.2
|
|
4
4
|
Summary: pushplus(推送加) 官方接口的 Python SDK,覆盖消息发送接口与全部开放接口。
|
|
5
5
|
Author: perk-net
|
|
6
6
|
License: Apache-2.0
|
|
@@ -35,7 +35,7 @@ Requires-Dist: responses>=0.23; extra == "dev"
|
|
|
35
35
|
[pushplus(推送加)](https://www.pushplus.plus) 官方接口的 Python SDK,覆盖 **消息接口** 与 **全部开放接口**。
|
|
36
36
|
|
|
37
37
|
- **消息接口**(`/send`、`/batchSend`):单渠道 + 多渠道发送,含 Builder API。
|
|
38
|
-
- **开放接口**(`/api/open/...` 与 `/push/api/open/...`):用户、消息、消息 token、群组、群组用户、好友、webhook、渠道、ClawBot
|
|
38
|
+
- **开放接口**(`/api/open/...` 与 `/push/api/open/...`):用户、消息、消息 token、群组、群组用户、好友、webhook、渠道、ClawBot、QQ 机器人、功能设置、预处理信息、图片服务、push 表单、push 文档、push 表格。
|
|
39
39
|
- **AccessKey 自动管理**:缓存 + 过期前自动刷新;`code=401` 自动刷新并重试一次。
|
|
40
40
|
- **本地限流守卫**:命中 `code=900` 后按 token 短路同 token 后续发送,避免被服务端长期封禁。
|
|
41
41
|
- **回调解析**:`message_complate`、`add_topic_user`、`add_friend` 三类回调统一解析。
|
|
@@ -168,6 +168,20 @@ topic_blacklist = client.topic_user.blacklist_list(TopicUserListQuery.of(1, 20,
|
|
|
168
168
|
# webhook 渠道
|
|
169
169
|
webhooks = client.webhook.list()
|
|
170
170
|
|
|
171
|
+
# QQ 机器人:绑定 -> 认领群 -> 建配置 -> 发到群
|
|
172
|
+
from perk_pushplus import QqBotSaveRequest
|
|
173
|
+
link = client.qq_bot.get_bind_link() # link.url 生成二维码,或私聊发送 link.bindCode
|
|
174
|
+
bind = client.qq_bot.bot_info() # bind.isBind == 1 表示已绑定
|
|
175
|
+
qq_groups = client.qq_bot.group_list()
|
|
176
|
+
client.qq_bot.add(QqBotSaveRequest(qqName="运维告警群", qqCode="ops-group", qqGroupId=qq_groups[0].id))
|
|
177
|
+
client.send(SendRequest(
|
|
178
|
+
title="服务告警",
|
|
179
|
+
content="订单服务响应超时",
|
|
180
|
+
channel=Channel.QQ,
|
|
181
|
+
option="ops-group", # 不传 option 则发给自己
|
|
182
|
+
template=Template.TXT,
|
|
183
|
+
))
|
|
184
|
+
|
|
171
185
|
# 设置
|
|
172
186
|
client.setting.change_is_send(1) # 启用发送
|
|
173
187
|
|
{perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus_sdk.egg-info/SOURCES.txt
RENAMED
|
@@ -25,6 +25,7 @@ src/perk_pushplus/api/message.py
|
|
|
25
25
|
src/perk_pushplus/api/message_token.py
|
|
26
26
|
src/perk_pushplus/api/open_message.py
|
|
27
27
|
src/perk_pushplus/api/pre.py
|
|
28
|
+
src/perk_pushplus/api/qqbot.py
|
|
28
29
|
src/perk_pushplus/api/setting.py
|
|
29
30
|
src/perk_pushplus/api/topic.py
|
|
30
31
|
src/perk_pushplus/api/topic_user.py
|
|
@@ -42,6 +43,7 @@ src/perk_pushplus/models/open_friend.py
|
|
|
42
43
|
src/perk_pushplus/models/open_image.py
|
|
43
44
|
src/perk_pushplus/models/open_message.py
|
|
44
45
|
src/perk_pushplus/models/open_pre.py
|
|
46
|
+
src/perk_pushplus/models/open_qqbot.py
|
|
45
47
|
src/perk_pushplus/models/open_setting.py
|
|
46
48
|
src/perk_pushplus/models/open_token.py
|
|
47
49
|
src/perk_pushplus/models/open_topic.py
|
|
@@ -292,3 +292,57 @@ def test_excel_import():
|
|
|
292
292
|
|
|
293
293
|
imported = client.excel.import_excel(b"xlsx", "销售日报.xlsx")
|
|
294
294
|
assert imported.docCode == "Sh3xY7kP"
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
def test_qq_bot_bind_and_group_config():
|
|
298
|
+
req = ScriptedRequester()
|
|
299
|
+
req.push(
|
|
300
|
+
"/api/open/qqBot/getBindLink",
|
|
301
|
+
200,
|
|
302
|
+
_ok({"url": "https://qun.qq.com/qunpro/robot/share?robot_appid=1", "bindCode": "A1B2C3", "expireSeconds": 300}),
|
|
303
|
+
)
|
|
304
|
+
req.push(
|
|
305
|
+
"/api/open/qqBot/botInfo",
|
|
306
|
+
200,
|
|
307
|
+
_ok({"isBind": 1, "receiveStatus": 1, "botInfo": {"appId": "1", "username": "pushplus"}}),
|
|
308
|
+
)
|
|
309
|
+
req.push(
|
|
310
|
+
"/api/open/qqBot/groupList",
|
|
311
|
+
200,
|
|
312
|
+
_ok([{"id": 9, "groupOpenId": "OPEN-1", "status": 1, "groupName": "运维告警群", "groupTags": ["运维"]}]),
|
|
313
|
+
)
|
|
314
|
+
req.push("/api/open/qqBot/add", 200, _ok(None))
|
|
315
|
+
req.push(
|
|
316
|
+
"/api/open/qqBot/list",
|
|
317
|
+
200,
|
|
318
|
+
_ok({"pageNum": 1, "pageSize": 20, "total": 1, "pages": 1, "list": [{"id": 3, "qqCode": "ops-group", "sendType": 2, "qqGroupId": 9}]}),
|
|
319
|
+
)
|
|
320
|
+
req.push("/api/open/qqBot/delete", 200, _ok(None))
|
|
321
|
+
client = _build_client(req)
|
|
322
|
+
|
|
323
|
+
from perk_pushplus import QqBotSaveRequest
|
|
324
|
+
|
|
325
|
+
link = client.qq_bot.get_bind_link(refresh=True)
|
|
326
|
+
assert link.bindCode == "A1B2C3"
|
|
327
|
+
assert "refresh=true" in next(c for c in req.calls if "getBindLink" in c[1])[1]
|
|
328
|
+
|
|
329
|
+
bind = client.qq_bot.bot_info()
|
|
330
|
+
assert bind.isBind == 1
|
|
331
|
+
assert bind.botInfo is not None and bind.botInfo.username == "pushplus"
|
|
332
|
+
|
|
333
|
+
groups = client.qq_bot.group_list()
|
|
334
|
+
assert groups[0].id == 9
|
|
335
|
+
assert groups[0].groupTags == ["运维"]
|
|
336
|
+
|
|
337
|
+
client.qq_bot.add(QqBotSaveRequest(qqName="运维告警群", qqCode="ops-group", qqGroupId=9))
|
|
338
|
+
add_call = next(c for c in req.calls if "/api/open/qqBot/add" in c[1])
|
|
339
|
+
assert add_call[2]["access-key"] == "ak-1"
|
|
340
|
+
assert json.loads(add_call[3])["sendType"] == 2
|
|
341
|
+
|
|
342
|
+
page = client.qq_bot.list()
|
|
343
|
+
assert page.list[0].qqCode == "ops-group"
|
|
344
|
+
|
|
345
|
+
client.qq_bot.delete(3)
|
|
346
|
+
delete_call = next(c for c in req.calls if "/api/open/qqBot/delete" in c[1])
|
|
347
|
+
assert delete_call[0] == "DELETE"
|
|
348
|
+
assert "id=3" in delete_call[1]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/models/open_channel.py
RENAMED
|
File without changes
|
{perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/models/open_clawbot.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/models/open_message.py
RENAMED
|
File without changes
|
|
File without changes
|
{perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/models/open_setting.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus/models/open_webhook.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus_sdk.egg-info/requires.txt
RENAMED
|
File without changes
|
{perk_pushplus_sdk-1.2.1 → perk_pushplus_sdk-1.2.2}/src/perk_pushplus_sdk.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|