SDK · 服务端

五个零第三方依赖的服务端 SDK,共享同一行为矩阵与 /openapi/v1 wire 契约:

语言 包 语言下限 测试
Go github.com/obihuang/imcore/clients/go(imcoreadmin) Go 1.22 go test
Node @imcore/admin(TS,原生 type-stripping,无构建步骤) Node ≥ 22.6 node --test
Python imcore-admin(stdlib) Python ≥ 3.9 unittest
Java imcore-admin-java(JDK 17,java.net.http + 手写扁平 JSON) Java 17+ JUnit 5(JDK 内置 HttpServer stub)
PHP imcore/admin(8.1+,ext-curl + 原生 JSON) PHP ≥ 8.1 内置 php -S stub(docker php:8.1-cli 验证)

行为完全对齐(五套测试矩阵互相锁定):Bearer 鉴权、按服务端 100 条上限 自动分批并累加 processed、本地预校验(空 userID、userA == userB、缺 call_id/recording_url 不发请求即报错)、非 2xx 类型化错误(含 index/processed 批次细节与 401/403/404/400/5xx 谓词,404 同时表示服务 端功能未开启)、不自动重试(批处理幂等,5xx 后重试安全)。

前置条件(服务端配置,三语言通用)

  • openapi.enabled = true(默认关,关闭时所有端点 404);
  • Bearer token:带 scope 的服务凭证(管理台 /admin/api/openapi/credentials) 或旧版 openapi.tokens;
  • scope:资料 user:profile_write、好友 friendship:write、录音 call:recording_write(* / user:* 通配可用);
  • 录音端点需 AI SKU 且 call_analysis.enabled = true,否则 404。

Node(@imcore/admin)

tar xzf imcore-sdk-node-<版本>.tar.gz
# package.json 依赖: "@imcore/admin": "file:./imcore-sdk-node-<版本>"
import { ImcoreAdminClient } from '@imcore/admin';

const client = new ImcoreAdminClient('https://im.example.com', '<token>');
const processed = await client.upsertProfiles([{ userID: '1001', userName: 'alice' }]);
await client.upsertFriendships([{ userA: '1001', userB: '2002' }]);
const result = await client.ingestCallRecording({
  call_id: 'call-9', recording_url: 'https://records/9.mp3',
  direction: 'inbound', started_at: 1760000000, duration_sec: 183,
});

// 错误处理
import { asAdminError } from '@imcore/admin';
try {
  await client.removeFriendships([{ userA: '1001', userB: '2002' }]);
} catch (error) {
  const adminError = asAdminError(error);
  if (adminError?.isForbidden()) {
    // 凭证缺 friendship:write scope
  }
}

超时默认 10s;可通过 transport 选项注入自定义 HTTP 传输(测试/代理场景)。

Python(imcore-admin)

tar xzf imcore-sdk-python-<版本>.tar.gz
pip install ./imcore-sdk-python-<版本>
from imcore_admin import ImcoreAdminClient, ProfileItem, FriendshipItem, CallRecording

client = ImcoreAdminClient("https://im.example.com", "<token>")
client.upsert_profiles([ProfileItem(userID="1001", userName="alice")])
client.upsert_friendships([FriendshipItem(userA="1001", userB="2002")])
result = client.ingest_call_recording(CallRecording(
    call_id="call-9", recording_url="https://records/9.mp3",
    direction="inbound", started_at=1760000000, duration_sec=183))

Go 版用法详见 SDK_GO_ZH.md。

范围与后续

五语言均覆盖 /openapi/v1 全部四个入站端点。Java 用法(AdminClient.create(...), 构建:cd clients/kotlin && ./gradlew -p ../java test);PHP 用法(AdminClient::create(...), items 为带 wire 键的数组;测试:docker run --rm -v "$PWD/clients/php":/work -w /work php:8.1-cli php tests/run.php)。后续:重试/限流封装、公共仓库发布(Go proxy / npm / PyPI / Maven Central / Packagist)——见 SDK 平台兼容性矩阵。