快速整合
本頁從零開始寫一個能登入、收發訊息的 Go 程式:建立工程、安裝 SDK、建立客戶端、用業務服務端簽發的憑證登入、建立長連線、收訊息並自動回覆、優雅退出。完成後你會得到一個可以直接 go run 的單檔案程式,可以在它的基礎上寫自己的機器人或整合邏輯。
準備工作
- 在控制檯使用註冊時自動建立的
demo應用,或另外建立應用,在概覽的“接入憑證”中複製 AppKey(如1575529652#demo)和 IM 服務的地址,即“REST 接入地址”(如https://im.example.com)。 - 業務服務端接入服務端 REST API,提供一個“獲取 IM 登入憑證”的介面:程式以某個使用者的身份呼叫它,業務服務端為這個使用者簽發登入憑證並返回,如
{"ticket": "ult_..."}。 - 安裝 Go 1.26.5 或以上。
憑證 5 分鐘內有效、只能使用一次,相當於使用者的臨時密碼。App Token 和 Client Secret 只能儲存在業務服務端,不能出現在 Go 程式中。開發和測試時,也可以用 curl 為測試賬號簽發一個憑證,複製到程式裡用。
建立工程並安裝
優先透過 Go 模組安裝,無需先下載 ZIP。在新的業務工程中執行:
mkdir imbot && cd imbot
go mod init example.com/imbot
go get github.com/DeepRespond-AI/deeprespond-im-go-sdk@v1.0.2儲存下面的完整 main.go 後執行 go mod tidy。示例使用 GitHub 已釋出的 v1.0.2 模組。
使用下載原始碼
如需離線開發,先下載 v1.0.2 原始碼 ZIP,解壓後可在業務工程中設定本地替換:
go mod edit -replace=github.com/DeepRespond-AI/deeprespond-im-go-sdk=/绝对路径/deeprespond-im-go-sdk-1.0.2替換路徑直接指向包含 go.mod 的解壓根目錄。移動原始碼後更新該路徑;恢復遠端版本時執行 go mod edit -dropreplace=github.com/DeepRespond-AI/deeprespond-im-go-sdk 和 go mod tidy。 只體驗 Demo 時無需建立 imbot,在解壓根目錄執行,見Demo 指南。
第 1 步:建立客戶端
cli, err := im.New(im.Config{
AppKey: "1575529652#demo", // 组织#应用,在控制台的应用详情中查看
APIURL: "https://im.example.com", // IM 服务端 REST 地址
})
if err != nil {
panic(err)
}im.New 不做任何網路請求,只檢查引數並填充預設值。全部配置項見初始化、登入與連線。
第 2 步:登入
生產環境用業務服務端簽發的憑證登入;開發測試時可以用密碼登入作為捷徑:
// 生产环境:ticket 来自你的业务服务端
session, err := cli.Login(ctx, im.LoginTicket, "alice", ticket)
// 开发测试捷径:密码登录(正式分发的程序不要这样写)
// session, err := cli.Login(ctx, im.LoginPassword, "alice", "pass-123")登入成功返回 *im.Session(訪問令牌、續期令牌、會話 ID、本人資料)。令牌的儲存與續期由 SDK 自動處理,你不需要重新整理它。
第 3 步:訂閱事件
長連線建立後,服務端的事件透過 OnEvent 回撥交給你。收新訊息只需處理 message.received:
cli.OnEvent(func(e im.Event) {
if e.Name != im.EventMessageReceived {
return
}
var m im.Message
if json.Unmarshal(e.Data, &m) != nil {
return
}
fmt.Printf("来自 %s:%s\n", m.Sender, m.TextBody())
})m.TextBody()提取文字訊息的正文;其他型別的訊息用m.BodyMap()拿到 body 物件;- 事件在同一個 goroutine 中按到達順序分發,回撥裡的耗時操作會阻塞後續事件,需要慢處理時自己開 goroutine;
- 全部事件見事件與同步。
第 4 步:建立長連線並同步
if err := cli.ConnectWait(ctx); err != nil {
panic(err)
}ConnectWait 建立長連線並阻塞等待首次認證完成(內部最長等 15 秒)。連線建立後才能收到事件,斷線後 SDK 自動重連。登入後建議做一次全量同步,把會話列表和最近訊息拉進記憶體快取:
n, err := cli.SyncAll(ctx)
fmt.Printf("已同步 %d 个会话\n", n)只收實時訊息、不讀歷史的機器人可以跳過同步。
第 5 步:傳送文字訊息
msg, err := cli.SendText(ctx, im.ToUser("bob"), "你好", nil)
fmt.Println(msg.Seq, err)im.ToUser("bob") 發給某個使用者,im.ToGroup("群 ID") 發給某個群。連線可用時訊息優先走長連線,連線不可用時自動改走 REST;傳送失敗(返回錯誤)時是否重試由你決定。
第 6 步:優雅退出
<-ctx.Done() // 例如收到 Ctrl+C
_ = cli.Logout(context.Background()) // 退出登录:断开长连接并结束服务端会话只需斷開連線、保持登入狀態時,用 cli.Disconnect();之後可以再次 Connect。Go SDK 沒有離線傳送佇列:SendText 返回成功即服務端已接收,之後投遞由服務端完成;程序被直接殺死不影響已經發出的訊息。
完整示例
把以下內容儲存為 main.go。示例從環境變數讀取憑證;實際程式中請改為呼叫你業務服務端的“獲取 IM 登入憑證”介面。
package main
import (
"context"
"encoding/json"
"fmt"
"os"
"os/signal"
"syscall"
"time"
im "github.com/DeepRespond-AI/deeprespond-im-go-sdk"
)
// 向业务服务端获取当前用户的 IM 登录凭证。
// 实际程序中在这里调用你自己定义的接口;业务服务端校验身份后,
// 用 App Token 调 IM 服务的 REST API 为用户签发凭证并返回。
func fetchTicket() (string, error) {
t := os.Getenv("IM_TICKET")
if t == "" {
return "", fmt.Errorf("请先设置 IM_TICKET(由业务服务端签发,见文档“快速集成”)")
}
return t, nil
}
func main() {
// Ctrl+C 或 SIGTERM 时取消 ctx,触发退出
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer stop()
// 1. 创建客户端(不做网络请求)
cli, err := im.New(im.Config{
AppKey: "1575529652#demo",
APIURL: "https://im.example.com",
})
if err != nil {
panic(err)
}
// 2. 登录:生产用凭证;开发测试可用 im.LoginPassword
ticket, err := fetchTicket()
if err != nil {
panic(err)
}
if _, err := cli.Login(ctx, im.LoginTicket, "alice", ticket); err != nil {
panic(err)
}
// 3. 订阅事件:收到文本消息时打印并回复一句
cli.OnEvent(func(e im.Event) {
if e.Name != im.EventMessageReceived {
return
}
var m im.Message
if json.Unmarshal(e.Data, &m) != nil {
return
}
fmt.Printf("来自 %s:%s\n", m.Sender, m.TextBody())
go func() {
sendCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
if _, err := cli.SendText(sendCtx, im.ToUser(m.Sender), "收到:"+m.TextBody(), nil); err != nil {
fmt.Println("回复失败:", err)
}
}()
})
// 4. 建立长连接并等待认证完成,然后全量同步一次
if err := cli.ConnectWait(ctx); err != nil {
panic(err)
}
fmt.Println("已连接,Ctrl+C 退出")
if n, err := cli.SyncAll(ctx); err != nil {
fmt.Println("同步失败:", err)
} else {
fmt.Printf("已同步 %d 个会话\n", n)
}
// 5. 等待退出信号,优雅退出
<-ctx.Done()
fmt.Println("退出中…")
logoutCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
_ = cli.Logout(logoutCtx)
}執行
go mod tidy
IM_TICKET=ult_xxx go run .再用另一個賬號(或 Web 端)給這個使用者發訊息,程式會列印收到的內容並自動回覆。傳送目標換成 im.ToGroup("群 ID") 就能把機器人拉進群裡用。
密碼登入只在開發測試時用
示例中的 im.LoginTicket 是生產環境的登入方式。開發除錯時可以把登入一行換成 cli.Login(ctx, im.LoginPassword, "alice", "pass-123"),省去簽發憑證的步驟;正式程式中不要內嵌密碼。
