Metadata-Version: 2.5
Name: tuitui-bot
Version: 1.0.16
Summary: 推推机器人 Python SDK
License-Expression: MIT
License-File: LICENSE
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: httpx<1,>=0.27
Requires-Dist: websockets<18,>=14
Provides-Extra: dev
Requires-Dist: build>=1.2; extra == 'dev'
Requires-Dist: hatchling>=1.27; extra == 'dev'
Requires-Dist: mypy>=1.13; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
Requires-Dist: pytest-cov>=6; extra == 'dev'
Requires-Dist: pytest-timeout>=2.3; extra == 'dev'
Requires-Dist: pytest>=8.3; extra == 'dev'
Requires-Dist: python-dotenv>=1; extra == 'dev'
Requires-Dist: respx>=0.22; extra == 'dev'
Requires-Dist: ruff>=0.9; extra == 'dev'
Requires-Dist: twine<8,>=7; extra == 'dev'
Provides-Extra: samples
Requires-Dist: python-dotenv>=1; extra == 'samples'
Description-Content-Type: text/markdown

# tuitui-bot

推推机器人异步 Python SDK，移植自 npm 包 `@qihoo/tuitui-bot-sdk`。支持 Python 3.10 及以上版本。

## 安装

```bash
pip install tuitui-bot
```

## 发送消息

```python
import asyncio

from tuitui_bot import TuituiBotClient


async def main() -> None:
    client = TuituiBotClient("your-app-id", "your-app-secret")
    try:
        response = await client.im.send_text(
            to=client.to.account("user-account"),
            text="**你好**，这是一条 `Markdown` 消息。",
        )
        print("消息发送成功", response)
    except Exception as error:
        print("消息发送失败", error)


asyncio.run(main())
```

SDK 使用 `client.to.account()`、`uid()`、`group()`、`accounts()` 和 `uids()` 创建单聊或群聊目标，
频道和帖子能力位于 `client.teams`。

消息、团队、文件和机器人属性等 API 调用失败时都会抛出异常，使用方应捕获并记录完整错误。接口错误
会抛出 `TuituiApiError`，异常文本包含底层网络错误。错误详情中的 `trans_id` 是本次 API 调用的上下文
ID；遇到难以定位的问题时，可将该 ID 和错误消息提交给推推技术支持团队。

## 事件订阅（收消息）

事件订阅通过 WebSocket 持续接收单聊、群聊、团队帖子和交互回调。只发送消息时不需要订阅；完整代码
见 `samples/receive.py`，消息结构见 SDK 导出的 `TuituiMessageData`。

SDK 自动确认事件、过滤心跳并去重。连接异常时会自动重连；如需感知错误，通过 `on_error` 记录日志，
不需要自行重连。调用 `await subscription.unsubscribe()` 后会关闭连接并停止重连。

## 发送交互式卡片

SDK 接收推推原生交互卡片结构，业务可以定义自己的模板。具体字段请参考 SDK 导出的
`TuituiOutboundInteractiveMessage` 类型以及推推 API 文档，完整代码请参考
`samples/send_interactive.py`。

**最佳实践**

需要提前开启事件订阅（收消息）。发送交互式卡片后，用户点击同意、拒绝等按钮时，会收到一条类型为
`interactive` 的消息。处理完业务逻辑后，应调用 `client.im.modify_interactive()` 原地更新卡片，删除
操作按钮并显示“已同意”或“已拒绝”等最终状态文案，不应继续保留可点击按钮，给用户操作反馈同时
避免用户重复操作。

## API

所有文本发送与编辑 API 的 `text` 字段都支持 Markdown 格式。

- `client.to`：创建账号、UID、群聊及批量消息目标。
- `client.im`：发送文本、图文混排、页面、链接和交互卡片，以及编辑、表情回复和聊天记录。
- `client.im.send_file()`、`client.teams.send_file()`：分别向单聊或群聊、团队帖子发送文件；支持 bytes、
  Path、本地路径、二进制文件对象、data URL 和 HTTP/HTTPS URL，文件大小限制为 100MB。
- `client.teams`：帖子、回复、编辑、表情、频道、标签、公告、成员和帖子链。
- `client.file`：底层文件上传。
- `client.file_space`：文件空间的节点、目录和文件 API。
- `client.property`：机器人信息、名称、头像、Webhook、交互地址和快捷指令。
- `client.event`：事件订阅、正文渲染和媒体提取。
- `client.request()`：调用尚未封装或未来新增的推推机器人 API。
