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:事件列表、登录后同步与错误处理。
