SDK · Go
github.com/obihuang/imcore/clients/go(包名 imcoreadmin)是 imcore 入站
服务端 API(/openapi/v1)的零依赖 Go 客户端:从你自己的业务后端推送
用户资料与好友关系、上报通话录音。仅使用标准库(net/http +
encoding/json),独立 Go module(go 1.22),不引入服务端任何依赖。
前置条件(服务端配置)
openapi.enabled = true—— 入站组总开关(默认关,关闭时所有端点 404);- 鉴权:Bearer token。优先使用带 scope 的服务凭证(管理台
/admin/api/openapi/credentials创建,token 只显示一次);openapi.tokens为兼容全路由旧路径; - 各端点所需 scope:资料
user:profile_write、好友friendship:write、 通话录音call:recording_write(*或user:*前缀通配可用); - 通话录音端点还要求 AI SKU 且
call_analysis.enabled = true,否则 404。
安装
# 下载页源码包(推荐,版本化 tarball)
tar xzf imcore-sdk-go-<版本>.tar.gz # 得到 imcore-sdk-go/
go mod edit -replace github.com/obihuang/imcore/clients/go=./imcore-sdk-go
go get github.com/obihuang/imcore/clients/go
用法
package main
import (
"context"
"fmt"
"log"
admin "github.com/obihuang/imcore/clients/go"
)
func main() {
client, err := admin.NewClient("https://im.example.com", "<service-credential-token>")
if err != nil {
log.Fatal(err)
}
ctx := context.Background()
// 用户注册/资料变更后:推送资料投影(空 userName/avatar 保持服务端已存值)
processed, err := client.UpsertProfiles(ctx, []admin.ProfileItem{
{UserID: "1001", UserName: "alice", Avatar: "https://cdn/a.png"},
})
if err != nil {
log.Fatal(err)
}
fmt.Println("profiles processed:", processed)
// 业务侧建立/解除好友后:双向同步
if _, err := client.UpsertFriendships(ctx, []admin.FriendshipItem{
{UserA: "1001", UserB: "2002"},
}); err != nil {
log.Fatal(err)
}
// 呼叫中心通话结束后:上报录音(call_id 幂等,重复上报 deduped=true)
result, err := client.IngestCallRecording(ctx, admin.CallRecording{
CallID: "call-2026-0009",
RecordingURL: "https://records.example.com/call-0009.mp3",
Direction: "inbound",
FromNumber: "+10000000001",
ToNumber: "+10000000002",
AgentID: "agent-7",
StartedAt: 1760000000,
DurationSec: 183,
})
if err != nil {
var adminErr *admin.Error
if admin.AsAdminError(err) && adminErr.IsNotFound() {
log.Fatal("端点未开启:检查 call_analysis.enabled 与 SKU")
}
log.Fatal(err)
}
fmt.Printf("ingested %s status=%s deduped=%v\n", result.CallID, result.Status, result.Deduped)
}
行为细节
| 语义 | 说明 |
|---|---|
| 分批 | 单请求上限 100 条(服务端约束);SDK 对更大的切片自动分批并累加 processed,批间失败会短路并返回已处理数 |
| 本地预校验 | 空 userID、userA == userB、缺 call_id/recording_url 等直接在客户端报 *admin.Error(400 语义),不发请求 |
| 错误映射 | 非 2xx 返回 *admin.Error{StatusCode, Code, Index, Processed};IsUnauthorized/IsForbidden/IsNotFound/IsValidation/IsServerError 覆盖四类服务端状态,404 同时表示“服务端功能未开启” |
| 重试 | SDK 不自动重试;入站批处理幂等,5xx/超时后用相同数据重试是安全的 |
| 超时 | 默认 10s,可用 admin.WithHTTPClient(...) 自定义 |
| 并发 | Client 可并发复用(单个 http.Client) |
测试与版本
cd clients/go && go test ./...
版本常量 admin.SDKVersion 与 clients/SDK_VERSION 同步
(scripts/check_sdk_version.sh 在 CI 守护)。完整 HTTP 契约也可直接从
部署实例的 /openapi.yaml / /openapi.json 获取 OpenAPI 3.1 文档。
范围与后续
首期覆盖 /openapi/v1 全部四个入站端点。Node(@imcore/admin)与
Python(imcore-admin)版本共享同一行为矩阵,见
SDK_SERVER_ZH.md。后续:Java/PHP 语言、自动
重试/限流封装、公共仓库发布 —— 见
SDK 平台兼容性矩阵。