imbot-sdk-python 0.1.0__tar.gz → 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.
Files changed (44) hide show
  1. {imbot_sdk_python-0.1.0 → imbot_sdk_python-0.1.1}/CHANGELOG.md +8 -0
  2. {imbot_sdk_python-0.1.0 → imbot_sdk_python-0.1.1}/MANIFEST.in +1 -0
  3. imbot_sdk_python-0.1.1/PKG-INFO +335 -0
  4. imbot_sdk_python-0.1.1/README.md +301 -0
  5. imbot_sdk_python-0.1.0/README.md → imbot_sdk_python-0.1.1/README.zh-CN.md +3 -1
  6. imbot_sdk_python-0.1.1/docs/API.md +170 -0
  7. imbot_sdk_python-0.1.0/docs/API.md → imbot_sdk_python-0.1.1/docs/API.zh-CN.md +2 -0
  8. imbot_sdk_python-0.1.1/docs/PROTOCOL.md +95 -0
  9. imbot_sdk_python-0.1.0/docs/PROTOCOL.md → imbot_sdk_python-0.1.1/docs/PROTOCOL.zh-CN.md +2 -0
  10. {imbot_sdk_python-0.1.0 → imbot_sdk_python-0.1.1}/imbot_sdk/__init__.py +1 -1
  11. imbot_sdk_python-0.1.1/imbot_sdk_python.egg-info/PKG-INFO +335 -0
  12. {imbot_sdk_python-0.1.0 → imbot_sdk_python-0.1.1}/imbot_sdk_python.egg-info/SOURCES.txt +3 -0
  13. {imbot_sdk_python-0.1.0 → imbot_sdk_python-0.1.1}/pyproject.toml +1 -1
  14. imbot_sdk_python-0.1.0/PKG-INFO +0 -296
  15. imbot_sdk_python-0.1.0/imbot_sdk_python.egg-info/PKG-INFO +0 -296
  16. {imbot_sdk_python-0.1.0 → imbot_sdk_python-0.1.1}/LICENSE +0 -0
  17. {imbot_sdk_python-0.1.0 → imbot_sdk_python-0.1.1}/examples/.env.example +0 -0
  18. {imbot_sdk_python-0.1.0 → imbot_sdk_python-0.1.1}/examples/echo_bot.py +0 -0
  19. {imbot_sdk_python-0.1.0 → imbot_sdk_python-0.1.1}/examples/quickstart.py +0 -0
  20. {imbot_sdk_python-0.1.0 → imbot_sdk_python-0.1.1}/examples/run.sh +0 -0
  21. {imbot_sdk_python-0.1.0 → imbot_sdk_python-0.1.1}/imbot_sdk/client.py +0 -0
  22. {imbot_sdk_python-0.1.0 → imbot_sdk_python-0.1.1}/imbot_sdk/consts.py +0 -0
  23. {imbot_sdk_python-0.1.0 → imbot_sdk_python-0.1.1}/imbot_sdk/data_accessor.py +0 -0
  24. {imbot_sdk_python-0.1.0 → imbot_sdk_python-0.1.1}/imbot_sdk/listeners.py +0 -0
  25. {imbot_sdk_python-0.1.0 → imbot_sdk_python-0.1.1}/imbot_sdk/messages/__init__.py +0 -0
  26. {imbot_sdk_python-0.1.0 → imbot_sdk_python-0.1.1}/imbot_sdk/messages/base.py +0 -0
  27. {imbot_sdk_python-0.1.0 → imbot_sdk_python-0.1.1}/imbot_sdk/messages/contents.py +0 -0
  28. {imbot_sdk_python-0.1.0 → imbot_sdk_python-0.1.1}/imbot_sdk/models.py +0 -0
  29. {imbot_sdk_python-0.1.0 → imbot_sdk_python-0.1.1}/imbot_sdk/pb/__init__.py +0 -0
  30. {imbot_sdk_python-0.1.0 → imbot_sdk_python-0.1.1}/imbot_sdk/pb/appmessages_pb2.py +0 -0
  31. {imbot_sdk_python-0.1.0 → imbot_sdk_python-0.1.1}/imbot_sdk/pb/chatroom_pb2.py +0 -0
  32. {imbot_sdk_python-0.1.0 → imbot_sdk_python-0.1.1}/imbot_sdk/pb/connect_pb2.py +0 -0
  33. {imbot_sdk_python-0.1.0 → imbot_sdk_python-0.1.1}/imbot_sdk/pb/rtcroom_pb2.py +0 -0
  34. {imbot_sdk_python-0.1.0 → imbot_sdk_python-0.1.1}/imbot_sdk/py.typed +0 -0
  35. {imbot_sdk_python-0.1.0 → imbot_sdk_python-0.1.1}/imbot_sdk_python.egg-info/dependency_links.txt +0 -0
  36. {imbot_sdk_python-0.1.0 → imbot_sdk_python-0.1.1}/imbot_sdk_python.egg-info/requires.txt +0 -0
  37. {imbot_sdk_python-0.1.0 → imbot_sdk_python-0.1.1}/imbot_sdk_python.egg-info/top_level.txt +0 -0
  38. {imbot_sdk_python-0.1.0 → imbot_sdk_python-0.1.1}/proto/appmessages.proto +0 -0
  39. {imbot_sdk_python-0.1.0 → imbot_sdk_python-0.1.1}/proto/chatroom.proto +0 -0
  40. {imbot_sdk_python-0.1.0 → imbot_sdk_python-0.1.1}/proto/connect.proto +0 -0
  41. {imbot_sdk_python-0.1.0 → imbot_sdk_python-0.1.1}/proto/gen.sh +0 -0
  42. {imbot_sdk_python-0.1.0 → imbot_sdk_python-0.1.1}/proto/rtcroom.proto +0 -0
  43. {imbot_sdk_python-0.1.0 → imbot_sdk_python-0.1.1}/requirements.txt +0 -0
  44. {imbot_sdk_python-0.1.0 → imbot_sdk_python-0.1.1}/setup.cfg +0 -0
@@ -4,6 +4,13 @@ All notable changes to this project are documented here. The format follows
4
4
  [Keep a Changelog](https://keepachangelog.com/), and the project adheres to
5
5
  [Semantic Versioning](https://semver.org/).
6
6
 
7
+ ## [0.1.1] - 2026-06-25
8
+
9
+ ### Changed
10
+
11
+ - Documentation is now bilingual: English `README.md` / `docs/*.md` with Chinese
12
+ `README.zh-CN.md` / `docs/*.zh-CN.md`, linked via a language switcher.
13
+
7
14
  ## [0.1.0] - 2026-06-25
8
15
 
9
16
  ### Added
@@ -24,4 +31,5 @@ All notable changes to this project are documented here. The format follows
24
31
  text, recall info, merge, thumbnail-packed image, snapshot-packed video) with
25
32
  an `UnknownMessage` fallback.
26
33
 
34
+ [0.1.1]: https://github.com/juggleim/imbot-sdk-python/releases/tag/v0.1.1
27
35
  [0.1.0]: https://github.com/juggleim/imbot-sdk-python/releases/tag/v0.1.0
@@ -1,4 +1,5 @@
1
1
  include README.md
2
+ include README.zh-CN.md
2
3
  include LICENSE
3
4
  include requirements.txt
4
5
  include CHANGELOG.md
@@ -0,0 +1,335 @@
1
+ Metadata-Version: 2.4
2
+ Name: imbot-sdk-python
3
+ Version: 0.1.1
4
+ Summary: JuggleIM Python Bot SDK — WebSocket long-connection IM client for bots and server-side agents
5
+ Author-email: Tyler <tyler@juggle.im>
6
+ Maintainer-email: Tyler <tyler@juggle.im>
7
+ License-Expression: Apache-2.0
8
+ Project-URL: Homepage, https://github.com/juggleim/imbot-sdk-python
9
+ Project-URL: Repository, https://github.com/juggleim/imbot-sdk-python
10
+ Project-URL: Issues, https://github.com/juggleim/imbot-sdk-python/issues
11
+ Project-URL: Documentation, https://github.com/juggleim/imbot-sdk-python#readme
12
+ Keywords: juggleim,im,instant-messaging,chat,bot,websocket,sdk
13
+ Classifier: Development Status :: 3 - Alpha
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.8
18
+ Classifier: Programming Language :: Python :: 3.9
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
+ Requires-Python: >=3.8
26
+ Description-Content-Type: text/markdown
27
+ License-File: LICENSE
28
+ Requires-Dist: protobuf>=5.0
29
+ Requires-Dist: websocket-client>=1.6
30
+ Provides-Extra: dev
31
+ Requires-Dist: build; extra == "dev"
32
+ Requires-Dist: twine; extra == "dev"
33
+ Dynamic: license-file
34
+
35
+ # imbot-sdk-python
36
+
37
+ **English** | [简体中文](README.zh-CN.md)
38
+
39
+ [![PyPI version](https://img.shields.io/pypi/v/imbot-sdk-python.svg)](https://pypi.org/project/imbot-sdk-python/)
40
+ [![Python versions](https://img.shields.io/pypi/pyversions/imbot-sdk-python.svg)](https://pypi.org/project/imbot-sdk-python/)
41
+ [![License](https://img.shields.io/pypi/l/imbot-sdk-python.svg)](https://github.com/juggleim/imbot-sdk-python/blob/main/LICENSE)
42
+
43
+ `imbot-sdk-python` is the JuggleIM Python SDK. It keeps a long-lived WebSocket
44
+ connection to the IM service, making it a good fit for bots, server-side message
45
+ agents, or any Python program that needs to actively send and receive messages.
46
+ It covers connection management, messaging, conversation queries, history,
47
+ chatrooms, user status, RTC rooms and file credential queries.
48
+
49
+ - Source: <https://github.com/juggleim/imbot-sdk-python>
50
+ - Distribution name: `imbot-sdk-python`; import name: `import imbot_sdk`
51
+
52
+ ## Installation
53
+
54
+ ```bash
55
+ pip install imbot-sdk-python
56
+ ```
57
+
58
+ Dependencies (`protobuf>=5.0`, `websocket-client>=1.6`) are installed
59
+ automatically. Python 3.8+.
60
+
61
+ Install from source:
62
+
63
+ ```bash
64
+ git clone https://github.com/juggleim/imbot-sdk-python.git
65
+ cd imbot-sdk-python
66
+ pip install .
67
+ ```
68
+
69
+ ## Test environment
70
+
71
+ | Item | Value |
72
+ | --- | --- |
73
+ | Server API | `http://127.0.0.1` |
74
+ | WebSocket | `wss://127.0.0.1` |
75
+ | AppKey | `AppKey` |
76
+
77
+ > A user token is issued by your JuggleIM app server / console using your AppKey
78
+ > + AppSecret via the Server API. The SDK itself only establishes the
79
+ > connection and sends/receives messages.
80
+
81
+ ## Feature overview
82
+
83
+ - Connection management: `connect`, `disconnect`, `logout`, heartbeat keep-alive,
84
+ automatic reconnect.
85
+ - Messaging: send/receive for private, group, chatroom and public-channel
86
+ conversations.
87
+ - Message management: history query, recall, modify, mark-read, search, top
88
+ messages.
89
+ - Conversation management: list, unread count, top, mute, tags.
90
+ - User & group info: user profile, friend profile, group info, online-status
91
+ subscription.
92
+ - Chatroom: join/quit, chatroom messages, attribute sync.
93
+ - RTC: create / join / query / quit RTC rooms.
94
+ - File: credential query via `get_file_cred`.
95
+
96
+ ## Quick start
97
+
98
+ ### 1. Create a client
99
+
100
+ ```python
101
+ from imbot_sdk import ImBotClient
102
+
103
+ client = ImBotClient("wss://127.0.0.1", "your-appkey")
104
+ ```
105
+
106
+ Notes:
107
+
108
+ - Pass the base `address`; the SDK appends the path automatically to form
109
+ `ws://host/imbot` or `wss://host/imbot`.
110
+ - `client.platform` defaults to `"Bot"`.
111
+ - `client.auto_reconnect` defaults to `True`.
112
+
113
+ ### 2. Connect
114
+
115
+ ```python
116
+ code, ack = client.connect("your-token")
117
+ ```
118
+
119
+ Notes:
120
+
121
+ - On success `code == ClientErrorCode.SUCCESS`.
122
+ - After success `ack.userId` is written to `client.user_id`.
123
+ - `connect` may only be called while disconnected; a repeated connect returns
124
+ `ClientErrorCode.CONNECT_EXISTED`.
125
+ - After an explicit `disconnect()` or `logout()`, auto-reconnect stops.
126
+
127
+ ### 3. Two ways to receive messages
128
+
129
+ Prefer the high-level listener (you receive a decoded `Message`):
130
+
131
+ ```python
132
+ from imbot_sdk import MessageListener, messages
133
+
134
+ class MyListener(MessageListener):
135
+ def on_message_receive(self, msg):
136
+ if isinstance(msg.msg_content, messages.TextMessage):
137
+ print("text:", msg.msg_content.content)
138
+
139
+ client.add_message_listener(MyListener())
140
+ ```
141
+
142
+ If you want the raw protobuf payloads:
143
+
144
+ ```python
145
+ client.on_message_callback = lambda down_msg: print(down_msg)
146
+ client.on_stream_msg_callback = lambda stream_msg: print(stream_msg)
147
+ ```
148
+
149
+ ### 4. Send a message
150
+
151
+ ```python
152
+ from imbot_sdk import Conversation, messages
153
+ from imbot_sdk.pb import appmessages_pb2 as pb
154
+
155
+ text = messages.TextMessage("hello from imbot-sdk-python")
156
+ up = client.build_up_msg(text, client_uid="bot-1")
157
+
158
+ conv = Conversation(conversation_type=pb.Private, conversation="target-user-id")
159
+ code, ack = client.send_message(conv, up)
160
+ # ack.msgId / ack.msgSeqNo carry the server's acknowledgement
161
+ ```
162
+
163
+ `build_up_msg` encodes a content model into `UpMsg.msgType / msgContent /
164
+ flags`; you can also construct a `pb.UpMsg` directly.
165
+
166
+ ## Full example: connect, listen, echo
167
+
168
+ ```python
169
+ import time
170
+ from imbot_sdk import ImBotClient, Conversation, MessageListener, ClientErrorCode, messages
171
+ from imbot_sdk.pb import appmessages_pb2 as pb
172
+
173
+ class Echo(MessageListener):
174
+ def __init__(self, client):
175
+ self.client = client
176
+ def on_message_receive(self, msg):
177
+ c = msg.msg_content
178
+ if isinstance(c, messages.TextMessage) and msg.sender_id != self.client.user_id:
179
+ up = self.client.build_up_msg(messages.TextMessage("echo: " + c.content),
180
+ client_uid="echo-%d" % time.time_ns())
181
+ self.client.send_message(msg.conversation, up)
182
+
183
+ client = ImBotClient("wss://127.0.0.1", "AppKey")
184
+ client.add_message_listener(Echo(client))
185
+
186
+ code, ack = client.connect("your-token")
187
+ assert code == ClientErrorCode.SUCCESS
188
+ print("connected:", ack.userId)
189
+
190
+ # Proactively send a private message to a user
191
+ up = client.build_up_msg(messages.TextMessage("hi"), client_uid="greet-1")
192
+ client.send_message(Conversation(conversation_type=pb.Private, conversation="target-user-id"), up)
193
+
194
+ try:
195
+ while True:
196
+ time.sleep(1)
197
+ except KeyboardInterrupt:
198
+ client.disconnect()
199
+ ```
200
+
201
+ A runnable version lives in [`examples/echo_bot.py`](examples/echo_bot.py). The
202
+ recommended way is `.env` + the launch script:
203
+
204
+ ```bash
205
+ cp examples/.env.example examples/.env
206
+ # edit examples/.env, at least set IMBOT_TOKEN (IMBOT_TARGET optional)
207
+ bash examples/run.sh
208
+ ```
209
+
210
+ `run.sh` loads `examples/.env` and starts the echo bot; extra arguments are
211
+ passed through (e.g. `bash examples/run.sh --target some-user-id`). You can also
212
+ skip the script and pass args / export env vars directly:
213
+
214
+ ```bash
215
+ python examples/echo_bot.py --token <your-token> --target <target-user-id>
216
+ ```
217
+
218
+ Configuration (env vars / `.env`):
219
+
220
+ | Variable | Description | Required |
221
+ | --- | --- | --- |
222
+ | `IMBOT_TOKEN` | User token | Yes |
223
+ | `IMBOT_TARGET` | Target user id to greet on startup | No |
224
+ | `IMBOT_ADDRESS` | WebSocket base address | No |
225
+ | `IMBOT_APPKEY` | App AppKey | No |
226
+
227
+ Additional notes:
228
+
229
+ - Use `pb.Private` for private chats, `pb.Group` for groups, `pb.Chatroom` for
230
+ chatrooms, `pb.PublicChannel` for public channels.
231
+ - Chatroom messages can also be sent via `client.send_chatroom_msg(chatroom_id, up_msg)`.
232
+ - A received `msg.msg_content` is already decoded by content type, so you can
233
+ `isinstance`-check it directly.
234
+
235
+ ## Message types
236
+
237
+ Built-in content models live in `imbot_sdk.messages`:
238
+
239
+ | Type | Identifier | Class |
240
+ | --- | --- | --- |
241
+ | Text | `jg:text` | `TextMessage` |
242
+ | Image | `jg:img` | `ImageMessage` |
243
+ | File | `jg:file` | `FileMessage` |
244
+ | Video | `jg:video` | `VideoMessage` |
245
+ | Voice | `jg:voice` | `VoiceMessage` |
246
+ | Stream text | `jg:streamtext` | `StreamTextMessage` |
247
+ | Recall notice | `jg:recallinfo` | `RecallInfoMessage` |
248
+ | Merged message | `jg:merge` | `MergeMessage` |
249
+ | Thumbnail-packed image | `jg:tpimg` | `ThumbnailPackedImageMessage` |
250
+ | Snapshot-packed video | `jg:spvideo` | `SnapshotPackedVideoMessage` |
251
+
252
+ For content types that are not built in, the SDK falls back to
253
+ `messages.UnknownMessage`. The JSON encode/decode fields of these models are
254
+ stable, so messages interoperate with the other JuggleIM client SDKs.
255
+
256
+ ## Common APIs
257
+
258
+ > See [`docs/API.md`](docs/API.md) for the full method list. Naming follows
259
+ > Python conventions (snake_case).
260
+
261
+ ### Connection & state
262
+
263
+ `connect(token)`, `reconnect()`, `disconnect()`, `logout()`, `ping()`,
264
+ `add_connection_status_change_listener(listener)`
265
+
266
+ ### Messages
267
+
268
+ `send_message(conversation, up_msg)`, `qry_history_msgs(req)`, `recall_msg(req)`,
269
+ `modify_msg(req)`, `mark_read_msg(req)`, `msg_search(req)`,
270
+ `msg_global_search(req)`, `set_top_msg(req)`, `del_top_msg(req)`
271
+
272
+ ### Conversations
273
+
274
+ `get_conversation(req)`, `get_conversations(req)`, `sync_conversations(req)`,
275
+ `clear_unread_count(req)`, `set_conversation_top(req)`, `set_mute(req)`,
276
+ `delete_conversations(req)`
277
+
278
+ ### Users, groups, status
279
+
280
+ `fetch_user_info(user_id)`, `fetch_group_info(group_id)`,
281
+ `fetch_friend_info(friend_user_id)`, `get_user_status(req)`,
282
+ `subscribe_user_status(req)`, `unsubscribe_user_status(req)`
283
+
284
+ ### Chatroom
285
+
286
+ `join_chatroom(chatroom_id)`, `quit_chatroom(chatroom_id)`,
287
+ `send_chatroom_msg(chatroom_id, up_msg)`, `set_attributes(chatroom_id, attributes)`,
288
+ `remove_attributes(chatroom_id, keys)`
289
+
290
+ ### RTC
291
+
292
+ `create_rtc_room(req)`, `join_rtc_room(req)`, `qry_rtc_room(room_id)`,
293
+ `quit_rtc_room(room_id)`, `rtc_invite(req)`
294
+
295
+ ### File
296
+
297
+ `get_file_cred(req)`
298
+
299
+ > The SDK provides file credential queries; the actual file upload/download flow
300
+ > must be handled by your application against your storage service.
301
+
302
+ ## Usage notes
303
+
304
+ - `publish` and `query` both require the connection state to be `CONNECTED`,
305
+ otherwise they return `ClientErrorCode.CONNECT_CLOSED`.
306
+ - Sends and queries wait up to 10 seconds for an ACK, returning
307
+ `ClientErrorCode.SEND_TIMEOUT` / `ClientErrorCode.QUERY_TIMEOUT` on timeout.
308
+ - The SDK handles heartbeats automatically; if no downstream data arrives for
309
+ more than two heartbeat windows (~20s), it disconnects and tries to reconnect.
310
+ - Message listener callbacks run on internal threads — avoid long blocking work,
311
+ and hand off to a worker queue if needed.
312
+ - Image / file / voice / video content models only encode/decode content; they
313
+ do not upload the underlying files.
314
+
315
+ ## Regenerating protobuf
316
+
317
+ The `.proto` sources live in [`proto/`](proto/). Regenerate after editing:
318
+
319
+ ```bash
320
+ bash proto/gen.sh
321
+ ```
322
+
323
+ ## Module layout
324
+
325
+ | Module | Description |
326
+ | --- | --- |
327
+ | `imbot_sdk.ImBotClient` | Main client entry point |
328
+ | `imbot_sdk.ClientErrorCode` / `ConnectState` | Error codes and connection state |
329
+ | `imbot_sdk.models` | Domain models (`Conversation` / `Message` / `UserInfo` …) |
330
+ | `imbot_sdk.messages` | Message content models |
331
+ | `imbot_sdk.pb` | Protobuf types (`appmessages_pb2` / `connect_pb2` / `chatroom_pb2` / `rtcroom_pb2`) |
332
+
333
+ ## License
334
+
335
+ [LICENSE](LICENSE) (Apache-2.0)
@@ -0,0 +1,301 @@
1
+ # imbot-sdk-python
2
+
3
+ **English** | [简体中文](README.zh-CN.md)
4
+
5
+ [![PyPI version](https://img.shields.io/pypi/v/imbot-sdk-python.svg)](https://pypi.org/project/imbot-sdk-python/)
6
+ [![Python versions](https://img.shields.io/pypi/pyversions/imbot-sdk-python.svg)](https://pypi.org/project/imbot-sdk-python/)
7
+ [![License](https://img.shields.io/pypi/l/imbot-sdk-python.svg)](https://github.com/juggleim/imbot-sdk-python/blob/main/LICENSE)
8
+
9
+ `imbot-sdk-python` is the JuggleIM Python SDK. It keeps a long-lived WebSocket
10
+ connection to the IM service, making it a good fit for bots, server-side message
11
+ agents, or any Python program that needs to actively send and receive messages.
12
+ It covers connection management, messaging, conversation queries, history,
13
+ chatrooms, user status, RTC rooms and file credential queries.
14
+
15
+ - Source: <https://github.com/juggleim/imbot-sdk-python>
16
+ - Distribution name: `imbot-sdk-python`; import name: `import imbot_sdk`
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ pip install imbot-sdk-python
22
+ ```
23
+
24
+ Dependencies (`protobuf>=5.0`, `websocket-client>=1.6`) are installed
25
+ automatically. Python 3.8+.
26
+
27
+ Install from source:
28
+
29
+ ```bash
30
+ git clone https://github.com/juggleim/imbot-sdk-python.git
31
+ cd imbot-sdk-python
32
+ pip install .
33
+ ```
34
+
35
+ ## Test environment
36
+
37
+ | Item | Value |
38
+ | --- | --- |
39
+ | Server API | `http://127.0.0.1` |
40
+ | WebSocket | `wss://127.0.0.1` |
41
+ | AppKey | `AppKey` |
42
+
43
+ > A user token is issued by your JuggleIM app server / console using your AppKey
44
+ > + AppSecret via the Server API. The SDK itself only establishes the
45
+ > connection and sends/receives messages.
46
+
47
+ ## Feature overview
48
+
49
+ - Connection management: `connect`, `disconnect`, `logout`, heartbeat keep-alive,
50
+ automatic reconnect.
51
+ - Messaging: send/receive for private, group, chatroom and public-channel
52
+ conversations.
53
+ - Message management: history query, recall, modify, mark-read, search, top
54
+ messages.
55
+ - Conversation management: list, unread count, top, mute, tags.
56
+ - User & group info: user profile, friend profile, group info, online-status
57
+ subscription.
58
+ - Chatroom: join/quit, chatroom messages, attribute sync.
59
+ - RTC: create / join / query / quit RTC rooms.
60
+ - File: credential query via `get_file_cred`.
61
+
62
+ ## Quick start
63
+
64
+ ### 1. Create a client
65
+
66
+ ```python
67
+ from imbot_sdk import ImBotClient
68
+
69
+ client = ImBotClient("wss://127.0.0.1", "your-appkey")
70
+ ```
71
+
72
+ Notes:
73
+
74
+ - Pass the base `address`; the SDK appends the path automatically to form
75
+ `ws://host/imbot` or `wss://host/imbot`.
76
+ - `client.platform` defaults to `"Bot"`.
77
+ - `client.auto_reconnect` defaults to `True`.
78
+
79
+ ### 2. Connect
80
+
81
+ ```python
82
+ code, ack = client.connect("your-token")
83
+ ```
84
+
85
+ Notes:
86
+
87
+ - On success `code == ClientErrorCode.SUCCESS`.
88
+ - After success `ack.userId` is written to `client.user_id`.
89
+ - `connect` may only be called while disconnected; a repeated connect returns
90
+ `ClientErrorCode.CONNECT_EXISTED`.
91
+ - After an explicit `disconnect()` or `logout()`, auto-reconnect stops.
92
+
93
+ ### 3. Two ways to receive messages
94
+
95
+ Prefer the high-level listener (you receive a decoded `Message`):
96
+
97
+ ```python
98
+ from imbot_sdk import MessageListener, messages
99
+
100
+ class MyListener(MessageListener):
101
+ def on_message_receive(self, msg):
102
+ if isinstance(msg.msg_content, messages.TextMessage):
103
+ print("text:", msg.msg_content.content)
104
+
105
+ client.add_message_listener(MyListener())
106
+ ```
107
+
108
+ If you want the raw protobuf payloads:
109
+
110
+ ```python
111
+ client.on_message_callback = lambda down_msg: print(down_msg)
112
+ client.on_stream_msg_callback = lambda stream_msg: print(stream_msg)
113
+ ```
114
+
115
+ ### 4. Send a message
116
+
117
+ ```python
118
+ from imbot_sdk import Conversation, messages
119
+ from imbot_sdk.pb import appmessages_pb2 as pb
120
+
121
+ text = messages.TextMessage("hello from imbot-sdk-python")
122
+ up = client.build_up_msg(text, client_uid="bot-1")
123
+
124
+ conv = Conversation(conversation_type=pb.Private, conversation="target-user-id")
125
+ code, ack = client.send_message(conv, up)
126
+ # ack.msgId / ack.msgSeqNo carry the server's acknowledgement
127
+ ```
128
+
129
+ `build_up_msg` encodes a content model into `UpMsg.msgType / msgContent /
130
+ flags`; you can also construct a `pb.UpMsg` directly.
131
+
132
+ ## Full example: connect, listen, echo
133
+
134
+ ```python
135
+ import time
136
+ from imbot_sdk import ImBotClient, Conversation, MessageListener, ClientErrorCode, messages
137
+ from imbot_sdk.pb import appmessages_pb2 as pb
138
+
139
+ class Echo(MessageListener):
140
+ def __init__(self, client):
141
+ self.client = client
142
+ def on_message_receive(self, msg):
143
+ c = msg.msg_content
144
+ if isinstance(c, messages.TextMessage) and msg.sender_id != self.client.user_id:
145
+ up = self.client.build_up_msg(messages.TextMessage("echo: " + c.content),
146
+ client_uid="echo-%d" % time.time_ns())
147
+ self.client.send_message(msg.conversation, up)
148
+
149
+ client = ImBotClient("wss://127.0.0.1", "AppKey")
150
+ client.add_message_listener(Echo(client))
151
+
152
+ code, ack = client.connect("your-token")
153
+ assert code == ClientErrorCode.SUCCESS
154
+ print("connected:", ack.userId)
155
+
156
+ # Proactively send a private message to a user
157
+ up = client.build_up_msg(messages.TextMessage("hi"), client_uid="greet-1")
158
+ client.send_message(Conversation(conversation_type=pb.Private, conversation="target-user-id"), up)
159
+
160
+ try:
161
+ while True:
162
+ time.sleep(1)
163
+ except KeyboardInterrupt:
164
+ client.disconnect()
165
+ ```
166
+
167
+ A runnable version lives in [`examples/echo_bot.py`](examples/echo_bot.py). The
168
+ recommended way is `.env` + the launch script:
169
+
170
+ ```bash
171
+ cp examples/.env.example examples/.env
172
+ # edit examples/.env, at least set IMBOT_TOKEN (IMBOT_TARGET optional)
173
+ bash examples/run.sh
174
+ ```
175
+
176
+ `run.sh` loads `examples/.env` and starts the echo bot; extra arguments are
177
+ passed through (e.g. `bash examples/run.sh --target some-user-id`). You can also
178
+ skip the script and pass args / export env vars directly:
179
+
180
+ ```bash
181
+ python examples/echo_bot.py --token <your-token> --target <target-user-id>
182
+ ```
183
+
184
+ Configuration (env vars / `.env`):
185
+
186
+ | Variable | Description | Required |
187
+ | --- | --- | --- |
188
+ | `IMBOT_TOKEN` | User token | Yes |
189
+ | `IMBOT_TARGET` | Target user id to greet on startup | No |
190
+ | `IMBOT_ADDRESS` | WebSocket base address | No |
191
+ | `IMBOT_APPKEY` | App AppKey | No |
192
+
193
+ Additional notes:
194
+
195
+ - Use `pb.Private` for private chats, `pb.Group` for groups, `pb.Chatroom` for
196
+ chatrooms, `pb.PublicChannel` for public channels.
197
+ - Chatroom messages can also be sent via `client.send_chatroom_msg(chatroom_id, up_msg)`.
198
+ - A received `msg.msg_content` is already decoded by content type, so you can
199
+ `isinstance`-check it directly.
200
+
201
+ ## Message types
202
+
203
+ Built-in content models live in `imbot_sdk.messages`:
204
+
205
+ | Type | Identifier | Class |
206
+ | --- | --- | --- |
207
+ | Text | `jg:text` | `TextMessage` |
208
+ | Image | `jg:img` | `ImageMessage` |
209
+ | File | `jg:file` | `FileMessage` |
210
+ | Video | `jg:video` | `VideoMessage` |
211
+ | Voice | `jg:voice` | `VoiceMessage` |
212
+ | Stream text | `jg:streamtext` | `StreamTextMessage` |
213
+ | Recall notice | `jg:recallinfo` | `RecallInfoMessage` |
214
+ | Merged message | `jg:merge` | `MergeMessage` |
215
+ | Thumbnail-packed image | `jg:tpimg` | `ThumbnailPackedImageMessage` |
216
+ | Snapshot-packed video | `jg:spvideo` | `SnapshotPackedVideoMessage` |
217
+
218
+ For content types that are not built in, the SDK falls back to
219
+ `messages.UnknownMessage`. The JSON encode/decode fields of these models are
220
+ stable, so messages interoperate with the other JuggleIM client SDKs.
221
+
222
+ ## Common APIs
223
+
224
+ > See [`docs/API.md`](docs/API.md) for the full method list. Naming follows
225
+ > Python conventions (snake_case).
226
+
227
+ ### Connection & state
228
+
229
+ `connect(token)`, `reconnect()`, `disconnect()`, `logout()`, `ping()`,
230
+ `add_connection_status_change_listener(listener)`
231
+
232
+ ### Messages
233
+
234
+ `send_message(conversation, up_msg)`, `qry_history_msgs(req)`, `recall_msg(req)`,
235
+ `modify_msg(req)`, `mark_read_msg(req)`, `msg_search(req)`,
236
+ `msg_global_search(req)`, `set_top_msg(req)`, `del_top_msg(req)`
237
+
238
+ ### Conversations
239
+
240
+ `get_conversation(req)`, `get_conversations(req)`, `sync_conversations(req)`,
241
+ `clear_unread_count(req)`, `set_conversation_top(req)`, `set_mute(req)`,
242
+ `delete_conversations(req)`
243
+
244
+ ### Users, groups, status
245
+
246
+ `fetch_user_info(user_id)`, `fetch_group_info(group_id)`,
247
+ `fetch_friend_info(friend_user_id)`, `get_user_status(req)`,
248
+ `subscribe_user_status(req)`, `unsubscribe_user_status(req)`
249
+
250
+ ### Chatroom
251
+
252
+ `join_chatroom(chatroom_id)`, `quit_chatroom(chatroom_id)`,
253
+ `send_chatroom_msg(chatroom_id, up_msg)`, `set_attributes(chatroom_id, attributes)`,
254
+ `remove_attributes(chatroom_id, keys)`
255
+
256
+ ### RTC
257
+
258
+ `create_rtc_room(req)`, `join_rtc_room(req)`, `qry_rtc_room(room_id)`,
259
+ `quit_rtc_room(room_id)`, `rtc_invite(req)`
260
+
261
+ ### File
262
+
263
+ `get_file_cred(req)`
264
+
265
+ > The SDK provides file credential queries; the actual file upload/download flow
266
+ > must be handled by your application against your storage service.
267
+
268
+ ## Usage notes
269
+
270
+ - `publish` and `query` both require the connection state to be `CONNECTED`,
271
+ otherwise they return `ClientErrorCode.CONNECT_CLOSED`.
272
+ - Sends and queries wait up to 10 seconds for an ACK, returning
273
+ `ClientErrorCode.SEND_TIMEOUT` / `ClientErrorCode.QUERY_TIMEOUT` on timeout.
274
+ - The SDK handles heartbeats automatically; if no downstream data arrives for
275
+ more than two heartbeat windows (~20s), it disconnects and tries to reconnect.
276
+ - Message listener callbacks run on internal threads — avoid long blocking work,
277
+ and hand off to a worker queue if needed.
278
+ - Image / file / voice / video content models only encode/decode content; they
279
+ do not upload the underlying files.
280
+
281
+ ## Regenerating protobuf
282
+
283
+ The `.proto` sources live in [`proto/`](proto/). Regenerate after editing:
284
+
285
+ ```bash
286
+ bash proto/gen.sh
287
+ ```
288
+
289
+ ## Module layout
290
+
291
+ | Module | Description |
292
+ | --- | --- |
293
+ | `imbot_sdk.ImBotClient` | Main client entry point |
294
+ | `imbot_sdk.ClientErrorCode` / `ConnectState` | Error codes and connection state |
295
+ | `imbot_sdk.models` | Domain models (`Conversation` / `Message` / `UserInfo` …) |
296
+ | `imbot_sdk.messages` | Message content models |
297
+ | `imbot_sdk.pb` | Protobuf types (`appmessages_pb2` / `connect_pb2` / `chatroom_pb2` / `rtcroom_pb2`) |
298
+
299
+ ## License
300
+
301
+ [LICENSE](LICENSE) (Apache-2.0)
@@ -1,5 +1,7 @@
1
1
  # imbot-sdk-python
2
2
 
3
+ [English](README.md) | **简体中文**
4
+
3
5
  [![PyPI version](https://img.shields.io/pypi/v/imbot-sdk-python.svg)](https://pypi.org/project/imbot-sdk-python/)
4
6
  [![Python versions](https://img.shields.io/pypi/pyversions/imbot-sdk-python.svg)](https://pypi.org/project/imbot-sdk-python/)
5
7
  [![License](https://img.shields.io/pypi/l/imbot-sdk-python.svg)](https://github.com/juggleim/imbot-sdk-python/blob/main/LICENSE)
@@ -199,7 +201,7 @@ python examples/echo_bot.py --token <your-token> --target <target-user-id>
199
201
 
200
202
  ## 常用 API
201
203
 
202
- > 完整方法清单见 [`docs/API.md`](docs/API.md)。命名采用 Python 风格(snake_case)。
204
+ > 完整方法清单见 [`docs/API.zh-CN.md`](docs/API.zh-CN.md)。命名采用 Python 风格(snake_case)。
203
205
 
204
206
  ### 连接与状态
205
207