wechat-ilink-bot 0.1.0__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.
- wechat_ilink_bot-0.1.0/.gitignore +12 -0
- wechat_ilink_bot-0.1.0/.readthedocs.yaml +15 -0
- wechat_ilink_bot-0.1.0/CHANGELOG.md +47 -0
- wechat_ilink_bot-0.1.0/CONTRIBUTING.md +292 -0
- wechat_ilink_bot-0.1.0/LICENSE +21 -0
- wechat_ilink_bot-0.1.0/PKG-INFO +270 -0
- wechat_ilink_bot-0.1.0/README.md +214 -0
- wechat_ilink_bot-0.1.0/SECURITY.md +124 -0
- wechat_ilink_bot-0.1.0/docs/api/bot.md +12 -0
- wechat_ilink_bot-0.1.0/docs/api/context.md +14 -0
- wechat_ilink_bot-0.1.0/docs/api/webhook.md +9 -0
- wechat_ilink_bot-0.1.0/docs/examples.md +20 -0
- wechat_ilink_bot-0.1.0/docs/faq.md +38 -0
- wechat_ilink_bot-0.1.0/docs/getting-started.md +122 -0
- wechat_ilink_bot-0.1.0/docs/index.md +23 -0
- wechat_ilink_bot-0.1.0/docs/installation.md +34 -0
- wechat_ilink_bot-0.1.0/docs/message-delivery.md +71 -0
- wechat_ilink_bot-0.1.0/docs/requirements.txt +4 -0
- wechat_ilink_bot-0.1.0/docs/webhook.md +63 -0
- wechat_ilink_bot-0.1.0/examples/account_switch.py +36 -0
- wechat_ilink_bot-0.1.0/examples/command_bot.py +39 -0
- wechat_ilink_bot-0.1.0/examples/echo_bot.py +28 -0
- wechat_ilink_bot-0.1.0/examples/login_bot.py +28 -0
- wechat_ilink_bot-0.1.0/examples/media_bot.py +50 -0
- wechat_ilink_bot-0.1.0/examples/proactive_send.py +51 -0
- wechat_ilink_bot-0.1.0/examples/webhook_server.py +72 -0
- wechat_ilink_bot-0.1.0/mkdocs.yml +44 -0
- wechat_ilink_bot-0.1.0/pyproject.toml +103 -0
- wechat_ilink_bot-0.1.0/scripts/clear_build.sh +34 -0
- wechat_ilink_bot-0.1.0/src/wechat_bot/__init__.py +80 -0
- wechat_ilink_bot-0.1.0/src/wechat_bot/_logging.py +9 -0
- wechat_ilink_bot-0.1.0/src/wechat_bot/_version.py +5 -0
- wechat_ilink_bot-0.1.0/src/wechat_bot/auth.py +182 -0
- wechat_ilink_bot-0.1.0/src/wechat_bot/bot.py +554 -0
- wechat_ilink_bot-0.1.0/src/wechat_bot/cli.py +71 -0
- wechat_ilink_bot-0.1.0/src/wechat_bot/client.py +284 -0
- wechat_ilink_bot-0.1.0/src/wechat_bot/context.py +237 -0
- wechat_ilink_bot-0.1.0/src/wechat_bot/errors.py +36 -0
- wechat_ilink_bot-0.1.0/src/wechat_bot/handlers.py +184 -0
- wechat_ilink_bot-0.1.0/src/wechat_bot/media/__init__.py +22 -0
- wechat_ilink_bot-0.1.0/src/wechat_bot/media/crypto.py +61 -0
- wechat_ilink_bot-0.1.0/src/wechat_bot/media/download.py +160 -0
- wechat_ilink_bot-0.1.0/src/wechat_bot/media/upload.py +156 -0
- wechat_ilink_bot-0.1.0/src/wechat_bot/models.py +203 -0
- wechat_ilink_bot-0.1.0/src/wechat_bot/polling.py +212 -0
- wechat_ilink_bot-0.1.0/src/wechat_bot/py.typed +1 -0
- wechat_ilink_bot-0.1.0/src/wechat_bot/storage.py +262 -0
- wechat_ilink_bot-0.1.0/src/wechat_bot/types.py +74 -0
- wechat_ilink_bot-0.1.0/src/wechat_bot/webhook.py +208 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Placeholder for upcoming changes.
|
|
13
|
+
|
|
14
|
+
## [0.1.0] - 2026-03-28
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- Initial public release of `wechat-ilink-bot`.
|
|
19
|
+
- QR login flow with local credential persistence.
|
|
20
|
+
- Long-polling runtime with handler registration and first-match dispatch model.
|
|
21
|
+
- Proactive send APIs:
|
|
22
|
+
- `send_text`
|
|
23
|
+
- `send_image`
|
|
24
|
+
- `send_video`
|
|
25
|
+
- `send_file`
|
|
26
|
+
- Message-context reply APIs:
|
|
27
|
+
- `reply`
|
|
28
|
+
- `reply_image`
|
|
29
|
+
- `reply_video`
|
|
30
|
+
- `reply_file`
|
|
31
|
+
- `send_typing`
|
|
32
|
+
- Media upload and download helpers.
|
|
33
|
+
- Webhook server (`/healthz`, `/send`) with API key support.
|
|
34
|
+
- CLI command: `wechat-bot webhook`.
|
|
35
|
+
- Owner-default recipient behavior with explicit `to` override support.
|
|
36
|
+
- Account switching and local account listing support.
|
|
37
|
+
- Read the Docs documentation scaffold (`MkDocs + mkdocstrings`).
|
|
38
|
+
- CI/testing/lint/build packaging checks.
|
|
39
|
+
|
|
40
|
+
### Changed
|
|
41
|
+
|
|
42
|
+
- Unified package version source in `src/wechat_bot/_version.py`.
|
|
43
|
+
- Standardized webhook response format:
|
|
44
|
+
- success: `{"status": 200}`
|
|
45
|
+
- error: `{"status": <code>, "detail": "..."}`
|
|
46
|
+
- Improved recipient resolution and error clarity for missing owner state.
|
|
47
|
+
- Improved local storage safety with atomic JSON writes and strict file permissions when supported.
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
# Contributing Guide
|
|
2
|
+
|
|
3
|
+
Thanks for contributing to `wechat-ilink-bot`.
|
|
4
|
+
|
|
5
|
+
This project is a Python SDK for the WeChat iLink Bot API. Contributions are welcome across runtime code, examples, tests, packaging, and public documentation. Please keep changes small, well-scoped, and aligned with current runtime behavior.
|
|
6
|
+
|
|
7
|
+
## Development Environment
|
|
8
|
+
|
|
9
|
+
### Requirements
|
|
10
|
+
|
|
11
|
+
- Python 3.10+
|
|
12
|
+
- A local environment that can install editable dependencies
|
|
13
|
+
- Optional: a real WeChat/iLink account only if you want to manually verify login or message delivery flows
|
|
14
|
+
|
|
15
|
+
### Install development dependencies
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
python -m pip install -e .[dev]
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
This installs the core SDK plus the development toolchain used in this repository:
|
|
22
|
+
|
|
23
|
+
- `pytest` / `pytest-asyncio`
|
|
24
|
+
- `ruff`
|
|
25
|
+
- `mypy`
|
|
26
|
+
- `build`
|
|
27
|
+
- `twine`
|
|
28
|
+
- webhook-related optional packages already included in `dev`
|
|
29
|
+
|
|
30
|
+
### Optional extras for focused development
|
|
31
|
+
|
|
32
|
+
If you are validating a specific distribution scenario, you may also want to test these install paths explicitly:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
python -m pip install -e .[qrcode]
|
|
36
|
+
python -m pip install -e .[socks]
|
|
37
|
+
python -m pip install -e .[webhook]
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Repository Layout
|
|
41
|
+
|
|
42
|
+
```text
|
|
43
|
+
src/wechat_bot/ Core SDK implementation
|
|
44
|
+
examples/ Runnable usage examples
|
|
45
|
+
tests/ Automated test suite
|
|
46
|
+
plans/ Execution/research plans used during maintenance
|
|
47
|
+
dist/ Build artifacts
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Some important modules:
|
|
51
|
+
|
|
52
|
+
- `src/wechat_bot/bot.py` — high-level user-facing bot API
|
|
53
|
+
- `src/wechat_bot/client.py` — low-level async iLink API client
|
|
54
|
+
- `src/wechat_bot/polling.py` — long-poll loop, retry, backoff, session recovery
|
|
55
|
+
- `src/wechat_bot/storage.py` — local state directory, credentials, sync cursor, context tokens
|
|
56
|
+
- `src/wechat_bot/webhook.py` — FastAPI webhook server integration
|
|
57
|
+
- `src/wechat_bot/context.py` — handler context helpers for reply, typing, media download
|
|
58
|
+
|
|
59
|
+
## What to Keep in Sync
|
|
60
|
+
|
|
61
|
+
When behavior changes, do not update code in isolation. Keep the following layers aligned:
|
|
62
|
+
|
|
63
|
+
- Runtime implementation in `src/wechat_bot/`
|
|
64
|
+
- Examples in `examples/`
|
|
65
|
+
- Tests in `tests/`
|
|
66
|
+
- Public docs such as `README.md`, `SECURITY.md`, and changelog entries
|
|
67
|
+
|
|
68
|
+
As a rule of thumb:
|
|
69
|
+
|
|
70
|
+
- If you change user-visible behavior, update `README.md`
|
|
71
|
+
- If you change example usage, update the corresponding script under `examples/`
|
|
72
|
+
- If you change runtime behavior, add or update tests
|
|
73
|
+
- If you change release-facing behavior, update `CHANGELOG.md` under `Unreleased`
|
|
74
|
+
|
|
75
|
+
## Development Workflow
|
|
76
|
+
|
|
77
|
+
A typical contribution flow looks like this:
|
|
78
|
+
|
|
79
|
+
1. Install the dev environment
|
|
80
|
+
2. Make a focused change
|
|
81
|
+
3. Add or update tests
|
|
82
|
+
4. Update examples/docs if behavior changed
|
|
83
|
+
5. Run the verification commands below
|
|
84
|
+
6. Update `CHANGELOG.md` when appropriate
|
|
85
|
+
7. Open a small, reviewable pull request
|
|
86
|
+
|
|
87
|
+
## Verification Commands
|
|
88
|
+
|
|
89
|
+
Run these checks before opening a PR:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
python -m ruff check src tests examples
|
|
93
|
+
python -m pytest -q
|
|
94
|
+
python -m build
|
|
95
|
+
python -m twine check dist/*
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
If you are touching typing-sensitive areas, you may also run:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
python -m mypy src
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Verification Matrix
|
|
105
|
+
|
|
106
|
+
Use the following matrix to decide what to run and what files to inspect.
|
|
107
|
+
|
|
108
|
+
### 1. Lint and import hygiene
|
|
109
|
+
|
|
110
|
+
Command:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
python -m ruff check src tests examples
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Use this for:
|
|
117
|
+
|
|
118
|
+
- formatting-adjacent issues
|
|
119
|
+
- unused imports/variables
|
|
120
|
+
- obvious correctness and style regressions
|
|
121
|
+
|
|
122
|
+
### 2. Behavior validation
|
|
123
|
+
|
|
124
|
+
Command:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
python -m pytest -q
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Use this for any runtime behavior change.
|
|
131
|
+
|
|
132
|
+
Particularly relevant test files:
|
|
133
|
+
|
|
134
|
+
- `tests/test_bot.py` — account loading, recipient resolution, send behavior, runtime helpers
|
|
135
|
+
- `tests/test_polling.py` — session expiry and recovery flow
|
|
136
|
+
- `tests/test_storage.py` — state persistence, permissions, current user behavior
|
|
137
|
+
- `tests/test_webhook.py` — webhook routing, auth, response format, error behavior
|
|
138
|
+
- `tests/test_auth.py` — QR login flow smoke behavior
|
|
139
|
+
- `tests/test_examples_smoke.py` — examples importability and basic callable paths
|
|
140
|
+
|
|
141
|
+
### 3. Packaging validation
|
|
142
|
+
|
|
143
|
+
Commands:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
python -m build
|
|
147
|
+
python -m twine check dist/*
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Use these when you modify:
|
|
151
|
+
|
|
152
|
+
- `pyproject.toml`
|
|
153
|
+
- package metadata
|
|
154
|
+
- README content that affects package rendering
|
|
155
|
+
- distribution-facing extras or entry points
|
|
156
|
+
|
|
157
|
+
## Change-Type Guidance
|
|
158
|
+
|
|
159
|
+
### If you modify bot runtime behavior
|
|
160
|
+
|
|
161
|
+
Examples:
|
|
162
|
+
|
|
163
|
+
- account selection
|
|
164
|
+
- owner-default recipient logic
|
|
165
|
+
- handler dispatch
|
|
166
|
+
- send APIs
|
|
167
|
+
- session recovery behavior
|
|
168
|
+
|
|
169
|
+
Expected follow-up:
|
|
170
|
+
|
|
171
|
+
- update `tests/test_bot.py`
|
|
172
|
+
- update `tests/test_polling.py` if polling/session behavior changed
|
|
173
|
+
- update `README.md` if user-facing behavior changed
|
|
174
|
+
|
|
175
|
+
### If you modify storage or local credential behavior
|
|
176
|
+
|
|
177
|
+
Examples:
|
|
178
|
+
|
|
179
|
+
- state directory layout
|
|
180
|
+
- `current_user.json`
|
|
181
|
+
- `credentials.json`
|
|
182
|
+
- file permissions
|
|
183
|
+
- atomic write strategy
|
|
184
|
+
|
|
185
|
+
Expected follow-up:
|
|
186
|
+
|
|
187
|
+
- update `tests/test_storage.py`
|
|
188
|
+
- update `README.md` if local state behavior is user-visible
|
|
189
|
+
- update `SECURITY.md` if the security posture changed
|
|
190
|
+
|
|
191
|
+
### If you modify webhook or CLI behavior
|
|
192
|
+
|
|
193
|
+
Examples:
|
|
194
|
+
|
|
195
|
+
- request schema
|
|
196
|
+
- response shape
|
|
197
|
+
- API key behavior
|
|
198
|
+
- host/port/default flags
|
|
199
|
+
- GET/POST route behavior
|
|
200
|
+
|
|
201
|
+
Expected follow-up:
|
|
202
|
+
|
|
203
|
+
- update `tests/test_webhook.py`
|
|
204
|
+
- update `tests/test_cli.py` if CLI behavior changed
|
|
205
|
+
- update `README.md`
|
|
206
|
+
- update `SECURITY.md` if exposure or auth behavior changed
|
|
207
|
+
|
|
208
|
+
### If you modify examples
|
|
209
|
+
|
|
210
|
+
Expected follow-up:
|
|
211
|
+
|
|
212
|
+
- keep examples runnable and consistent with the current public API
|
|
213
|
+
- ensure `tests/test_examples_smoke.py` still reflects the intended import/call path
|
|
214
|
+
- update `README.md` example references if script purpose or invocation changed
|
|
215
|
+
|
|
216
|
+
## Code Style Expectations
|
|
217
|
+
|
|
218
|
+
- Prefer small, focused pull requests
|
|
219
|
+
- Keep public API changes backward-compatible when possible
|
|
220
|
+
- Favor clear names and explicit behavior over implicit magic
|
|
221
|
+
- Preserve current async-first design unless a change is clearly justified
|
|
222
|
+
- Handle errors carefully, especially around auth, polling, storage, and webhook responses
|
|
223
|
+
- Avoid leaking sensitive implementation details in externally exposed error surfaces
|
|
224
|
+
|
|
225
|
+
## Documentation Expectations
|
|
226
|
+
|
|
227
|
+
This repository treats documentation as part of the product surface.
|
|
228
|
+
|
|
229
|
+
Please update docs when you change:
|
|
230
|
+
|
|
231
|
+
- installation flow
|
|
232
|
+
- example commands
|
|
233
|
+
- webhook usage
|
|
234
|
+
- account selection behavior
|
|
235
|
+
- state directory behavior
|
|
236
|
+
- security-relevant behavior
|
|
237
|
+
|
|
238
|
+
When updating terms, keep wording consistent across:
|
|
239
|
+
|
|
240
|
+
- `README.md`
|
|
241
|
+
- `CONTRIBUTING.md`
|
|
242
|
+
- `SECURITY.md`
|
|
243
|
+
|
|
244
|
+
Important terms that should stay consistent include:
|
|
245
|
+
|
|
246
|
+
- `account_id`
|
|
247
|
+
- `user_id`
|
|
248
|
+
- `owner-default`
|
|
249
|
+
- `current_user.json`
|
|
250
|
+
- `context_token`
|
|
251
|
+
- `webhook key`
|
|
252
|
+
- `session expired`
|
|
253
|
+
|
|
254
|
+
## Changelog Policy
|
|
255
|
+
|
|
256
|
+
If your change affects users, add an entry under `## [Unreleased]` in `CHANGELOG.md`.
|
|
257
|
+
|
|
258
|
+
Typical cases:
|
|
259
|
+
|
|
260
|
+
- new features
|
|
261
|
+
- behavior changes
|
|
262
|
+
- breaking or compatibility-sensitive adjustments
|
|
263
|
+
- docs that materially affect onboarding or operational use
|
|
264
|
+
- security-related changes
|
|
265
|
+
|
|
266
|
+
Try to place changes under the existing categories such as `Added` or `Changed`.
|
|
267
|
+
|
|
268
|
+
## Pull Request Checklist
|
|
269
|
+
|
|
270
|
+
Before opening a PR, confirm the following:
|
|
271
|
+
|
|
272
|
+
- [ ] The change is focused and reviewable
|
|
273
|
+
- [ ] Lint passes locally
|
|
274
|
+
- [ ] Tests pass locally
|
|
275
|
+
- [ ] Examples were updated if usage changed
|
|
276
|
+
- [ ] Public docs were updated if behavior changed
|
|
277
|
+
- [ ] `CHANGELOG.md` was updated under `Unreleased` when appropriate
|
|
278
|
+
- [ ] No sensitive local state or credentials were added to the repository
|
|
279
|
+
|
|
280
|
+
## Reporting Bugs
|
|
281
|
+
|
|
282
|
+
If you are opening a bug report, please include:
|
|
283
|
+
|
|
284
|
+
- Python version
|
|
285
|
+
- OS/platform
|
|
286
|
+
- minimal reproducible code
|
|
287
|
+
- relevant logs or error output
|
|
288
|
+
- whether the issue affects login, polling, sending, webhook, storage, or packaging
|
|
289
|
+
|
|
290
|
+
Open regular bugs in the repository issue tracker.
|
|
291
|
+
|
|
292
|
+
For suspected security vulnerabilities, do **not** open a public issue. Follow the private disclosure guidance in `SECURITY.md`.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 wechat-bot contributors
|
|
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,270 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: wechat-ilink-bot
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python SDK for WeChat iLink Bot API — send and receive WeChat messages programmatically.
|
|
5
|
+
Project-URL: Homepage, https://github.com/hkslover/wechat-ilink-bot
|
|
6
|
+
Project-URL: Repository, https://github.com/hkslover/wechat-ilink-bot
|
|
7
|
+
Project-URL: Issues, https://github.com/hkslover/wechat-ilink-bot/issues
|
|
8
|
+
Project-URL: Documentation, https://wechat-ilink-bot.readthedocs.io/en/latest/
|
|
9
|
+
Project-URL: Changelog, https://github.com/hkslover/wechat-ilink-bot/blob/main/CHANGELOG.md
|
|
10
|
+
Author: hkslover
|
|
11
|
+
License-Expression: MIT
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Keywords: bot,ilink,sdk,wechat,weixin
|
|
14
|
+
Classifier: Development Status :: 3 - Alpha
|
|
15
|
+
Classifier: Framework :: AsyncIO
|
|
16
|
+
Classifier: Intended Audience :: Developers
|
|
17
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
23
|
+
Classifier: Topic :: Communications :: Chat
|
|
24
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
25
|
+
Classifier: Typing :: Typed
|
|
26
|
+
Requires-Python: >=3.10
|
|
27
|
+
Requires-Dist: cryptography>=42.0
|
|
28
|
+
Requires-Dist: httpx>=0.27
|
|
29
|
+
Requires-Dist: pydantic>=2.0
|
|
30
|
+
Provides-Extra: dev
|
|
31
|
+
Requires-Dist: build>=1.0; extra == 'dev'
|
|
32
|
+
Requires-Dist: fastapi>=0.111; extra == 'dev'
|
|
33
|
+
Requires-Dist: mkdocs-material>=9.5; extra == 'dev'
|
|
34
|
+
Requires-Dist: mkdocs>=1.6; extra == 'dev'
|
|
35
|
+
Requires-Dist: mkdocstrings[python]>=0.25; extra == 'dev'
|
|
36
|
+
Requires-Dist: mypy>=1.10; extra == 'dev'
|
|
37
|
+
Requires-Dist: pymdown-extensions>=10.8; extra == 'dev'
|
|
38
|
+
Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
|
|
39
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
40
|
+
Requires-Dist: ruff>=0.5; extra == 'dev'
|
|
41
|
+
Requires-Dist: twine>=6.0; extra == 'dev'
|
|
42
|
+
Requires-Dist: uvicorn>=0.30; extra == 'dev'
|
|
43
|
+
Provides-Extra: docs
|
|
44
|
+
Requires-Dist: mkdocs-material>=9.5; extra == 'docs'
|
|
45
|
+
Requires-Dist: mkdocs>=1.6; extra == 'docs'
|
|
46
|
+
Requires-Dist: mkdocstrings[python]>=0.25; extra == 'docs'
|
|
47
|
+
Requires-Dist: pymdown-extensions>=10.8; extra == 'docs'
|
|
48
|
+
Provides-Extra: qrcode
|
|
49
|
+
Requires-Dist: qrcode[pil]; extra == 'qrcode'
|
|
50
|
+
Provides-Extra: socks
|
|
51
|
+
Requires-Dist: httpx[socks]; extra == 'socks'
|
|
52
|
+
Provides-Extra: webhook
|
|
53
|
+
Requires-Dist: fastapi>=0.111; extra == 'webhook'
|
|
54
|
+
Requires-Dist: uvicorn>=0.30; extra == 'webhook'
|
|
55
|
+
Description-Content-Type: text/markdown
|
|
56
|
+
|
|
57
|
+
# wechat-ilink-bot
|
|
58
|
+
|
|
59
|
+
轻量、实用的 Python SDK,用于接入 WeChat iLink Bot API。
|
|
60
|
+
|
|
61
|
+
支持扫码登录、长轮询收消息、文本/图片/视频/文件发送,以及一键 webhook 发送。
|
|
62
|
+
|
|
63
|
+
## 核心能力
|
|
64
|
+
|
|
65
|
+
- 收消息:长轮询 + handler
|
|
66
|
+
- 主动发送文本:`send_text`
|
|
67
|
+
- 主动发送图片/视频/文件:`send_image` / `send_video` / `send_file`
|
|
68
|
+
- 会话内回复文本:`ctx.reply`
|
|
69
|
+
- 会话内回复图片/视频/文件:`ctx.reply_image` / `ctx.reply_video` / `ctx.reply_file`
|
|
70
|
+
- Webhook 触发发送(当前为文本)
|
|
71
|
+
|
|
72
|
+
<p>
|
|
73
|
+
<a href="https://wechat-ilink-bot.readthedocs.io/en/latest/" target="_blank">
|
|
74
|
+
<strong>Read the Docs: https://wechat-ilink-bot.readthedocs.io/en/latest/</strong>
|
|
75
|
+
</a>
|
|
76
|
+
</p>
|
|
77
|
+
|
|
78
|
+
## 安装
|
|
79
|
+
|
|
80
|
+
PyPI 安装:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
pip install wechat-ilink-bot
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
源码安装(开发/调试推荐):
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
git clone https://github.com/hkslover/wechat-ilink-bot.git
|
|
90
|
+
cd wechat-ilink-bot
|
|
91
|
+
pip install -e .
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
可选依赖:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
# 终端二维码打印
|
|
98
|
+
pip install "wechat-ilink-bot[qrcode]"
|
|
99
|
+
|
|
100
|
+
# webhook
|
|
101
|
+
pip install "wechat-ilink-bot[webhook]"
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## 快速开始
|
|
105
|
+
|
|
106
|
+
### 1) 扫码登录并持久化账号
|
|
107
|
+
|
|
108
|
+
```python
|
|
109
|
+
import asyncio
|
|
110
|
+
|
|
111
|
+
from wechat_bot import Bot
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
async def main() -> None:
|
|
115
|
+
bot = Bot(use_current_user=False)
|
|
116
|
+
result = await bot.login()
|
|
117
|
+
print(f"login ok: account_id={result.account_id}, user_id={result.user_id}")
|
|
118
|
+
await bot.stop()
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
if __name__ == "__main__":
|
|
122
|
+
asyncio.run(main())
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### 2) 最小 Echo Bot
|
|
126
|
+
|
|
127
|
+
```python
|
|
128
|
+
from wechat_bot import Bot, Filter
|
|
129
|
+
|
|
130
|
+
bot = Bot()
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
@bot.on_message(Filter.text())
|
|
134
|
+
async def echo(ctx):
|
|
135
|
+
await ctx.reply(f"Echo: {ctx.text}")
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
if __name__ == "__main__":
|
|
139
|
+
bot.run()
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### 3) 主动发送(owner-default 或显式目标)
|
|
143
|
+
|
|
144
|
+
```python
|
|
145
|
+
import asyncio
|
|
146
|
+
|
|
147
|
+
from wechat_bot import Bot
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
async def main() -> None:
|
|
151
|
+
bot = Bot()
|
|
152
|
+
|
|
153
|
+
# owner-default(不传 to)
|
|
154
|
+
await bot.send_text(text="Hello from wechat-ilink-bot!")
|
|
155
|
+
|
|
156
|
+
# 或者显式目标
|
|
157
|
+
# await bot.send_text(to="o9xxx@im.wechat", text="Hello")
|
|
158
|
+
|
|
159
|
+
await bot.stop()
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
if __name__ == "__main__":
|
|
163
|
+
asyncio.run(main())
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### 4) 主动发送富媒体(图片 / 视频 / 文件)
|
|
167
|
+
|
|
168
|
+
```python
|
|
169
|
+
import asyncio
|
|
170
|
+
|
|
171
|
+
from wechat_bot import Bot
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
async def main() -> None:
|
|
175
|
+
bot = Bot()
|
|
176
|
+
|
|
177
|
+
# owner-default(不传 to)
|
|
178
|
+
await bot.send_image(file_path="/path/to/image.png", caption="image")
|
|
179
|
+
await bot.send_video(file_path="/path/to/video.mp4", caption="video")
|
|
180
|
+
await bot.send_file(file_path="/path/to/file.pdf", caption="file")
|
|
181
|
+
|
|
182
|
+
# 显式目标(需要时)
|
|
183
|
+
# await bot.send_image(to="o9xxx@im.wechat", file_path="/path/to/image.png")
|
|
184
|
+
|
|
185
|
+
await bot.stop()
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
if __name__ == "__main__":
|
|
189
|
+
asyncio.run(main())
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### 5) 会话内回复富媒体(ctx.reply_*)
|
|
193
|
+
|
|
194
|
+
```python
|
|
195
|
+
from wechat_bot import Bot, Filter
|
|
196
|
+
|
|
197
|
+
bot = Bot()
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
@bot.on_message(Filter.text_startswith("/image"))
|
|
201
|
+
async def reply_image(ctx):
|
|
202
|
+
await ctx.reply_image("/path/to/image.png", caption="image")
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
@bot.on_message(Filter.text_startswith("/video"))
|
|
206
|
+
async def reply_video(ctx):
|
|
207
|
+
await ctx.reply_video("/path/to/video.mp4", caption="video")
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
@bot.on_message(Filter.text_startswith("/file"))
|
|
211
|
+
async def reply_file(ctx):
|
|
212
|
+
await ctx.reply_file("/path/to/file.pdf", caption="file")
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
if __name__ == "__main__":
|
|
216
|
+
bot.run()
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
## Webhook 快速使用
|
|
220
|
+
|
|
221
|
+
启动:
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
wechat-bot webhook --api-key your-secret
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
请求示例:
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
# GET
|
|
231
|
+
curl "http://127.0.0.1:8787/send?text=hello&key=your-secret"
|
|
232
|
+
|
|
233
|
+
# POST
|
|
234
|
+
curl -X POST "http://127.0.0.1:8787/send" \
|
|
235
|
+
-H "Content-Type: application/json" \
|
|
236
|
+
-H "X-Webhook-Key: your-secret" \
|
|
237
|
+
-d '{"text":"hello from webhook"}'
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
> Webhook `/send` 当前用于发送文本。
|
|
241
|
+
> 图片/视频/文件发送请使用 `Bot.send_image` / `Bot.send_video` / `Bot.send_file`。
|
|
242
|
+
|
|
243
|
+
## Examples
|
|
244
|
+
|
|
245
|
+
更多完整脚本请查看:
|
|
246
|
+
|
|
247
|
+
- [examples/login_bot.py](examples/login_bot.py)
|
|
248
|
+
- [examples/echo_bot.py](examples/echo_bot.py)
|
|
249
|
+
- [examples/command_bot.py](examples/command_bot.py)
|
|
250
|
+
- [examples/media_bot.py](examples/media_bot.py)
|
|
251
|
+
- [examples/proactive_send.py](examples/proactive_send.py)
|
|
252
|
+
- [examples/account_switch.py](examples/account_switch.py)
|
|
253
|
+
- [examples/webhook_server.py](examples/webhook_server.py)
|
|
254
|
+
|
|
255
|
+
## 本地文档预览
|
|
256
|
+
|
|
257
|
+
```bash
|
|
258
|
+
pip install -r docs/requirements.txt
|
|
259
|
+
mkdocs serve
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
## 参与贡献
|
|
263
|
+
|
|
264
|
+
- [Contributing Guide](CONTRIBUTING.md)
|
|
265
|
+
- [Security Policy](SECURITY.md)
|
|
266
|
+
- [Changelog](CHANGELOG.md)
|
|
267
|
+
|
|
268
|
+
## License
|
|
269
|
+
|
|
270
|
+
MIT
|