Go SDK 使用者、好友與線上狀態
本頁介紹與“人”有關的功能:本人的資料、其他使用者的資料、好友與好友申請、黑名單、線上狀態,以及本人的登入裝置。Go SDK 裡它們都是 im.Client 上的方法,方法名、引數與返回值以下文為準,與原始碼一一對應。
這些方法都要在登入之後呼叫(見初始化與登入)。收到的變化以事件的形式送達(見事件、同步與 Store),SDK 的記憶體 Store 只快取會話與訊息,好友、群和線上狀態需要你自己儲存。
| 要做什麼 | 看哪裡 |
|---|---|
| 讀取、修改本人資料 | 本人資料 |
| 查詢其他使用者的暱稱、頭像 | 其他使用者的資料 |
| 顯示線上狀態 | 線上狀態 |
| 列出、踢掉本人的登入裝置 | 登入裝置 |
| 好友、好友申請、新增方式 | 好友、好友申請、好友新增方式 |
| 拉黑 | 黑名單 |
本人資料
| 方法 | 用途 | 關鍵引數 |
|---|---|---|
c.Me(ctx) | 獲取本人資料 | 返回 *im.SelfProfile(含 HasPassword) |
c.UpdateProfile(ctx, nickname, avatarURL, attributes) | 修改本人資料 | 暱稱、頭像傳空字串表示不修改;attributes 傳 nil 表示不修改 |
c.SetPassword(ctx, oldPassword, newPassword) | 設定/修改密碼 | oldPassword 為空表示首次設定 |
c.ClientConfig(ctx) | 應用級配置 | 返回 map[string]any |
c.Report(ctx, reason, attributes) | 上報崩潰、日誌、統計等 | reason 不超過 256 字元 |
ctx := context.Background()
me, err := c.Me(ctx)
if err != nil {
log.Fatal(err)
}
_, err = c.UpdateProfile(ctx, "张三", "", map[string]any{"sign": "今天也要加油"})
if err != nil {
log.Print(err)
}
// 首次设置密码时第一个参数传空字符串
err = c.SetPassword(ctx, "", "new-pass-123")其他使用者的資料
| 方法 | 用途 | 關鍵引數 |
|---|---|---|
c.GetUser(ctx, username) | 獲取指定使用者的公開資料 | 返回 *im.UserProfile |
c.LookupUsers(ctx, usernames) | 批次查詢使用者 | 一次最多 100 個;返回 []im.UserProfile |
p, err := c.GetUser(ctx, "bob")
if err == nil {
fmt.Println(p.Username, p.Nickname)
}
profiles, err := c.LookupUsers(ctx, []string{"bob", "lisi"})使用者修改自己的資料時,你會收到 im.EventUserProfileChanged(user.profile_changed,只關於本人);其他使用者修改資料沒有推送,需要顯示最新資料時重新查詢。
線上狀態
| 方法 | 用途 | 關鍵引數 |
|---|---|---|
c.QueryPresence(ctx, usernames) | 查詢一次線上狀態 | 返回 []im.PresenceItem |
c.SubscribePresence(ctx, usernames) | 訂閱線上狀態 | 走長連線(presence.subscribe),必須先 ConnectWait 成功 |
c.UnsubscribePresence(ctx, usernames) | 取消訂閱 | usernames 為空切片時取消全部訂閱 |
訂閱模型是“訂閱 + 事件”,不是輪詢:SubscribePresence 登記要持續關注的人,之後這些人的狀態變化以 im.EventPresenceChanged(presence.changed)事件送達,每個事件只帶一個人的最新狀態。事件載荷是一個線上狀態 JSON,欄位與 QueryPresence 返回的 PresenceItem 相同(username、online、platforms、last_seen_at、version),直接解析到 im.PresenceItem 即可:
c.OnEvent(func(e im.Event) {
switch e.Name {
case im.EventPresenceChanged:
var p im.PresenceItem
if json.Unmarshal(e.Data, &p) == nil {
fmt.Println(p.Username, p.Online, p.Platforms)
}
case im.EventPresenceReset:
// 订阅被服务端取消(如应用的在线状态设置变化)
// 清空本地保存的状态后重新订阅
}
})
if err := c.SubscribePresence(ctx, []string{"bob"}); err != nil {
log.Print(err)
}只訂閱需要顯示的人
訂閱屬於單條長連線,斷線重連後要重新訂閱。每條連線能訂閱的人數有上限,好友可能有幾萬,只訂閱當前介面上要顯示線上狀態的人(如會話列表裡的好友、開啟中的單聊對方),離開介面時用 UnsubscribePresence 退訂。SDK 不會替你維護這份訂閱清單。
需要應用開啟線上狀態
線上狀態功能由你的應用在服務端開啟。未開啟時 SubscribePresence 以 permission_denied 拒絕,QueryPresence 同樣被拒絕。可以先用 c.ClientConfig(ctx) 讀取應用配置,決定介面上是否顯示線上狀態。
登入裝置
| 方法 | 用途 | 關鍵引數 |
|---|---|---|
c.Sessions(ctx) | 本人全部有效的登入會話(多端裝置) | 返回 []im.LoginSession,Current 為 true 的是本機 |
c.RevokeSession(ctx, sessionID) | 踢掉指定的登入會話 | 被踢的裝置長連線立即斷開,需要重新登入 |
LoginSession 含 SessionID、Platform、DeviceName、DeviceID、CreatedAt、LastActiveAt、Current。也可以用 c.SessionID() 直接取當前登入會話的服務端會話 ID,用來在裝置列表裡標記“本機”:
sessions, err := c.Sessions(ctx)
if err != nil {
log.Print(err)
}
for _, s := range sessions {
mark := ""
if s.SessionID == c.SessionID() || s.Current {
mark = "(本机)"
}
fmt.Println(s.DeviceName, s.Platform, mark)
}
// 吊销其他设备:跳过本机
for _, s := range sessions {
if s.SessionID != c.SessionID() {
_ = c.RevokeSession(ctx, s.SessionID)
}
}本人的裝置在其他裝置上被吊銷、或需要重新登入時,會收到 im.EventUserSessionsRevoked、im.EventUserReloginRequired,裝置列表變化時有 im.EventDevicesChanged。
好友
| 方法 | 用途 | 關鍵引數 |
|---|---|---|
c.Friends(ctx) | 好友列表 | 返回 []im.Friend,Remark/Attributes 是本人視角 |
c.CheckFriends(ctx, usernames) | 批次檢查好友關係 | 返回 []im.FriendCheck(Username + IsFriend) |
c.SetFriendRemark(ctx, username, remark, attributes) | 設定好友備註與擴充套件屬性 | 空字串/nil 表示不修改 |
c.RemoveFriend(ctx, username) | 刪除好友 | 雙方的好友列表都會移除對方 |
備註和自定義屬性只屬於本人這一側,對方看不到。好友關係的變化以事件送達:im.EventFriendAdded、im.EventFriendUpdated、im.EventFriendRemoved,載荷可解析為 im.FriendEventData(含 FriendUsername、Remark、Reason 等欄位)。刪除好友後,服務端可能同時取消你對他的線上狀態訂閱。
好友申請
傳送申請返回一個狀態字串:對方設定了需要驗證時為 pending,等對方處理;對方允許任何人新增時為 accepted,已直接成為好友。
| 方法 | 用途 | 關鍵引數 |
|---|---|---|
c.SendFriendRequest(ctx, username, message) | 發好友申請 | 返回 status:pending 或 accepted |
c.FriendRequests(ctx, which) | 收到/發出的申請列表 | which 為 received 或 sent;返回 []im.FriendRequest |
c.AcceptFriendRequest(ctx, username) | 接受申請 | 引數為申請人的使用者名稱 |
c.DeclineFriendRequest(ctx, username) | 拒絕申請 | 引數為申請人的使用者名稱 |
c.MarkFriendRequestsRead(ctx) | 收到的申請標為已讀 | 無引數 |
c.FriendRequestUnreadCount(ctx) | 申請未讀數 | 返回 int64 |
完整的申請流程:
// alice 向 bob 发起申请
status, err := c.SendFriendRequest(ctx, "bob", "我是 alice")
if err != nil {
log.Print(err)
} else if status == "accepted" {
fmt.Println("已成为好友")
}
// bob 这一侧:查未读、列出收到的申请、同意
n, _ := c.FriendRequestUnreadCount(ctx)
reqs, _ := c.FriendRequests(ctx, "received")
for _, r := range reqs {
fmt.Println(r.Username, r.Message, r.Status) // pending|accepted|declined
}
err = c.AcceptFriendRequest(ctx, "alice")
_ = c.MarkFriendRequestsRead(ctx)
// 发出的申请用 "sent" 查询;拒绝用 DeclineFriendRequest
sent, _ := c.FriendRequests(ctx, "sent")
_ = sent申請相關的事件:收到申請 im.EventFriendRequestReceived,發出的申請被拒絕 im.EventFriendRequestDeclined(載荷 im.FriendRequestEventData),其他裝置上把申請標為已讀時收到 im.EventFriendRequestRead,可以據此重新整理未讀數。
好友新增方式
| 方法 | 用途 | 關鍵引數 |
|---|---|---|
c.FriendSettings(ctx) | 讀取本人的好友新增模式 | 返回字串:anyone(任何人可直接加為好友)或 request(需要本人驗證) |
c.SetFriendSettings(ctx, mode) | 設定好友新增模式 | mode 為 anyone 或 request |
這不是免打擾
FriendSettings 控制的是“別人向我傳送好友申請時怎樣處理”,與訊息免打擾無關。模式為 anyone 時,別人的申請會直接成為好友,SendFriendRequest 一側拿到的 status 就是 accepted。
黑名單
| 方法 | 用途 | 關鍵引數 |
|---|---|---|
c.Blacklist(ctx) | 黑名單列表 | 返回 []string(使用者名稱) |
c.BlockUser(ctx, username) | 加入黑名單 | 已在黑名單中時同樣成功 |
c.UnblockUser(ctx, username) | 移出黑名單 | 不在黑名單中時同樣成功 |
把某人加入黑名單後,他不能再給本人發單聊訊息、不能向本人發好友申請。變化以 im.EventBlacklistChanged(blacklist.changed)送達,載荷 im.BlacklistChangedData 的 Blocked 為 false 表示移出了黑名單。
錯誤處理
以上方法的失敗都返回 *im.APIError,用 im.IsCode 判斷錯誤碼,可用的碼見事件、同步與 Store。例如使用者不存在返回 not_found,未登入返回 unauthenticated。
if _, err := c.GetUser(ctx, "ghost"); err != nil {
if im.IsCode(err, im.CodeNotFound) {
fmt.Println("用户不存在")
}
}另見
- 初始化與登入:建立客戶端、登入、建立長連線。
- 群組:建群、成員管理、邀請與申請。
- 事件、同步與 Store:事件列表、登入後同步與錯誤處理。
