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 平台兼容性矩阵。