功能与套餐开通对照表

本项目是自托管产品,“套餐”体现为三层控制:① 服务开通项(8 个 service.activation 开关)决定相关 Open API 是否返回 1021;② 配额(4 项)在协议上限内进一步收紧;③ 控制台功能开关(6 项)写穿到前两层。没有计费、购买与到期,因此本页只对照“能力 ↔ 开通项 ↔ 接口 ↔ SDK ↔ Demo ↔ 控制台”,并标注哪些是代码强制、哪些只是记录。

概念​

层数据模型作用点默认值
服务开通ServiceActivation.services: map<ServiceKey,bool>Open API 分发前、回调入队前、客户端 REST 建聊天室前8 项全部开通
配额ServiceActivation.quotas(4 项)建群/加人/入聊天室时取 min(协议上限, 配额)0 = 使用协议上限
功能开关控制台 features(6 项)写穿到 services 或 app.pushEnabled跟随服务开通项

当前契约表(Rust contract::dump_tables() 导出的机器产物 contract-tables.json)共 230 个 Open API 操作,其中 91 个声明了服务开通项;其余操作不校验开通状态。

前置条件​

  • 服务端已启动;已创建应用(POST /api/admin/apps)。
  • 持有 Admin Secret(IM_ADMIN_SECRET,默认 dev-admin)。
  • 若要验证 1021,需要一个可签名的 Open API 调用(AppKey + AppSecret + 签名),见OpenAPI 与 Postman 调试。
两个容易误解的点

客户端 WS 发送(send 帧)不读取服务开通项:关闭 private_chat 不会阻止已连接客户端继续发消息,只影响 Open API 发布接口。

敏感词过滤不依赖 sensitive_words 开关:只要应用配置了词表,命中就按 block/replace 处置;该开关只门禁 6 个词表管理接口。

步骤​

  1. 查看当前开通项与配额

    curl -sS -X GET "http://127.0.0.1:8080/api/admin/apps/demo/services" \ -H 'X-Admin-Secret: dev-admin'

  2. 关闭一个服务并验证 1021

    curl -sS -X POST "http://127.0.0.1:8080/api/admin/apps/demo/services" \ -H 'X-Admin-Secret: dev-admin' \ -H 'content-type: application/json' \ -d '{"services":{"private_chat":false},"quotas":{"maxGroupMembers":100,"maxSuperGroupMembers":1000,"maxChatroomMembers":200,"messageRatePerMinute":60}}'

    随后用 Open API 调 message.private.publish,应返回 403 / code=1021;调 user.get 仍成功(该操作无 service 声明)。

  3. 验证配额生效

    把 maxGroupMembers 设为 3 后创建群并加第 4 个成员,应返回 1015(成员数量超出上限);普通群上限默认取 protocol.limits.groupMaxMembers。

    配额只收紧、不放宽:即使配置值大于协议上限,实际仍以协议上限为准。

  4. 用控制台功能开关联动

    curl -sS -X POST "http://127.0.0.1:8080/api/admin/apps/demo/features" \ -H 'X-Admin-Secret: dev-admin' \ -H 'content-type: application/json' \ -d '{"features":{"friend":false,"group":false,"chatroom":false,"push":false,"sensitiveWord":false,"messageCallbacks":false}}'

    该接口把开关写穿到 services.private_chat/group/chatroom/sensitive_words/callbacks 与 app.pushEnabled。

  5. 恢复默认

    curl -sS -X POST "http://127.0.0.1:8080/api/admin/apps/demo/services" \ -H 'X-Admin-Secret: dev-admin' \ -H 'content-type: application/json' \ -d '{"services":{"private_chat":true,"group":true,"supergroup":true,"chatroom":true,"system_notification":true,"callbacks":true,"sensitive_words":true,"message_routing":true},"quotas":{"maxGroupMembers":0,"maxSuperGroupMembers":0,"maxChatroomMembers":0,"messageRatePerMinute":0}}'

参数表​

功能闭环表​

功能开通项 (service key)Open API / IDL opSDK opDemo 入口控制台代码强制?
单聊消息private_chatmessage.private.publishsendTextMessage / sendMessage会话(单聊)#services✅ 代码强制
状态消息(单聊)private_chatstatusmessage.private.publishsendTypingStatus会话输入条#services✅ 代码强制
群聊消息groupmessage.group.publishsendMessage(GROUP)+ 群聊 / 群管理#services✅ 代码强制
建群 / 群资料groupgroup.create / group.updatecreateGroup / updateGroupName+ 群聊#services✅ 代码强制
超级群(频道/用户组)supergroupsupergroup.channel.create / supergroup.usergroup.create / message.group.publish(channelId)createSupergroupChannel / createUserGroup(rev21);sendMessage options.channelId(rev23);频道 UI:ChannelSwitcher / ChannelListDialog / ChannelList(rev24,运行时组件)超级群场景 / 频道 / 频道级消息 / 频道 UI 指南#services✅ 代码强制
聊天室chatroomchatroom.create / message.chatroom.publishcreateChatroom / joinChatroom+ 聊天室#chatrooms✅ 代码强制
系统通知system_notificationmessage.system.publishgetSystemMessages(接收侧)系统通知会话#messages✅ 代码强制
全量消息路由message_routing无(未在任何 operation 上声明)无无#services(仅展示)🟡 仅记录(代码未读取)
服务端回调callbackscallback.config.set / callback.delivery.retry无(接收方为应用服务器)无#callbacks✅ 代码强制
敏感词词表管理sensitive_wordssensitive-word.set / sensitiveword.batch.add无(发送时自动过滤)发送含敏感词消息#sensitive✅ 代码强制
好友关系(无)friend.add / friend.list(未声明 service)sendFriendRequest / getFriends联系人#users(关系视图)⚪ 无开通项(仅 features.friend → private_chat)
在线状态(无)user.online.check / presence.batchgetOnlineStatus / getOnlineStatusBatch联系人在线点#connections⚪ 无开通项
离线推送通道(无,改为 app.pushEnabled)push.send / push.test(管理端)无(接收方 webhook)无#features(push)✅ 由应用推送开关强制
消息翻译 / AI 代理(无)message.translate / agent.chat.generate无无#features⚪ 由环境变量端点控制(未配置返回 1021)

8 个服务开通项的强制点​

service key能力声明该服务的操作数强制机制结论
private_chat单聊消息2Open API message.private.publish / statusmessage.private.publish 声明 service;未开通返回 1021✅ 代码强制
group普通群2323 个群相关 Open API 操作声明 service;群成员上限受配额约束✅ 代码强制
supergroup超级群2929 个超级群/用户组/频道操作声明 service✅ 代码强制
chatroom聊天室2626 个聊天室操作 + 客户端 REST POST /api/apps/{appkey}/chatrooms✅ 代码强制
system_notification系统通知1message.system.publish 发布前校验✅ 代码强制
callbacks服务端回调4事件入队前校验(未开通则事件被丢弃)+ 4 个回调管理操作✅ 代码强制
sensitive_words敏感词管理66 个敏感词词表操作声明 service;命中过滤本身只要词表非空就生效✅ 代码强制
message_routing全量消息路由0仅记录在开通项中,代码未读取(recorded-only)🟡 仅记录

计数由构建时解析服务端契约声明中的 service 字段得到;若解析失败则显示 0,页面仍可生成。

配额(services.quotas)​

配额字段默认生效点超出错误
maxGroupMembers3000(协议上限)建群、加群成员时取 min(协议上限, 配额)1015 MEMBERSHIP_LIMIT
maxSuperGroupMembers100000(协议上限)超级群成员上限1015
maxChatroomMembers5000(协议上限)加入聊天室时按在线人数校验1015
messageRatePerMinute120(仅回显)未在发送路径强制;接口级限流请用 ratelimit—(recorded-only)

控制台功能开关 → 数据源​

开关写穿到说明
friendservices.private_chat好友关系依赖单聊通道
groupservices.group普通群;不影响 supergroup
chatroomservices.chatroomOpen API 与客户端 REST 同源
pushapp.pushEnabled离线推送 webhook 开关
sensitiveWordservices.sensitive_words词表管理接口开关(过滤逻辑独立)
messageCallbacksservices.callbacks回调事件入队开关

示例​

查询 → 关闭 → 断言 1021 → 恢复(Node.js)​

service-gate.mjs
// service-gate.mjs — 验证服务开通项对 Open API 的强制效果
import { createHash, randomBytes } from 'node:crypto';

const HOST = process.env.IM_HOST || 'http://127.0.0.1:8080';
const ADMIN_SECRET = process.env.IM_ADMIN_SECRET || 'dev-admin';
const APPKEY = process.env.IM_APPKEY || 'demo';
const APP_SECRET = process.env.APP_SECRET || 'YOUR_APP_SECRET'; // 变量:应用 AppSecret

async function admin(method, path, body) {
  const res = await fetch(HOST + path, {
    method,
    headers: { 'X-Admin-Secret': ADMIN_SECRET, 'content-type': 'application/json' },
    body: body ? JSON.stringify(body) : undefined,
  });
  return (await res.json()).data;
}

async function openapi(path, body) {
  const nonce = randomBytes(8).toString('hex');
  const timestamp = String(Date.now());
  const signature = createHash('sha1').update(APP_SECRET + nonce + timestamp).digest('hex');
  const res = await fetch(HOST + '/im/v2' + path, {
    method: 'POST',
    headers: {
      'content-type': 'application/json',
      'App-Key': APPKEY,
      Nonce: nonce, Timestamp: timestamp, Signature: signature,
    },
    body: JSON.stringify(body),
  });
  return { status: res.status, body: await res.json() };
}

const before = await admin('GET', '/api/admin/apps/' + APPKEY + '/services');
console.log('当前 private_chat =', before.services.private_chat);

await admin('POST', '/api/admin/apps/' + APPKEY + '/services', { services: { private_chat: false } });
const blocked = await openapi('/message/private/publish', {
  fromUserId: 'alice', toUserId: 'bob', content: { type: 'text', text: 'hi' },
});
console.log('关闭后发布单聊:', blocked.status, blocked.body.code); // 期望 403 / 1021

await admin('POST', '/api/admin/apps/' + APPKEY + '/services', { services: { private_chat: true } });
const ok = await openapi('/message/private/publish', {
  fromUserId: 'alice', toUserId: 'bob', content: { type: 'text', text: 'hi' },
});
console.log('恢复后发布单聊:', ok.status, ok.body.code); // 期望 200 / 0

恢复全部开通(curl)​

Shell
curl -sS -X POST "http://127.0.0.1:8080/api/admin/apps/demo/services" \
  -H 'X-Admin-Secret: dev-admin' \
  -H 'content-type: application/json' \
  -d '{"services":{"private_chat":true,"group":true,"supergroup":true,"chatroom":true,"system_notification":true,"callbacks":true,"sensitive_words":true,"message_routing":true},"quotas":{"maxGroupMembers":0,"maxSuperGroupMembers":0,"maxChatroomMembers":0,"messageRatePerMinute":0}}'

常见问题​

关闭 service 后客户端还能发消息?​

能。客户端 WS send 帧不校验服务开通项;关闭只影响 Open API(以及客户端 REST 建聊天室)。若要做客户端级管控,请同时下发 features 快照到客户端,由客户端隐藏入口。

配额设得比协议上限大,会放宽吗?​

不会。生效值取 min(协议上限, 配额);配额只能收紧。

message_routing 开关有用吗?​

当前没有。它只出现在开通项列表中,代码没有读取点;全量消息路由由 callbacks 与订阅事件决定。

messageRatePerMinute 能限流吗?​

不能。该字段只回显;真正的接口限流是 ratelimit 的按 operation QPS(超限 1008 + Retry-After: 1)。

为什么 features 里点「好友」关掉,单聊也不能发了?​

friend 开关映射到 services.private_chat,因此 message.private.publish 会返回 1021。

如何判断某个 Open API 是否受开通项约束?​

看本页「功能闭环表」;或查 API 文档中该接口说明,1021 出现在错误码列表即表示有 service 声明。

相关链接​