From 93f467247822816b214c57c166f15b70b8242673 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=9E=97?= <576101059@qq.com> Date: Fri, 5 Nov 2021 17:38:07 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8DBUG&=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 26 +++++++- group/api.go | 172 +++++++++++++++++++++++++++++++++++++++---------- group/group.go | 18 +++--- group/types.go | 69 ++++++++++++-------- im_test.go | 145 +++++++++++++++++++++++++++-------------- 5 files changed, 311 insertions(+), 119 deletions(-) diff --git a/README.md b/README.md index 3d345a0..9bb0f35 100644 --- a/README.md +++ b/README.md @@ -669,7 +669,7 @@ func main() { √ - 群组管理 + 群组管理 拉取App中的所有群组ID @@ -725,6 +725,14 @@ func main() { App管理员可以根据群组ID获取群组成员的资料。 √ + + + 拉取群成员详细资料 + + Group.PullMembers + 本方法由“拉取群成员详细资料(FetchMembers)”拓展而来 + √ + 修改群基础资料 @@ -773,6 +781,14 @@ func main() { App管理员可以通过本接口获取某一用户加入的群信息。默认不获取用户已加入但未激活好友工作群(Work)以及直播群(AVChatRoom)群信息。 √ + + + 拉取用户所加入的群组 + + Group.PullMemberGroups + 本方法由“拉取用户所加入的群组(FetchMemberGroups)”拓展而来 + √ + 查询用户在群组中的身份 @@ -926,6 +942,14 @@ func main() { √ + + + 续拉取群历史消息 + + Group.PullMessages + 本方法由“拉取群历史消息(FetchMessages)”拓展而来 + √ + 获取直播群在线人数 diff --git a/group/api.go b/group/api.go index 7822d61..b65fb6a 100644 --- a/group/api.go +++ b/group/api.go @@ -89,6 +89,13 @@ type API interface { // https://cloud.tencent.com/document/product/269/1617 FetchMembers(groupId string, limit, offset int, filter ...*Filter) (ret *FetchMembersRet, err error) + // PullMembers 续拉取群成员详细资料 + // 本方法由“拉取群成员详细资料(FetchMembers)”拓展而来 + // App管理员可以根据群组ID获取群组成员的资料。 + // 点击查看详细文档: + // https://cloud.tencent.com/document/product/269/1617 + PullMembers(arg *PullMembersArg, fn func(ret *FetchMembersRet)) (err error) + // UpdateGroup 修改群基础资料 // App管理员可以通过该接口修改指定群组的基础信息。 // 点击查看详细文档: @@ -123,7 +130,14 @@ type API interface { // App管理员可以通过本接口获取某一用户加入的群信息。默认不获取用户已加入但未激活好友工作群(Work)以及直播群(AVChatRoom)群信息。 // 点击查看详细文档: // https://cloud.tencent.com/document/product/269/1625 - FetchMemberGroups(arg FetchMemberGroupsArg) (ret *FetchMemberGroupsRet, err error) + FetchMemberGroups(arg *FetchMemberGroupsArg) (ret *FetchMemberGroupsRet, err error) + + // PullMemberGroups 续拉取用户所加入的群组 + // 本方法由“拉取用户所加入的群组(FetchMemberGroups)”拓展而来 + // App管理员可以通过本接口获取某一用户加入的群信息。默认不获取用户已加入但未激活好友工作群(Work)以及直播群(AVChatRoom)群信息。 + // 点击查看详细文档: + // https://cloud.tencent.com/document/product/269/1625 + PullMemberGroups(arg *PullMemberGroupsArg, fn func(ret *FetchMemberGroupsRet)) (err error) // GetRolesInGroup 查询用户在群组中的身份 // App管理员可以通过该接口获取一批用户在群内的身份,即“成员角色”。 @@ -224,6 +238,15 @@ type API interface { // https://cloud.tencent.com/document/product/269/2738 FetchMessages(groupId string, limit int, msgSeq ...int) (ret *FetchMessagesRet, err error) + // PullMessages 续拉取群历史消息 + // 本方法由“拉取群历史消息(FetchMessages)”拓展而来 + // 即时通信 IM 的群消息是按 Seq 排序的,按照 server 收到群消息的顺序分配 Seq,先发的群消息 Seq 小,后发的 Seq 大。 + // 如果用户想拉取一个群的全量消息,首次拉取时不用填拉取 Seq,Server 会自动返回最新的消息,以后拉取时拉取 Seq 填上次返回的最小 Seq 减1。 + // 如果返回消息的 IsPlaceMsg 为1,表示这个 Seq 的消息或者过期、或者存储失败、或者被删除了。 + // 点击查看详细文档: + // https://cloud.tencent.com/document/product/269/2738 + PullMessages(groupId string, limit int, fn func(ret *FetchMessagesRet)) (err error) + // GetOnlineMemberNum 获取直播群在线人数 // App 管理员可以根据群组 ID 获取直播群在线人数。 // 点击查看详细文档: @@ -356,7 +379,7 @@ func (a *api) CreateGroup(group *Group) (groupId string, err error) { req := &createGroupReq{} req.GroupId = group.id req.OwnerUserId = group.owner - req.Type = group.types + req.GroupType = group.groupType req.Name = group.name req.FaceUrl = group.avatar req.Introduction = group.introduction @@ -374,8 +397,8 @@ func (a *api) CreateGroup(group *Group) (groupId string, err error) { } } - if len(group.members) > 0 { - req.MemberList = make([]*memberItem, 0, len(group.members)) + if c := len(group.members); c > 0 { + req.MemberList = make([]*memberItem, 0, c) var item *memberItem for _, member := range group.members { @@ -424,7 +447,7 @@ func (a *api) GetGroup(groupId string, filter ...*Filter) (group *Group, err err return } - if groups != nil && len(groups) > 0 { + if len(groups) > 0 { if err = groups[0].err; err != nil { return } @@ -473,7 +496,7 @@ func (a *api) GetGroups(groupIds []string, filters ...*Filter) (groups []*Group, if group.err == nil { group.id = item.GroupId group.name = item.Name - group.types = item.Type + group.groupType = item.GroupType group.owner = item.OwnerUserId group.avatar = item.FaceUrl group.memberNum = item.MemberNum @@ -525,10 +548,7 @@ func (a *api) GetGroups(groupIds []string, filters ...*Filter) (groups []*Group, // 点击查看详细文档: // https://cloud.tencent.com/document/product/269/1617 func (a *api) FetchMembers(groupId string, limit, offset int, filters ...*Filter) (ret *FetchMembersRet, err error) { - req := &fetchMembersReq{} - req.GroupId = groupId - req.Limit = limit - req.Offset = offset + req := &fetchMembersReq{GroupId: groupId, Limit: limit, Offset: offset} if len(filters) > 0 { if filter := filters[0]; filter != nil { @@ -547,7 +567,7 @@ func (a *api) FetchMembers(groupId string, limit, offset int, filters ...*Filter ret = &FetchMembersRet{} ret.Total = resp.MemberNum ret.List = make([]*Member, 0, len(resp.MemberList)) - ret.HasMore = resp.MemberNum > limit*(offset+1) + ret.HasMore = resp.MemberNum > limit+offset for _, m := range resp.MemberList { member := &Member{ @@ -572,6 +592,33 @@ func (a *api) FetchMembers(groupId string, limit, offset int, filters ...*Filter return } +// PullMembers 续拉取群成员详细资料 +// 本方法由“拉取群成员详细资料(FetchMembers)”拓展而来 +// App管理员可以根据群组ID获取群组成员的资料。 +// 点击查看详细文档: +// https://cloud.tencent.com/document/product/269/1617 +func (a *api) PullMembers(arg *PullMembersArg, fn func(ret *FetchMembersRet)) (err error) { + var ( + offset int + ret *FetchMembersRet + ) + + for ret == nil || ret.HasMore { + ret, err = a.FetchMembers(arg.GroupId, arg.Limit, offset, arg.Filter) + if err != nil { + return + } + + fn(ret) + + if ret.HasMore { + offset += arg.Limit + } + } + + return +} + // UpdateGroup 修改群基础资料 // App管理员可以通过该接口修改指定群组的基础信息。 // 点击查看详细文档: @@ -721,12 +768,8 @@ func (a *api) DestroyGroup(groupId string) (err error) { // App管理员可以通过本接口获取某一用户加入的群信息。默认不获取用户已加入但未激活好友工作群(Work)以及直播群(AVChatRoom)群信息。 // 点击查看详细文档: // https://cloud.tencent.com/document/product/269/1625 -func (a *api) FetchMemberGroups(arg FetchMemberGroupsArg) (ret *FetchMemberGroupsRet, err error) { - req := &fetchMemberGroupsReq{} - req.UserId = arg.UserId - req.Limit = arg.Limit - req.Offset = arg.Offset - req.GroupType = string(arg.GroupType) +func (a *api) FetchMemberGroups(arg *FetchMemberGroupsArg) (ret *FetchMemberGroupsRet, err error) { + req := &fetchMemberGroupsReq{UserId: arg.UserId, Limit: arg.Limit, Offset: arg.Offset, GroupType: arg.GroupType} if arg.Filter != nil { req.ResponseFilter = &responseFilter{ @@ -756,14 +799,14 @@ func (a *api) FetchMemberGroups(arg FetchMemberGroupsArg) (ret *FetchMemberGroup if arg.Limit == 0 { ret.HasMore = false } else { - ret.HasMore = arg.Limit*(1+arg.Offset) < resp.TotalCount + ret.HasMore = arg.Limit+arg.Offset < resp.TotalCount } for _, item := range resp.GroupList { group := NewGroup() group.id = item.GroupId group.name = item.Name - group.types = item.Type + group.groupType = item.GroupType group.owner = item.OwnerUserId group.avatar = item.FaceUrl group.memberNum = item.MemberNum @@ -807,21 +850,55 @@ func (a *api) FetchMemberGroups(arg FetchMemberGroupsArg) (ret *FetchMemberGroup return } +// PullMemberGroups 续拉取用户所加入的群组 +// 本方法由“拉取用户所加入的群组(FetchMemberGroups)”拓展而来 +// App管理员可以通过本接口获取某一用户加入的群信息。默认不获取用户已加入但未激活好友工作群(Work)以及直播群(AVChatRoom)群信息。 +// 点击查看详细文档: +// https://cloud.tencent.com/document/product/269/1625 +func (a *api) PullMemberGroups(arg *PullMemberGroupsArg, fn func(ret *FetchMemberGroupsRet)) (err error) { + var ( + ret *FetchMemberGroupsRet + req = &FetchMemberGroupsArg{ + UserId: arg.UserId, + Limit: arg.Limit, + GroupType: arg.GroupType, + Filter: arg.Filter, + IsWithNoActiveGroups: arg.IsWithNoActiveGroups, + IsWithLiveRoomGroups: arg.IsWithLiveRoomGroups, + } + ) + + for ret == nil || ret.HasMore { + ret, err = a.FetchMemberGroups(req) + if err != nil { + return + } + + fn(ret) + + if ret.HasMore { + req.Offset += arg.Limit + } + } + + return +} + // GetRolesInGroup 查询用户在群组中的身份 // App管理员可以通过该接口获取一批用户在群内的身份,即“成员角色”。 // 点击查看详细文档: // https://cloud.tencent.com/document/product/269/1626 -func (a *api) GetRolesInGroup(groupId string, userIds []string) (memberRoles map[string]string, err error) { - req := getRolesInGroupReq{GroupId: groupId, UserIds: userIds} +func (a *api) GetRolesInGroup(groupId string, userIds []string) (roles map[string]string, err error) { + req := &getRolesInGroupReq{GroupId: groupId, UserIds: userIds} resp := &getRolesInGroupResp{} if err = a.client.Post(serviceGroup, commandGetRoleInGroup, req, resp); err != nil { return } - memberRoles = make(map[string]string) + roles = make(map[string]string, len(resp.MemberRoleList)) for _, item := range resp.MemberRoleList { - memberRoles[item.UserId] = item.Role + roles[item.UserId] = item.Role } return @@ -834,7 +911,7 @@ func (a *api) GetRolesInGroup(groupId string, userIds []string) (memberRoles map // 点击查看详细文档: // https://cloud.tencent.com/document/product/269/1627 func (a *api) ForbidSendMessage(groupId string, userIds []string, shutUpTime int64) (err error) { - req := forbidSendMessageReq{ + req := &forbidSendMessageReq{ GroupId: groupId, UserIds: userIds, ShutUpTime: shutUpTime, @@ -860,7 +937,7 @@ func (a *api) AllowSendMessage(groupId string, userIds []string) (err error) { // 点击查看详细文档: // https://cloud.tencent.com/document/product/269/2925 func (a *api) GetShuttedUpMembers(groupId string) (shuttedUps map[string]int64, err error) { - req := getShuttedUpMembersReq{GroupId: groupId} + req := &getShuttedUpMembersReq{GroupId: groupId} resp := &getShuttedUpMembersResp{} if err = a.client.Post(serviceGroup, commandGetGroupShuttedUin, req, resp); err != nil { @@ -884,7 +961,7 @@ func (a *api) SendMessage(groupId string, message *Message) (ret *SendMessageRet return } - req := sendMessageReq{} + req := &sendMessageReq{} req.GroupId = groupId req.FromUserId = message.GetSender() req.OfflinePushInfo = message.GetOfflinePushInfo() @@ -931,8 +1008,8 @@ func (a *api) SendMessage(groupId string, message *Message) (ret *SendMessageRet // App 管理员可以通过该接口在群组中发送系统通知。 // 点击查看详细文档: // https://cloud.tencent.com/document/product/269/1630 -func (a *api) SendNotification(groupId, content string, userId ...string) (err error) { - req := sendNotificationReq{GroupId: groupId, Content: content, UserIds: userId} +func (a *api) SendNotification(groupId, content string, userIds ...string) (err error) { + req := &sendNotificationReq{GroupId: groupId, Content: content, UserIds: userIds} if err = a.client.Post(serviceGroup, commandSendGroupSystemNotification, req, &types.ActionBaseResp{}); err != nil { return @@ -948,7 +1025,7 @@ func (a *api) SendNotification(groupId, content string, userId ...string) (err e // 点击查看详细文档: // https://cloud.tencent.com/document/product/269/1633 func (a *api) ChangeGroupOwner(groupId, userId string) (err error) { - req := changeGroupOwnerReq{GroupId: groupId, OwnerUserId: userId} + req := &changeGroupOwnerReq{GroupId: groupId, OwnerUserId: userId} if err = a.client.Post(serviceGroup, commandChangeGroupOwner, req, &types.ActionBaseResp{}); err != nil { return @@ -1013,10 +1090,10 @@ func (a *api) ImportGroup(group *Group) (groupId string, err error) { return } - req := importGroupReq{} + req := &importGroupReq{} req.GroupId = group.id req.OwnerUserId = group.owner - req.Type = group.types + req.GroupType = group.groupType req.Name = group.name req.FaceUrl = group.avatar req.Introduction = group.introduction @@ -1026,9 +1103,9 @@ func (a *api) ImportGroup(group *Group) (groupId string, err error) { req.CreateTime = group.createTime if data := group.GetAllCustomData(); data != nil { - req.AppDefinedData = make([]customDataItem, 0, len(data)) + req.AppDefinedData = make([]*customDataItem, 0, len(data)) for key, val := range data { - req.AppDefinedData = append(req.AppDefinedData, customDataItem{ + req.AppDefinedData = append(req.AppDefinedData, &customDataItem{ Key: key, Value: val, }) @@ -1191,6 +1268,35 @@ func (a *api) FetchMessages(groupId string, limit int, msgSeq ...int) (ret *Fetc return } +// PullMessages 续拉取群历史消息 +// 本方法由“拉取群历史消息(FetchMessages)”拓展而来 +// 即时通信 IM 的群消息是按 Seq 排序的,按照 server 收到群消息的顺序分配 Seq,先发的群消息 Seq 小,后发的 Seq 大。 +// 如果用户想拉取一个群的全量消息,首次拉取时不用填拉取 Seq,Server 会自动返回最新的消息,以后拉取时拉取 Seq 填上次返回的最小 Seq 减1。 +// 如果返回消息的 IsPlaceMsg 为1,表示这个 Seq 的消息或者过期、或者存储失败、或者被删除了。 +// 点击查看详细文档: +// https://cloud.tencent.com/document/product/269/2738 +func (a *api) PullMessages(groupId string, limit int, fn func(ret *FetchMessagesRet)) (err error) { + var ( + ret *FetchMessagesRet + msgSeq int + ) + + for ret == nil || ret.HasMore { + ret, err = a.FetchMessages(groupId, limit, msgSeq) + if err != nil { + return + } + + fn(ret) + + if ret.HasMore { + msgSeq = ret.NextSeq + } + } + + return +} + // GetOnlineMemberNum 获取直播群在线人数 // App 管理员可以根据群组 ID 获取直播群在线人数。 // 点击查看详细文档: diff --git a/group/group.go b/group/group.go index 8093c55..f8e57ca 100644 --- a/group/group.go +++ b/group/group.go @@ -52,7 +52,7 @@ type Group struct { err error id string // 群ID name string // 群名称 - types string // 群类型 + groupType GroupType // 群类型 owner string // 群主ID introduction string // 群简介 notification string // 群公告 @@ -107,14 +107,14 @@ func (g *Group) GetName() string { return g.name } -// SetType 设置群类型 -func (g *Group) SetType(types GroupType) { - g.types = string(types) +// SetGroupType 设置群类型 +func (g *Group) SetGroupType(groupType GroupType) { + g.groupType = groupType } -// GetType 获取群类型 -func (g *Group) GetType() GroupType { - return GroupType(g.types) +// GetGroupType 获取群类型 +func (g *Group) GetGroupType() GroupType { + return g.groupType } // SetIntroduction 设置群简介 @@ -351,11 +351,11 @@ func (g *Group) checkNameArgError() error { // 检测群类型参数错误 func (g *Group) checkTypeArgError() error { - if g.types == "" { + if g.groupType == "" { return errNotSetGroupType } - switch GroupType(g.types) { + switch GroupType(g.groupType) { case TypePublic, TypePrivate, TypeChatRoom, TypeLiveRoom: default: return errInvalidGroupType diff --git a/group/types.go b/group/types.go index 6676212..03743e8 100644 --- a/group/types.go +++ b/group/types.go @@ -63,7 +63,7 @@ type ( createGroupReq struct { OwnerUserId string `json:"Owner_Account,omitempty"` // (选填)群主 ID(需是 已导入 的账号)。填写后自动添加到群成员中;如果不填,群没有群主 GroupId string `json:"GroupId,omitempty"` // (选填)为了使得群组 ID 更加简单,便于记忆传播,腾讯云支持 App 在通过 REST API 创建群组时 自定义群组 ID - Type string `json:"Type"` // (必填)群组形态,包括 Public(陌生人社交群),Private(即 Work,好友工作群),ChatRoom(即 Meeting,会议群),AVChatRoom(直播群) + GroupType GroupType `json:"Type"` // (必填)群组形态,包括 Public(陌生人社交群),Private(即 Work,好友工作群),ChatRoom(即 Meeting,会议群),AVChatRoom(直播群) Name string `json:"Name"` // (必填)群名称,最长30字节,使用 UTF-8 编码,1个汉字占3个字节 Introduction string `json:"Introduction,omitempty"` // (选填)群简介,最长240字节,使用 UTF-8 编码,1个汉字占3个字节 Notification string `json:"Notification,omitempty"` // (选填)群公告,最长300字节,使用 UTF-8 编码,1个汉字占3个字节 @@ -124,7 +124,7 @@ type ( GroupId string `json:"GroupId"` ErrorCode int `json:"ErrorCode"` ErrorInfo string `json:"ErrorInfo"` - Type string `json:"GroupType"` + GroupType GroupType `json:"Type"` Name string `json:"Name"` AppId int `json:"Appid"` Introduction string `json:"Introduction"` @@ -146,19 +146,19 @@ type ( // 获取群成员详细资料(请求) fetchMembersReq struct { - GroupId string `json:"GroupId"` - Limit int `json:"Limit"` - Offset int `json:"Offset"` - MemberInfoFilter []string `json:"MemberInfoFilter"` - MemberRoleFilter []string `json:"MemberRoleFilter"` - MemberCustomDataFilter []string `json:"AppDefinedDataFilter_GroupMember"` + GroupId string `json:"GroupId"` // (必填)需要拉取成员信息的群组的 ID + Limit int `json:"Limit"` // (选填)一次最多获取多少个成员的资料,不得超过6000。如果不填,则获取群内全部成员的信息 + Offset int `json:"Offset"` // (选填)从第几个成员开始获取,如果不填则默认为0,表示从第一个成员开始获取 + MemberInfoFilter []string `json:"MemberInfoFilter"` // (选填)需要获取哪些信息, 如果没有该字段则为群成员全部资料,成员信息字段详情请参阅 群成员资料 + MemberRoleFilter []string `json:"MemberRoleFilter"` // (选填)拉取指定身份的群成员资料。如没有填写该字段,默认为所有身份成员资料,成员身份可以为:“Owner”,“Admin”,“Member” + MemberCustomDataFilter []string `json:"AppDefinedDataFilter_GroupMember"` // (选填)默认情况是没有的。该字段用来群成员维度的自定义字段过滤器,指定需要获取的群成员维度的自定义字段,群成员维度的自定义字段详情请参阅 自定义字段 } // 获取群成员详细资料(响应) fetchMembersResp struct { types.ActionBaseResp - MemberNum int `json:"MemberNum"` - MemberList []memberItem `json:"MemberList"` + MemberNum int `json:"MemberNum"` // 本群组的群成员总数 + MemberList []memberItem `json:"MemberList"` // 获取到的群成员列表,其中包含了全部或者指定的群成员信息,成员信息字段详情请参阅 群成员资料 } // FetchMembersRet 拉取群成员结果 @@ -168,6 +168,13 @@ type ( List []*Member // 成员列表 } + // PullMembersArg 续拉取群成员(参数) + PullMembersArg struct { + GroupId string // (必填)需要拉取成员信息的群组的 ID + Limit int // (选填)一次最多获取多少个成员的资料,不得超过6000。如果不填,则获取群内全部成员的信息 + Filter *Filter // (选填)返回过滤器 + } + // 修改群基础资料(请求) updateGroupReq struct { GroupId string `json:"GroupId"` @@ -241,12 +248,22 @@ type ( List []*Group // 列表 } + // PullMemberGroupsArg 续拉取用户所加入的群组(参数) + PullMemberGroupsArg struct { + UserId string // (必填)用户ID + Limit int // (选填)单次拉取的群组数量,如果不填代表所有群组 + GroupType GroupType // (选填)拉取哪种群组类型 + Filter *Filter // (选填)过滤器 + IsWithNoActiveGroups bool // (选填)是否获取用户已加入但未激活的 Private(即新版本中 Work,好友工作群) 群信息 + IsWithLiveRoomGroups bool // (选填)是否获取用户加入的 AVChatRoom(直播群) + } + // 拉取用户所加入的群组(请求) fetchMemberGroupsReq struct { UserId string `json:"Member_Account"` // (必填)用户ID Limit int `json:"Limit,omitempty"` // (选填)单次拉取的群组数量,如果不填代表所有群组 Offset int `json:"Offset,omitempty"` // (选填)从第多少个群组开始拉取 - GroupType string `json:"GroupType,omitempty"` // (选填)拉取哪种群组类型 + GroupType GroupType `json:"GroupType,omitempty"` // (选填)拉取哪种群组类型 WithHugeGroups int `json:"WithHugeGroups,omitempty"` WithNoActiveGroups int `json:"WithNoActiveGroups,omitempty"` ResponseFilter *responseFilter `json:"ResponseFilter,omitempty"` // (选填)响应过滤 @@ -256,7 +273,7 @@ type ( fetchMemberGroupsResp struct { types.ActionBaseResp TotalCount int `json:"TotalCount"` - GroupList []groupInfo `json:"GroupIds"` + GroupList []groupInfo `json:"GroupIdList"` } // 获取 @@ -334,9 +351,9 @@ type ( // 在群组中发送系统通知(请求) sendNotificationReq struct { - GroupId string `json:"GroupId"` - Content string `json:"Content"` - UserIds []string `json:"ToMembers_Account"` + GroupId string `json:"GroupId"` // (必填)向哪个群组发送系统通知 + Content string `json:"Content"` // (必填)系统通知的内容 + UserIds []string `json:"ToMembers_Account,omitempty"` // (选填)接收者群成员列表,请填写接收者 UserID,不填或为空表示全员下发 } // 转让群主(请求) @@ -369,17 +386,17 @@ type ( // 导入群基础资料(请求) importGroupReq struct { - OwnerUserId string `json:"Owner_Account,omitempty"` // (选填)群主 ID(需是 已导入 的账号)。填写后自动添加到群成员中;如果不填,群没有群主 - GroupId string `json:"GroupId,omitempty"` // (选填)为了使得群组 ID 更加简单,便于记忆传播,腾讯云支持 App 在通过 REST API 创建群组时 自定义群组 ID - Type string `json:"GroupType"` // (必填)群组形态,包括 Public(陌生人社交群),Private(即 Work,好友工作群),ChatRoom(即 Meeting,会议群),AVChatRoom(直播群) - Name string `json:"Name"` // (必填)群名称,最长30字节,使用 UTF-8 编码,1个汉字占3个字节 - Introduction string `json:"Introduction,omitempty"` // (选填)群简介,最长240字节,使用 UTF-8 编码,1个汉字占3个字节 - Notification string `json:"Notification,omitempty"` // (选填)群公告,最长300字节,使用 UTF-8 编码,1个汉字占3个字节 - FaceUrl string `json:"FaceUrl,omitempty"` // (选填)群头像 URL,最长100字节 - MaxMemberNum uint `json:"MaxMemberCount,omitempty"` // (选填)最大群成员数量,缺省时的默认值:付费套餐包上限,例如体验版是20,如果升级套餐包,需按照修改群基础资料修改这个字段 - ApplyJoinOption string `json:"ApplyJoinOption,omitempty"` // (选填)申请加群处理方式。包含 FreeAccess(自由加入),NeedPermission(需要验证),DisableApply(禁止加群),不填默认为 NeedPermission(需要验证) 仅当创建支持申请加群的 群组 时,该字段有效 - AppDefinedData []customDataItem `json:"AppDefinedData,omitempty"` // (选填)群组维度的自定义字段,默认情况是没有的,可以通过 即时通信 IM 控制台 进行配置,详情请参阅 自定义字段 - CreateTime int64 `json:"CreateTime"` // (选填)群组的创建时间 + OwnerUserId string `json:"Owner_Account,omitempty"` // (选填)群主 ID(需是 已导入 的账号)。填写后自动添加到群成员中;如果不填,群没有群主 + GroupId string `json:"GroupId,omitempty"` // (选填)为了使得群组 ID 更加简单,便于记忆传播,腾讯云支持 App 在通过 REST API 创建群组时 自定义群组 ID + GroupType GroupType `json:"Type"` // (必填)群组形态,包括 Public(陌生人社交群),Private(即 Work,好友工作群),ChatRoom(即 Meeting,会议群),AVChatRoom(直播群) + Name string `json:"Name"` // (必填)群名称,最长30字节,使用 UTF-8 编码,1个汉字占3个字节 + Introduction string `json:"Introduction,omitempty"` // (选填)群简介,最长240字节,使用 UTF-8 编码,1个汉字占3个字节 + Notification string `json:"Notification,omitempty"` // (选填)群公告,最长300字节,使用 UTF-8 编码,1个汉字占3个字节 + FaceUrl string `json:"FaceUrl,omitempty"` // (选填)群头像 URL,最长100字节 + MaxMemberNum uint `json:"MaxMemberCount,omitempty"` // (选填)最大群成员数量,缺省时的默认值:付费套餐包上限,例如体验版是20,如果升级套餐包,需按照修改群基础资料修改这个字段 + ApplyJoinOption string `json:"ApplyJoinOption,omitempty"` // (选填)申请加群处理方式。包含 FreeAccess(自由加入),NeedPermission(需要验证),DisableApply(禁止加群),不填默认为 NeedPermission(需要验证) 仅当创建支持申请加群的 群组 时,该字段有效 + AppDefinedData []*customDataItem `json:"AppDefinedData,omitempty"` // (选填)群组维度的自定义字段,默认情况是没有的,可以通过 即时通信 IM 控制台 进行配置,详情请参阅 自定义字段 + CreateTime int64 `json:"CreateTime"` // (选填)群组的创建时间 } // 导入群基础资料(响应) diff --git a/im_test.go b/im_test.go index 9c6d5ec..85410f1 100644 --- a/im_test.go +++ b/im_test.go @@ -1016,8 +1016,8 @@ func TestIm_Private_GetUnreadMessageNum(t *testing.T) { // 创建群组 func TestIm_Group_CreateGroup(t *testing.T) { g := group.NewGroup() - g.SetName("测试群1") - g.SetType(group.TypeLiveRoom) + g.SetName("测试群2") + g.SetGroupType(group.TypePrivate) g.SetMaxMemberNum(30) g.SetAvatar("http://www.baidu.com") g.SetGroupId("test_group2") @@ -1040,7 +1040,7 @@ func TestIm_Group_CreateGroup(t *testing.T) { // 解散单个群 func TestIm_Group_DestroyGroup(t *testing.T) { - err := NewIM().Group().DestroyGroup("test_group1") + err := NewIM().Group().DestroyGroup("test_group2") if err != nil { handleError(t, "group.DestroyGroup", err) } @@ -1050,15 +1050,15 @@ func TestIm_Group_DestroyGroup(t *testing.T) { // 获取单个群详细资料 func TestIm_Group_GetGroup(t *testing.T) { - g, err := NewIM().Group().GetGroup("test_group1") + g, err := NewIM().Group().GetGroup("test_group2") if err != nil { - t.Fatal(err) + handleError(t, "group.GetGroup", err) } if g != nil { t.Log(g.GetGroupId()) t.Log(g.GetName()) - t.Log(g.GetType()) + t.Log(g.GetGroupType()) t.Log(g.GetOwner()) t.Log(g.GetAvatar()) } @@ -1067,10 +1067,10 @@ func TestIm_Group_GetGroup(t *testing.T) { // 获取多个群详细资料 func TestIm_Group_GetGroups(t *testing.T) { groups, err := NewIM().Group().GetGroups([]string{ - "test_group1", + "test_group2", }) if err != nil { - t.Fatal(err) + handleError(t, "group.GetGroups", err) } for _, g := range groups { @@ -1079,7 +1079,7 @@ func TestIm_Group_GetGroups(t *testing.T) { } else { t.Log(g.GetGroupId()) t.Log(g.GetName()) - t.Log(g.GetType()) + t.Log(g.GetGroupType()) t.Log(g.GetOwner()) t.Log(g.GetAvatar()) } @@ -1088,12 +1088,12 @@ func TestIm_Group_GetGroups(t *testing.T) { // 添加群成员 func TestIm_Group_AddGroupMembers(t *testing.T) { - results, err := NewIM().Group().AddMembers("test_group1", []string{ + results, err := NewIM().Group().AddMembers("test_group2", []string{ test1, test2, }, true) if err != nil { - t.Fatal(err) + handleError(t, "group.AddMembers", err) } t.Log(results) @@ -1101,13 +1101,13 @@ func TestIm_Group_AddGroupMembers(t *testing.T) { // 删除群成员 func TestIm_Group_DeleteGroupMembers(t *testing.T) { - err := NewIM().Group().DeleteMembers("test_group1", []string{ + err := NewIM().Group().DeleteMembers("test_group2", []string{ test1, test2, test3, }, "测试删除", true) if err != nil { - t.Fatal(err) + handleError(t, "group.DeleteMembers", err) } t.Log("Success") @@ -1115,9 +1115,9 @@ func TestIm_Group_DeleteGroupMembers(t *testing.T) { // 转让群组 func TestIm_Group_ChangeGroupOwner(t *testing.T) { - err := NewIM().Group().ChangeGroupOwner("test_group1", test1) + err := NewIM().Group().ChangeGroupOwner("test_group2", test1) if err != nil { - t.Fatal(err) + handleError(t, "group.ChangeGroupOwner", err) } t.Log("Success") @@ -1127,16 +1127,16 @@ func TestIm_Group_ChangeGroupOwner(t *testing.T) { func TestIm_Group_UpdateGroup(t *testing.T) { g := group.NewGroup() g.SetName("测试群1") - g.SetType(group.TypePublic) + g.SetGroupType(group.TypePublic) g.SetMaxMemberNum(30) g.SetAvatar("http://www.baidu.com") - g.SetGroupId("test_group1") + g.SetGroupId("test_group2") g.SetIntroduction("这是一个测试群") g.SetNotification("这是一个测试群公告") err := NewIM().Group().UpdateGroup(g) if err != nil { - t.Fatal(err) + handleError(t, "group.UpdateGroup", err) } t.Log("Success") @@ -1144,13 +1144,13 @@ func TestIm_Group_UpdateGroup(t *testing.T) { // 查询用户在群组中的身份 func TestIm_Group_GetRolesInGroup(t *testing.T) { - ret, err := NewIM().Group().GetRolesInGroup("test_group1", []string{ + ret, err := NewIM().Group().GetRolesInGroup("test_group2", []string{ test1, test2, test3, }) if err != nil { - t.Fatal(err) + handleError(t, "group.GetRolesInGroup", err) } t.Log(ret) @@ -1160,7 +1160,7 @@ func TestIm_Group_GetRolesInGroup(t *testing.T) { func TestIm_Group_FetchGroupMembers(t *testing.T) { ret, err := NewIM().Group().FetchMembers("test_group1", 3, 2) if err != nil { - t.Fatal(err) + handleError(t, "group.FetchMembers", err) } t.Log(ret.HasMore) @@ -1171,6 +1171,24 @@ func TestIm_Group_FetchGroupMembers(t *testing.T) { } } +// 拉取群成员详细资料 +func TestIm_Group_PullGroupMembers(t *testing.T) { + err := NewIM().Group().PullMembers(&group.PullMembersArg{ + GroupId: "test_group2", + Limit: 3, + }, func(ret *group.FetchMembersRet) { + t.Log(ret.HasMore) + t.Log(ret.Total) + + for _, member := range ret.List { + t.Log(member.GetUserId()) + } + }) + if err != nil { + handleError(t, "group.PullMembers", err) + } +} + // 拉取App中的所有群组 func TestIm_Group_FetchGroupIds(t *testing.T) { ret, err := NewIM().Group().FetchGroupIds(3, 7964653962) @@ -1229,9 +1247,9 @@ func TestIm_Group_UpdateGroupMember(t *testing.T) { member.SetNameCard("这是一个测试名片信息") member.SetMsgFlag(group.MsgFlagAcceptAndNotify) - err := NewIM().Group().UpdateMember("test_group1", member) + err := NewIM().Group().UpdateMember("test_group2", member) if err != nil { - t.Fatal(err) + handleError(t, "group.UpdateMember", err) } t.Log("Success") @@ -1239,15 +1257,15 @@ func TestIm_Group_UpdateGroupMember(t *testing.T) { // 拉取用户所加入的群组 func TestIm_Group_FetchMemberGroups(t *testing.T) { - ret, err := NewIM().Group().FetchMemberGroups(group.FetchMemberGroupsArg{ + ret, err := NewIM().Group().FetchMemberGroups(&group.FetchMemberGroupsArg{ UserId: test1, Limit: 3, - Offset: 2, + Offset: 0, IsWithLiveRoomGroups: true, IsWithNoActiveGroups: true, }) if err != nil { - t.Fatal(err) + handleError(t, "group.FetchMemberGroups", err) } t.Log(ret.Total) @@ -1255,13 +1273,30 @@ func TestIm_Group_FetchMemberGroups(t *testing.T) { t.Log(ret.List) } +// 续拉取用户所加入的群组 +func TestIm_Group_PullMemberGroups(t *testing.T) { + err := NewIM().Group().PullMemberGroups(&group.PullMemberGroupsArg{ + UserId: test1, + Limit: 3, + IsWithLiveRoomGroups: true, + IsWithNoActiveGroups: true, + }, func(ret *group.FetchMemberGroupsRet) { + t.Log(ret.Total) + t.Log(ret.HasMore) + t.Log(ret.List) + }) + if err != nil { + handleError(t, "group.PullMemberGroups", err) + } +} + // 批量禁言 func TestIm_Group_ForbidSendMessage(t *testing.T) { err := NewIM().Group().ForbidSendMessage("test_group1", []string{ test1, }, 1000) if err != nil { - t.Fatal(err) + handleError(t, "group.ForbidSendMessage", err) } t.Log("Success") @@ -1269,7 +1304,7 @@ func TestIm_Group_ForbidSendMessage(t *testing.T) { // 取消禁言 func TestIm_Group_AllowSendMessage(t *testing.T) { - err := NewIM().Group().AllowSendMessage("test_group1", []string{ + err := NewIM().Group().AllowSendMessage("test_group2", []string{ test1, test2, }) @@ -1282,9 +1317,9 @@ func TestIm_Group_AllowSendMessage(t *testing.T) { // 获取被禁言群成员列表 func TestIm_Group_GetShuttedUpMembers(t *testing.T) { - shuttedUps, err := NewIM().Group().GetShuttedUpMembers("test_group1") + shuttedUps, err := NewIM().Group().GetShuttedUpMembers("test_group2") if err != nil { - t.Fatal(err) + handleError(t, "group.GetShuttedUpMembers", err) } t.Log(shuttedUps) @@ -1292,9 +1327,9 @@ func TestIm_Group_GetShuttedUpMembers(t *testing.T) { // 撤回单条群消息 func TestIm_Group_RevokeMessage(t *testing.T) { - err := NewIM().Group().RevokeMessage("test_group1", 100) + err := NewIM().Group().RevokeMessage("test_group2", 100) if err != nil { - t.Fatal(err) + handleError(t, "group.RevokeMessage", err) } t.Log("Success") @@ -1302,9 +1337,9 @@ func TestIm_Group_RevokeMessage(t *testing.T) { // 撤回多条群消息 func TestIm_Group_RevokeMessages(t *testing.T) { - results, err := NewIM().Group().RevokeMessages("test_group1", 100) + results, err := NewIM().Group().RevokeMessages("test_group2", 100) if err != nil { - t.Fatal(err) + handleError(t, "group.RevokeMessages", err) } t.Log(results) @@ -1312,9 +1347,9 @@ func TestIm_Group_RevokeMessages(t *testing.T) { // 设置成员未读消息计数 func TestIm_Group_SetMemberUnreadMsgNum(t *testing.T) { - err := NewIM().Group().SetMemberUnreadMsgNum("test_group1", test1, 100) + err := NewIM().Group().SetMemberUnreadMsgNum("test_group2", test1, 100) if err != nil { - t.Fatal(err) + handleError(t, "group.SetMemberUnreadMsgNum", err) } t.Log("Success") @@ -1322,9 +1357,9 @@ func TestIm_Group_SetMemberUnreadMsgNum(t *testing.T) { // 撤回指定用户发送的消息 func TestIm_Group_RevokeMemberMessages(t *testing.T) { - err := NewIM().Group().RevokeMemberMessages("test_group1", test1) + err := NewIM().Group().RevokeMemberMessages("test_group2", test1) if err != nil { - t.Fatal(err) + handleError(t, "group.RevokeMemberMessages", err) } t.Log("Success") @@ -1352,9 +1387,9 @@ func TestIm_Group_SendMessage(t *testing.T) { message.AtMembers(test2) message.ClearAtMembers() - ret, err := NewIM().Group().SendMessage("test_group1", message) + ret, err := NewIM().Group().SendMessage("test_group2", message) if err != nil { - t.Fatal(err) + handleError(t, "group.SendMessage", err) } t.Log(ret.MsgSeq) @@ -1363,9 +1398,9 @@ func TestIm_Group_SendMessage(t *testing.T) { // 在群组中发送普通消息 func TestIm_Group_SendNotification(t *testing.T) { - err := NewIM().Group().SendNotification("test_group1", "Hello welcome to the test group", test1) + err := NewIM().Group().SendNotification("test_group2", "Hello welcome to the test group", test1) if err != nil { - t.Fatal(err) + handleError(t, "group.SendNotification", err) } t.Log("Success") @@ -1375,7 +1410,7 @@ func TestIm_Group_SendNotification(t *testing.T) { func TestIm_Group_ImportGroup(t *testing.T) { g := group.NewGroup() g.SetName("测试群1") - g.SetType(group.TypePublic) + g.SetGroupType(group.TypePublic) g.SetMaxMemberNum(30) g.SetAvatar("http://www.baidu.com") g.SetIntroduction("这是一个测试群") @@ -1383,7 +1418,7 @@ func TestIm_Group_ImportGroup(t *testing.T) { groupId, err := NewIM().Group().ImportGroup(g) if err != nil { - t.Fatal(err) + handleError(t, "group.ImportGroup", err) } t.Log(groupId) @@ -1399,9 +1434,9 @@ func TestIm_Group_ImportMessages(t *testing.T) { Text: "Hello world", }) - results, err := NewIM().Group().ImportMessages("test_group1", message) + results, err := NewIM().Group().ImportMessages("test_group2", message) if err != nil { - t.Fatal(err) + handleError(t, "group.ImportMessages", err) } t.Log(results) @@ -1419,9 +1454,9 @@ func TestIm_Group_ImportMembers(t *testing.T) { members = append(members, member) } - results, err := NewIM().Group().ImportMembers("@TGS#25J4AWNHA", members...) + results, err := NewIM().Group().ImportMembers("test_group2", members...) if err != nil { - t.Fatal(err) + handleError(t, "group.ImportMembers", err) } t.Log(results) @@ -1429,14 +1464,24 @@ func TestIm_Group_ImportMembers(t *testing.T) { // 拉取群历史消息 func TestIm_Group_FetchMessages(t *testing.T) { - ret, err := NewIM().Group().FetchMessages("test_group1", 5) + ret, err := NewIM().Group().FetchMessages("test_group2", 5) if err != nil { - t.Fatal(err) + handleError(t, "group.FetchMessages", err) } t.Log(ret) } +// 续拉取群历史消息 +func TestIm_Group_PullMessages(t *testing.T) { + err := NewIM().Group().PullMessages("test_group2", 5, func(ret *group.FetchMessagesRet) { + t.Log(ret) + }) + if err != nil { + handleError(t, "group.PullMessages", err) + } +} + // 拉取会话列表 func TestIm_RecentContact_FetchSessions(t *testing.T) { ret, err := NewIM().RecentContact().FetchSessions(&recentcontact.FetchSessionsArg{