私信 API(DirectApi)¶
1. 概述¶
DirectApi 同时支持 Web 平台和 Android 平台,通过已登录的 igapi.web.Client 或 igapi.android.Client 构造。igapi.ios.Client 也可用于构造 DirectApi,但调用任意方法都会抛出 TypeError(iOS 暂未实现 Direct 端点)。
Web 平台提供四类能力:
- 建群 / 创建会话(REST):
create_group_thread()通过 Web 旧版 REST 接口一次性建群,收件人直接使用 IGID/pk,无需 FBID,也无人数上限。 - 建群并发首条消息(GraphQL):
create_group_thread_graphql()不预先建群,直接把收件人放进 GraphQLIGDirectTextSendMutation的 variables,由服务端隐式建群并发送首条消息。 - 发送文本私信(GraphQL):
send_text()(私聊)/send_text_to_thread()(已有群聊线程),底层走 Web GraphQLIGDirectTextSendMutation。 - REST broadcast 直发:
send_text_broadcast()走旧版 RESTdirect_v2/threads/broadcast/text/端点,不预先建群,直接提交收件人集合发送。
Android 平台目前只提供一类能力:
- REST broadcast 直发:
send_text_broadcast(),走 Android 私有 APIdirect_v2/threads/broadcast/text/(signed_body签名),语义与 Web 的 broadcast 直发一致,但请求签名和端点参数不同。
重要:Web 专属方法(
create_group_thread/create_group_thread_graphql/prefetch_tokens/fire_init_signals/send_text/send_text_to_thread)在非igapi.web.Client上调用会抛TypeError。send_text_broadcast()同时支持igapi.android.Client与igapi.web.Client,igapi.ios.Client调用抛TypeError。所有方法调用前DirectApi使用的客户端都必须已登录。
四种发送路径的取舍¶
| 方法 | 平台 | 底层协议 | 建群方式 | 适用场景 |
|---|---|---|---|---|
create_group_thread() |
Web | REST | 先建群,返回 thread_id | 需要复用 thread_id 多次发送 |
create_group_thread_graphql() |
Web | GraphQL | 隐式建群 + 首条消息 | 建群与首条消息一步完成 |
send_text() / send_text_to_thread() |
Web | GraphQL | 已有会话 / 隐式建会话 | 常规私聊 / 已知 thread_id 发送 |
send_text_broadcast() |
Android / Web | REST | 隐式建群 + 发送 | 不需要 thread_id,一次性直发 |
鉴权说明¶
- Web 方法复用 Web 会话已有的
csrftoken(注入X-CSRFToken请求头),无需fb_dtsg/jazoest。调用前必须先完成igapi.web.Client的登录或通过account=恢复登录态。 - Android
send_text_broadcast()复用 Android 会话的signed_body签名机制,调用前必须先完成igapi.android.Client的登录或通过account=恢复登录态。
2. 快速开始¶
import asyncio
import igapi
async def main():
# 通过已保存的 Web 账号信息恢复登录态
account = igapi.web.AccountInfo.parse("<username>:<password>||<csrf_token>|<cookies>||")
web = igapi.web.Client(account=account)
direct = igapi.DirectApi(web)
# 1) 建群(≥2 个收件人)或创建 1:1 会话(1 个收件人)
thread_id = await direct.create_group_thread([
"17841400000000001",
"17841400000000002",
])
print("群线程 ID:", thread_id)
# 2) 向群聊线程发送消息
result = await direct.send_text_to_thread(thread_id, "大家好 👋")
print("消息 ID:", result.item_id)
# 3) 直接给某人发私信(首发自动建会话)
await direct.send_text("17841400000000003", "你好")
# 4) GraphQL 建群并直接发首条消息(不需要先拿 thread_id)
result = await direct.create_group_thread_graphql(
["17841400000000001", "17841400000000002"],
"大家好,我是 GraphQL 建群",
)
print("GraphQL 建群 thread_id:", result.thread_id)
# 5) Web REST broadcast 直发(不预先建群)
await direct.send_text_broadcast(["17841400000000003"], "Web broadcast 直发")
asyncio.run(main())
Android 平台仅支持 send_text_broadcast():
import asyncio
import igapi
async def main():
account = igapi.android.AccountInfo.parse("用户名:密码||android_id;phone_id;uuid;device_id|cookies||")
android = igapi.android.Client(account=account)
direct = igapi.DirectApi(android)
result = await direct.send_text_broadcast(["17841400000000003"], "Android broadcast 直发")
print("thread_id:", result.thread_id)
asyncio.run(main())
3. API 参考¶
3.1 DirectApi(client)¶
构造 Direct 私信 API。
| 参数 | 类型 | 说明 |
|---|---|---|
client |
igapi.android.Client | igapi.web.Client | igapi.ios.Client |
已登录的客户端。Web 专属方法只接受 igapi.web.Client;send_text_broadcast() 接受 Android/Web;igapi.ios.Client 可构造但调用任意方法都抛 TypeError |
3.2 await create_group_thread(recipient_users)¶
通过 Web 旧版 REST 接口建群 / 创建 1:1 会话。
请求端点:POST /api/v1/direct_v2/create_group_thread/
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
recipient_users |
list[str] |
是 | 收件人 IGID/pk 列表(10-11 位数字字符串),无需 17 位 FBID |
行为:
- 1 个收件人 → 创建 1:1 私聊会话
- 2+ 个收件人 → 创建群聊
- 无 32 人上限的三段式流程,一次性建成
返回:str —— 群线程 ID(thread_id),可直接传给 send_text_to_thread()。
异常:
| 异常 | 触发条件 |
|---|---|
ValueError |
recipient_users 为空,或响应缺少 thread_id |
PermissionError |
未登录(csrftoken 缺失) |
ConnectionError |
网络错误或 HTTP 错误状态码 |
3.3 await send_text(recipient_igid, text)¶
向指定用户发送文本私信(私聊,首发自动建会话)。
底层:Web GraphQL IGDirectTextSendMutation
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
recipient_igid |
str |
是 | 收件人 IGID (pk),10-11 位数字 |
text |
str |
是 | 消息文本 |
异常:
| 异常 | 触发条件 |
|---|---|
ValueError |
IG 软拒绝(HTTP 200 但无 mutation response,可能触达 24h 发送上限) |
PermissionError |
未登录 |
ConnectionError |
网络错误 |
3.4 await send_text_to_thread(thread_id, text)¶
向已有群聊线程发送文本消息。
底层:Web GraphQL IGDirectTextSendMutation
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
thread_id |
str |
是 | 群聊线程 ID(create_group_thread() 返回值) |
text |
str |
是 | 消息文本 |
异常:同 send_text()。
3.5 await create_group_thread_graphql(recipient_users, text)¶
通过 GraphQL IGDirectTextSendMutation 创建群聊并发送首条文本消息(仅 igapi.web.Client)。
与 create_group_thread()(旧版 REST)不同:不预先建群,直接把所有收件人放进 GraphQL variables,由服务端隐式建群并直接发送首条消息,一步完成。
底层:Web GraphQL IGDirectTextSendMutation
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
recipient_users |
list[str] |
是 | 收件人 IGID/pk 列表,至少 2 个才能创建群聊 |
text |
str |
是 | 群聊创建后的首条消息文本 |
异常:
| 异常 | 触发条件 |
|---|---|
ValueError |
recipient_users 少于 2 个,或 IG 软拒绝(可能触达发送上限) |
PermissionError |
未登录 |
ConnectionError |
网络错误 |
TypeError |
非 igapi.web.Client 调用 |
3.6 await send_text_broadcast(recipient_users, text)¶
通过旧版 REST broadcast 接口向收件人集合直接发送文本(Android / Web 均支持)。
不预先调用建群接口,而是直接提交收件人集合,由服务端选择或隐式创建线程后发送消息。Android 走 direct_v2/threads/broadcast/text/(signed_body 签名),Web 走同名 REST 端点(X-CSRFToken)。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
recipient_users |
list[str] |
是 | 收件人 ID 列表;1 个为 1:1,2+ 个为群聊收件人集合 |
text |
str |
是 | 消息文本 |
异常:
| 异常 | 触发条件 |
|---|---|
ValueError |
recipient_users 为空 |
PermissionError |
未登录 |
ConnectionError |
网络错误 |
TypeError |
igapi.ios.Client 调用(iOS 暂未实现该端点) |
3.7 SendTextResult¶
发送文本私信的返回结果。
| 属性 | 类型 | 说明 |
|---|---|---|
thread_id |
str \| None |
消息所在的线程 ID |
item_id |
str \| None |
消息 ID |
timestamp |
str \| None |
服务端时间戳(微秒) |
4. 注意事项¶
- 必须已登录:Web 方法依赖
csrftoken,Androidsend_text_broadcast()依赖signed_body签名,未登录调用均会抛PermissionError。 - 收件人 ID 类型:所有方法都用 IGID/pk(10-11 位数字),不是 17 位 EIMU FBID。
- 软拒绝:
send_text()/send_text_to_thread()/create_group_thread_graphql()返回 HTTP 200 但缺少 mutation response 时,视为 IG 静默丢弃(可能触达 24h 发送上限),SDK 会抛ValueError,而非误判为成功。 - 平台边界:Web 专属方法在 Android/iOS 客户端上调用会抛
TypeError;send_text_broadcast()支持 Android/Web,但 iOS 调用同样抛TypeError(iOS 暂未实现 Direct 端点)。 - 频率限制:私信是高风控接口,建议控制发送频率,避免账号被风控。