初始化项目

This commit is contained in:
2022-09-27 11:31:23 +08:00
parent b4dc3c7305
commit 533ede4f66
54 changed files with 12011 additions and 25 deletions

1315
group/api.go Normal file

File diff suppressed because it is too large Load Diff

210
group/filter.go Normal file
View File

@@ -0,0 +1,210 @@
/**
* @Author: Echo
* @Author:1711788888@qq.com
* @Date: 2021/9/8 10:17
* @Desc: 群组响应过滤器
*/
package group
type (
// BaseInfoField 群基础信息字段
BaseInfoField string
// MemberInfoField 群成员信息字段
MemberInfoField string
)
const (
BaseFieldGroupId BaseInfoField = "GroupId" // 群组的唯一标识
BaseFieldType BaseInfoField = "Type" // 群组类型
BaseFieldName BaseInfoField = "Name" // 群组名称
BaseFieldIntroduction BaseInfoField = "Introduction" // 群组简介
BaseFieldNotification BaseInfoField = "Notification" // 群组公告
BaseFieldAvatar BaseInfoField = "FaceUrl" // 群组头像URL
BaseFieldOwner BaseInfoField = "Owner_Account" // 群主ID
BaseFieldCreateTime BaseInfoField = "CreateTime" // 群组的创建时间
BaseFieldInfoSeq BaseInfoField = "InfoSeq" // 群资料变更次数
BaseFieldLastInfoTime BaseInfoField = "LastInfoTime" // 群组最后一次信息变更时间
BaseFieldLastMsgTime BaseInfoField = "LastMsgTime" // 群组内最后发消息的时间
BaseFieldNextMsgSeq BaseInfoField = "NextMsgSeq" // 群内下一条消息的Seq
BaseFieldMemberNum BaseInfoField = "MemberNum" // 当前成员数量
BaseFieldMaxMemberNum BaseInfoField = "MaxMemberNum" // 最大成员数量
BaseFieldApplyJoinOption BaseInfoField = "ApplyJoinOption" // 申请加群选项
MemberFieldUserId MemberInfoField = "Member_Account" // 群成员ID
MemberFieldRole MemberInfoField = "Role" // 群内身份
MemberFieldJoinTime MemberInfoField = "JoinTime" // 入群时间
MemberFieldMsgSeq MemberInfoField = "MsgSeq" // 该成员当前已读消息Seq
MemberFieldMsgFlag MemberInfoField = "MsgFlag" // 消息接收选项
MemberFieldLastSendMsgTime MemberInfoField = "LastSendMsgTime" // 最后发送消息的时间
MemberFieldNameCard MemberInfoField = "NameCard" // 群名片
)
type Filter struct {
baseInfo map[string]bool
memberInfo map[string]bool
memberRole map[string]bool
groupCustomData map[string]bool
memberCustomData map[string]bool
}
// AddBaseInfoFilter 添加基础信息过滤器
func (f *Filter) AddBaseInfoFilter(field BaseInfoField) {
if f.baseInfo == nil {
f.baseInfo = make(map[string]bool)
}
f.baseInfo[string(field)] = true
}
// RemBaseInfoFilter 移除基础信息过滤器
func (f *Filter) RemBaseInfoFilter(field BaseInfoField) {
if f.baseInfo == nil {
return
}
delete(f.baseInfo, string(field))
}
// GetAllBaseInfoFilterFields 获取所有基础信息过滤器字段
func (f *Filter) GetAllBaseInfoFilterFields() (filters []string) {
if f.baseInfo == nil {
return
}
filters = make([]string, 0, len(f.baseInfo))
for k, _ := range f.baseInfo {
filters = append(filters, k)
}
return
}
// AddMemberInfoFilter 添加成员信息过滤器
func (f *Filter) AddMemberInfoFilter(field MemberInfoField) {
if f.memberInfo == nil {
f.memberInfo = make(map[string]bool)
}
f.memberInfo[string(field)] = true
}
// RemMemberInfoFilter 移除成员信息过滤器
func (f *Filter) RemMemberInfoFilter(field MemberInfoField) {
if f.memberInfo == nil {
return
}
delete(f.memberInfo, string(field))
}
// GetAllMemberInfoFilterFields 获取所有成员信息过滤器字段
func (f *Filter) GetAllMemberInfoFilterFields() (filters []string) {
if f.memberInfo == nil {
return
}
filters = make([]string, 0, len(f.memberInfo))
for k, _ := range f.memberInfo {
filters = append(filters, k)
}
return
}
// AddMemberRoleFilter 添加群成员角色过滤器
func (f *Filter) AddMemberRoleFilter(field string) {
if f.memberRole == nil {
f.memberRole = make(map[string]bool)
}
f.memberRole[field] = true
}
// RemMemberRoleFilter 移除群成员角色过滤器
func (f *Filter) RemMemberRoleFilter(field string) {
if f.memberRole == nil {
return
}
delete(f.memberRole, field)
}
// GetAllMemberRoleFilterValues 获取所有群成员角色过滤器值
func (f *Filter) GetAllMemberRoleFilterValues() (filters []string) {
if f.memberRole == nil {
return
}
filters = make([]string, 0, len(f.memberRole))
for k, _ := range f.memberRole {
filters = append(filters, k)
}
return
}
// AddGroupCustomDataFilter 添加群自定义数据过滤器
func (f *Filter) AddGroupCustomDataFilter(field string) {
if f.groupCustomData == nil {
f.groupCustomData = make(map[string]bool)
}
f.groupCustomData[field] = true
}
// RemGroupCustomDataFilter 移除群自定义数据过滤器
func (f *Filter) RemGroupCustomDataFilter(field string) {
if f.groupCustomData == nil {
return
}
delete(f.groupCustomData, field)
}
// GetAllGroupCustomDataFilterFields 获取所有群自定义数据过滤器字段
func (f *Filter) GetAllGroupCustomDataFilterFields() (filters []string) {
if f.groupCustomData == nil {
return
}
filters = make([]string, 0, len(f.groupCustomData))
for k, _ := range f.groupCustomData {
filters = append(filters, k)
}
return
}
// AddMemberCustomDataFilter 添加群成员自定义数据过滤器
func (f *Filter) AddMemberCustomDataFilter(field string) {
if f.memberCustomData == nil {
f.memberCustomData = make(map[string]bool)
}
f.memberCustomData[field] = true
}
// RemMemberCustomDataFilter 移除群成员自定义数据过滤器
func (f *Filter) RemMemberCustomDataFilter(field string) {
if f.memberCustomData == nil {
return
}
delete(f.memberCustomData, field)
}
// GetAllMemberCustomDataFilterFields 获取所有群成员自定义数据过滤器字段
func (f *Filter) GetAllMemberCustomDataFilterFields() (filters []string) {
if f.memberCustomData == nil {
return
}
filters = make([]string, 0, len(f.memberCustomData))
for k, _ := range f.memberCustomData {
filters = append(filters, k)
}
return
}

383
group/group.go Normal file
View File

@@ -0,0 +1,383 @@
/**
* @Author: Echo
* @Author:1711788888@qq.com
* @Date: 2021/9/7 17:11
* @Desc: TODO
*/
package group
import (
"time"
"git.echol.cn/loser/tencent-im/internal/core"
"git.echol.cn/loser/tencent-im/internal/enum"
)
var (
errNotSetGroupType = core.NewError(enum.InvalidParamsCode, "group type is not set")
errNotSetGroupName = core.NewError(enum.InvalidParamsCode, "group name is not set")
errGroupNameTooLong = core.NewError(enum.InvalidParamsCode, "group name is too long")
errInvalidGroupType = core.NewError(enum.InvalidParamsCode, "invalid group type")
errGroupIntroductionTooLong = core.NewError(enum.InvalidParamsCode, "group introduction is too long")
errGroupNotificationTooLong = core.NewError(enum.InvalidParamsCode, "group notification is too long")
)
type (
// Type 群类型
Type string
// ApplyJoinOption 申请加群处理方式
ApplyJoinOption string
// ShutUpStatus 全员禁言状态
ShutUpStatus string
)
const (
TypePublic Type = "Public" // Public陌生人社交群
TypePrivate Type = "Private" // Private即 Work好友工作群
TypeChatRoom Type = "ChatRoom" // ChatRoom即 Meeting会议群
TypeLiveRoom Type = "AVChatRoom" // AVChatRoom直播群
ApplyJoinOptionFreeAccess ApplyJoinOption = "FreeAccess" // 自由加入
ApplyJoinOptionNeedPermission ApplyJoinOption = "NeedPermission" // 需要验证
ApplyJoinOptionDisableApply ApplyJoinOption = "DisableApply" // 禁止加群
ShutUpStatusOn ShutUpStatus = "On" // 开启
ShutUpStatusOff ShutUpStatus = "Off" // 关闭
)
type Group struct {
err error
id string // 群ID
name string // 群名称
groupType Type // 群类型
owner string // 群主ID
introduction string // 群简介
notification string // 群公告
avatar string // 群头像
memberNum uint // 群成员数
maxMemberNum uint // 最大群成员数量
applyJoinOption string // 申请加群处理方式
members []*Member // 群成员
customData map[string]interface{} // 群自定义数据
createTime int64 // 群创建时间
lastInfoTime int64 // 最后群资料变更时间
lastMsgTime int64 // 群内最后一条消息的时间
nextMsgSeq int // 群内下一条消息的Seq
shutUpStatus string // 群全员禁言状态
}
func NewGroup(id ...string) *Group {
group := &Group{}
if len(id) > 0 {
group.SetGroupId(id[0])
}
return group
}
// SetGroupId 设置群ID
func (g *Group) SetGroupId(id string) {
g.id = id
}
// GetGroupId 获取群ID
func (g *Group) GetGroupId() string {
return g.id
}
// SetOwner 设置群主ID
func (g *Group) SetOwner(owner string) {
g.owner = owner
}
// GetOwner 获取群主ID
func (g *Group) GetOwner() string {
return g.owner
}
// SetName 设置群名称
func (g *Group) SetName(name string) {
g.name = name
}
// GetName 获取群名称
func (g *Group) GetName() string {
return g.name
}
// SetGroupType 设置群类型
func (g *Group) SetGroupType(groupType Type) {
g.groupType = groupType
}
// GetGroupType 获取群类型
func (g *Group) GetGroupType() Type {
return g.groupType
}
// SetIntroduction 设置群简介
func (g *Group) SetIntroduction(introduction string) {
g.introduction = introduction
}
// GetIntroduction 获取群简介
func (g *Group) GetIntroduction() string {
return g.introduction
}
// SetNotification 设置群公告
func (g *Group) SetNotification(notification string) {
g.notification = notification
}
// GetNotification 获取群公告
func (g *Group) GetNotification() string {
return g.notification
}
// SetAvatar 设置群头像
func (g *Group) SetAvatar(avatar string) {
g.avatar = avatar
}
// GetAvatar 获取群头像
func (g *Group) GetAvatar() string {
return g.avatar
}
// SetMaxMemberNum 设置最大群成员数量
func (g *Group) SetMaxMemberNum(maxMemberNum uint) {
g.maxMemberNum = maxMemberNum
}
// GetMaxMemberNum 获取最大群成员数量
func (g *Group) GetMaxMemberNum() uint {
return g.maxMemberNum
}
// GetMemberNum 获取群成员数
func (g *Group) GetMemberNum() uint {
return g.memberNum
}
// SetApplyJoinOption 设置申请加群处理方式
func (g *Group) SetApplyJoinOption(applyJoinOption ApplyJoinOption) {
g.applyJoinOption = string(applyJoinOption)
}
// GetApplyJoinOption 获取申请加群处理方式
func (g *Group) GetApplyJoinOption() string {
return g.applyJoinOption
}
// AddMembers 添加群成员
func (g *Group) AddMembers(member ...*Member) {
if g.members == nil {
g.members = make([]*Member, 0)
}
g.members = append(g.members, member...)
}
// SetMembers 设置群成员
func (g *Group) SetMembers(member ...*Member) {
if g.members != nil {
g.members = g.members[0:0]
}
g.AddMembers(member...)
}
// SetCustomData 设置自定义数据
func (g *Group) SetCustomData(name string, value interface{}) {
if g.customData == nil {
g.customData = make(map[string]interface{})
}
g.customData[name] = value
}
// GetCustomData 获取自定义数据
func (g *Group) GetCustomData(name string) (val interface{}, exist bool) {
if g.customData == nil {
return
}
val, exist = g.customData[name]
return
}
// GetAllCustomData 获取所有自定义数据
func (g *Group) GetAllCustomData() map[string]interface{} {
return g.customData
}
// GetMembers 获取群成员
func (g *Group) GetMembers() []*Member {
return g.members
}
// GetGroupCreateTime 获取群创建时间
func (g *Group) GetGroupCreateTime() time.Time {
return time.Unix(g.createTime, 0)
}
// GetLastInfoTime 获取最后群资料变更时间
func (g *Group) GetLastInfoTime() time.Time {
return time.Unix(g.lastInfoTime, 0)
}
// GetLastMsgTime 获取群内最后一条消息的时间
func (g *Group) GetLastMsgTime() time.Time {
return time.Unix(g.lastMsgTime, 0)
}
// GetNextMsgSeq 获取群内下一条消息的Seq
func (g *Group) GetNextMsgSeq() int {
return g.nextMsgSeq
}
// SetShutUpStatus 设置全员禁言状态
func (g *Group) SetShutUpStatus(shutUpStatus ShutUpStatus) {
g.shutUpStatus = string(shutUpStatus)
}
// GetShutUpStatus 获取群全员禁言状态
func (g *Group) GetShutUpStatus() string {
return g.shutUpStatus
}
// SetCreateTime 设置群组创建时间
func (g *Group) SetCreateTime(createTime int64) {
g.createTime = createTime
}
// GetCreateTime 获取群组创建时间
func (g *Group) GetCreateTime() int64 {
return g.createTime
}
// IsValid 检测用户是否有效
func (g *Group) IsValid() bool {
return g.err == nil
}
// GetError 获取异常错误
func (g *Group) GetError() error {
return g.err
}
// 设置异常错误
func (g *Group) setError(code int, message string) {
if code != enum.SuccessCode {
g.err = core.NewError(code, message)
}
}
// 检测创建错误
func (g *Group) checkCreateError() (err error) {
if err = g.checkTypeArgError(); err != nil {
return
}
if err = g.checkNameArgError(); err != nil {
return
}
if err = g.checkIntroductionArgError(); err != nil {
return
}
if err = g.checkNotificationArgError(); err != nil {
return
}
return
}
// 检测导入错误
func (g *Group) checkImportError() (err error) {
if err = g.checkTypeArgError(); err != nil {
return
}
if err = g.checkNameArgError(); err != nil {
return
}
if err = g.checkIntroductionArgError(); err != nil {
return
}
if err = g.checkNotificationArgError(); err != nil {
return
}
return
}
// 检测更新错误
func (g *Group) checkUpdateError() (err error) {
if err = g.checkNameArgError(); err != nil {
return
}
if err = g.checkIntroductionArgError(); err != nil {
return
}
if err = g.checkNotificationArgError(); err != nil {
return
}
return
}
// 检测群名称参数错误
func (g *Group) checkNameArgError() error {
if g.name == "" {
return errNotSetGroupName
}
if len(g.name) > 30 {
return errGroupNameTooLong
}
return nil
}
// 检测群类型参数错误
func (g *Group) checkTypeArgError() error {
if g.groupType == "" {
return errNotSetGroupType
}
switch Type(g.groupType) {
case TypePublic, TypePrivate, TypeChatRoom, TypeLiveRoom:
default:
return errInvalidGroupType
}
return nil
}
// 检测群简介参数错误
func (g *Group) checkIntroductionArgError() error {
if len(g.introduction) > 240 {
return errGroupIntroductionTooLong
}
return nil
}
// 检测群公告参数错误
func (g *Group) checkNotificationArgError() error {
if len(g.notification) > 300 {
return errGroupNotificationTooLong
}
return nil
}

160
group/member.go Normal file
View File

@@ -0,0 +1,160 @@
/**
* @Author: Echo
* @Author:1711788888@qq.com
* @Date: 2021/9/7 18:06
* @Desc: TODO
*/
package group
import (
"errors"
"time"
)
var errNotSetUserId = errors.New("member's userid is not set")
type (
// MsgFlag 消息接收选项
MsgFlag string
)
const (
MsgFlagAcceptAndNotify MsgFlag = "AcceptAndNotify" // 接收并提示
MsgFlagAcceptNotNotify MsgFlag = "AcceptNotNotify" // 接收不提示(不会触发 APNs 远程推送)
MsgFlagDiscard MsgFlag = "Discard" // 屏蔽群消息(不会向客户端推送消息)
)
type Member struct {
userId string // 成员ID
role string // 群内身份
joinTime int64 // 加入时间
nameCard string // 群名片
msgSeq int // 成员当前已读消息Seq
msgFlag MsgFlag // 消息接收选项
lastSendMsgTime int64 // 最后发送消息的时间
shutUpUntil *int64 // 需禁言时间单位为秒0表示取消禁言
unreadMsgNum int // 未读入群成员的未读消息计数
customData map[string]interface{} // 自定义数据
}
func NewMember(userId ...string) *Member {
member := &Member{}
if len(userId) > 0 {
member.SetUserId(userId[0])
}
return member
}
// SetUserId 设置群成员ID
func (m *Member) SetUserId(userId string) {
m.userId = userId
}
// GetUserId 获取群成员ID
func (m *Member) GetUserId() string {
return m.userId
}
// SetRole 设置群内身份
func (m *Member) SetRole(role string) {
m.role = role
}
// GetRole 获取群内身份
func (m *Member) GetRole() string {
return m.role
}
// SetJoinTime 设置加入时间
func (m *Member) SetJoinTime(joinTime time.Time) {
m.joinTime = joinTime.Unix()
}
// GetJoinTime 获取加入时间
func (m *Member) GetJoinTime() time.Time {
return time.Unix(m.joinTime, 0)
}
// SetNameCard 设置群名片
func (m *Member) SetNameCard(nameCard string) {
m.nameCard = nameCard
}
// GetNameCard 获取群名片
func (m *Member) GetNameCard() string {
return m.nameCard
}
// GetMsgSeq 获取成员当前已读消息Seq
func (m *Member) GetMsgSeq() int {
return m.msgSeq
}
// SetMsgFlag 设置消息接收选项
func (m *Member) SetMsgFlag(msgFlag MsgFlag) {
m.msgFlag = msgFlag
}
// GetMsgFlag 获取消息接收选项
func (m *Member) GetMsgFlag() MsgFlag {
return m.msgFlag
}
// SetShutUpUntil 设置需禁言时间单位为秒0表示取消禁言
func (m *Member) SetShutUpUntil(shutUpUntil int64) {
m.shutUpUntil = &shutUpUntil
}
// GetShutUpUntil 获取需禁言时间单位为秒0表示取消禁言
func (m *Member) GetShutUpUntil() int64 {
if m.shutUpUntil == nil {
return 0
} else {
return *m.shutUpUntil
}
}
// SetUnreadMsgNum 设置成员的未读消息计数
func (m *Member) SetUnreadMsgNum(unreadMsgNum int) {
m.unreadMsgNum = unreadMsgNum
}
// GetUnreadMsgNum 获取成员的未读消息计数
func (m *Member) GetUnreadMsgNum() int {
return m.unreadMsgNum
}
// SetCustomData 设置自定义数据
func (m *Member) SetCustomData(name string, value interface{}) {
if m.customData == nil {
m.customData = make(map[string]interface{})
}
m.customData[name] = value
}
// GetCustomData 获取自定义数据
func (m *Member) GetCustomData(name string) (val interface{}, exist bool) {
if m.customData == nil {
return
}
val, exist = m.customData[name]
return
}
// GetAllCustomData 获取所有自定义数据
func (m *Member) GetAllCustomData() map[string]interface{} {
return m.customData
}
// 检测参数错误
func (m *Member) checkError() (err error) {
if m.userId == "" {
return errNotSetUserId
}
return nil
}

221
group/message.go Normal file
View File

@@ -0,0 +1,221 @@
/**
* @Author: Echo
* @Author:1711788888@qq.com
* @Date: 2021/8/31 18:04
* @Desc: 私聊消息实体
*/
package group
import (
"errors"
"git.echol.cn/loser/tencent-im/internal/entity"
)
var (
errNotSetSender = errors.New("message's sender not set")
errNotSetSendTime = errors.New("message's send time not set")
)
type (
// MsgOnlineOnlyFlag 只发送在线成员标识
MsgOnlineOnlyFlag int
// MsgPriority 消息优先级
MsgPriority string
// MsgStatus 消息状态
MsgStatus int
)
const (
MsgOnlineOnlyFlagNo MsgOnlineOnlyFlag = 0 // 发送所有成员
MsgOnlineOnlyFlagYes MsgOnlineOnlyFlag = 1 // 仅发送在线成员
MsgPriorityHigh MsgPriority = "High" // 高优先级消息
MsgPriorityNormal MsgPriority = "Normal" // 普通优先级消息
MsgPriorityLow MsgPriority = "Low" // 低优先级消息
MsgPriorityLowest MsgPriority = "Lowest" // 最低优先级消息
MsgStatusNormal MsgStatus = 0 // 正常消息
MsgStatusInvalid MsgStatus = 1 // 被删除或者消息过期的消息
MsgStatusRevoked MsgStatus = 2 // 被撤回的消息
AtAllMembersFlag = "@all" // @所有成员的标识
)
type Message struct {
entity.Message
priority MsgPriority // 消息的优先级
onlineOnlyFlag MsgOnlineOnlyFlag // 仅发送在线成员标识
sendTime int64 // 消息发送时间
timestamp int64 // 消息时间戳UNIX 时间戳(单位:秒)
seq int // 消息序列号
status MsgStatus // 消息状态
customData interface{} // 自定义数据
sendControls map[string]bool // 发送消息控制
callbackControls map[string]bool // 禁用回调
atMembers map[string]bool // @用户
}
func NewMessage() *Message {
return &Message{}
}
// SetPriority 设置消息优先级
func (m *Message) SetPriority(priority MsgPriority) {
m.priority = priority
}
// GetPriority 获取消息优先级
func (m *Message) GetPriority() MsgPriority {
return m.priority
}
// SetCustomData 设置自定义数据
func (m *Message) SetCustomData(data interface{}) {
m.customData = data
}
// GetCustomData 获取自定义数据
func (m *Message) GetCustomData() interface{} {
return m.customData
}
// SetOnlineOnlyFlag 设置仅发送在线成员标识
func (m *Message) SetOnlineOnlyFlag(flag MsgOnlineOnlyFlag) {
m.onlineOnlyFlag = flag
}
// GetOnlineOnlyFlag 获取仅发送在线成员标识
func (m *Message) GetOnlineOnlyFlag() MsgOnlineOnlyFlag {
return m.onlineOnlyFlag
}
// SetSendTime 设置发送时间
func (m *Message) SetSendTime(sendTime int64) {
m.sendTime = sendTime
}
// GetSendTime 获取发送时间
func (m *Message) GetSendTime() int64 {
return m.sendTime
}
// GetStatus 获取消息状态
func (m *Message) GetStatus() MsgStatus {
return m.status
}
// SetForbidBeforeSendMsgCallback 设置禁止发消息前回调
func (m *Message) SetForbidBeforeSendMsgCallback() {
if m.callbackControls == nil {
m.callbackControls = make(map[string]bool, 0)
}
m.callbackControls["ForbidBeforeSendMsgCallback"] = true
}
// SetForbidAfterSendMsgCallback 设置禁止发消息后回调
func (m *Message) SetForbidAfterSendMsgCallback() {
if m.callbackControls == nil {
m.callbackControls = make(map[string]bool, 0)
}
m.callbackControls["ForbidAfterSendMsgCallback"] = true
}
// GetForbidCallbackControl 获取消息回调禁止开关
func (m *Message) GetForbidCallbackControl() (controls []string) {
if m.callbackControls != nil {
if n := len(m.callbackControls); n > 0 {
controls = make([]string, 0, n)
for k := range m.callbackControls {
controls = append(controls, k)
}
}
}
return
}
// SetNoUnread 设置该条消息不计入未读数
func (m *Message) SetNoUnread() {
if m.sendControls == nil {
m.sendControls = make(map[string]bool, 0)
}
m.sendControls["NoUnread"] = true
}
// SetNoLastMsg 设置该条消息不更新会话列表
func (m *Message) SetNoLastMsg() {
if m.sendControls == nil {
m.sendControls = make(map[string]bool, 0)
}
m.sendControls["NoLastMsg"] = true
}
// GetSendMsgControl 获取消息发送控制选项
func (m *Message) GetSendMsgControl() (controls []string) {
if m.sendControls != nil {
if n := len(m.sendControls); n > 0 {
controls = make([]string, 0, n)
for k := range m.sendControls {
controls = append(controls, k)
}
}
}
return
}
// AtMembers @某个成员
func (m *Message) AtMembers(userId ...string) {
if m.atMembers == nil {
m.atMembers = make(map[string]bool)
}
for _, id := range userId {
m.atMembers[id] = true
}
}
// AtAllMembers @所有成员
func (m *Message) AtAllMembers() {
m.AtMembers(AtAllMembersFlag)
}
// ClearAtMembers 清空所有的的@成员
func (m *Message) ClearAtMembers() {
m.atMembers = nil
}
// GetTimestamp 获取消息的时间戳
func (m *Message) GetTimestamp() int64 {
return m.timestamp
}
// 检测发送错误
func (m *Message) checkSendError() (err error) {
if err = m.CheckBodyArgError(); err != nil {
return
}
return
}
// 检测导入错误
func (m *Message) checkImportError() (err error) {
if m.GetSender() == "" {
return errNotSetSender
}
if m.sendTime == 0 {
return errNotSetSendTime
}
if err = m.CheckBodyArgError(); err != nil {
return
}
return
}

508
group/types.go Normal file
View File

@@ -0,0 +1,508 @@
/**
* @Author: Echo
* @Author:1711788888@qq.com
* @Date: 2021/5/29 17:43
* @Desc: 群组管理
*/
package group
import "git.echol.cn/loser/tencent-im/internal/types"
type (
// 拉取App中的所有群组请求
fetchGroupIdsReq struct {
Limit int `json:"Limit,omitempty"` // (选填)本次获取的群组 ID 数量的上限,不得超过 10000。如果不填默认为最大值 10000
Next int `json:"Next,omitempty"` // 选填群太多时分页拉取标志第一次填0以后填上一次返回的值返回的 Next 为0代表拉完了
Type string `json:"Type,omitempty"` // (选填)如果仅需要返回特定群组形态的群组,可以通过 Type 进行过滤,但此时返回的 TotalCount 的含义就变成了 App 中属于该群组形态的群组总数。不填为获取所有类型的群组。
}
// 拉取App中的所有群组响应
fetchGroupIdsResp struct {
types.ActionBaseResp
Next int `json:"Next"` // 分页拉取的标志
TotalCount int `json:"TotalCount"` // App 当前的群组总数。
GroupIdList []groupIdItem `json:"GroupIdList"` // 获取到的群组 ID 的集合
}
// FetchGroupIdsRet 拉取App中的所有群组ID返回
FetchGroupIdsRet struct {
Total int // App 当前的群组总数
Next int // 分页拉取的标志
HasMore bool // 是否还有更多数据
List []string // 群组ID列表
}
// FetchGroupsRet 拉取APP中的所有群返回
FetchGroupsRet struct {
Total int // App 当前的群组总数
Next int // 分页拉取的标志
HasMore bool // 是否还有更多数据
List []*Group // 群组列表
}
// PullGroupsArg 续拉取群信息(参数)
PullGroupsArg struct {
Limit int // 分页限制
Type Type // 群组类型
Filter *Filter // 过滤器
}
// 群ID
groupIdItem struct {
GroupId string `json:"GroupId"` // 群ID
}
// 自定义数据
customDataItem struct {
Key string `json:"Key"`
Value interface{} `json:"Value"`
}
// 创建群(请求)
createGroupReq struct {
OwnerUserId string `json:"Owner_Account,omitempty"` // (选填)群主 ID需是 已导入 的账号)。填写后自动添加到群成员中;如果不填,群没有群主
GroupId string `json:"GroupId,omitempty"` // (选填)为了使得群组 ID 更加简单,便于记忆传播,腾讯云支持 App 在通过 REST API 创建群组时 自定义群组 ID
Type Type `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 控制台 进行配置,详情请参阅 自定义字段
MemberList []*memberItem `json:"MemberList,omitempty"` // 选填初始群成员列表最多100个成员信息字段详情请参阅 群成员资料
}
// 创建群(响应)
createGroupResp struct {
types.ActionBaseResp
GroupId string `json:"GroupId"` // 群ID
}
// 群成员信息
memberItem struct {
UserId string `json:"Member_Account"` // 群成员ID
Role string `json:"Role,omitempty"` // 群内身份
JoinTime int64 `json:"JoinTime,omitempty"` // 入群时间
MsgSeq int `json:"MsgSeq,omitempty"` // 该成员当前已读消息Seq
MsgFlag string `json:"MsgFlag,omitempty"` // 消息接收选项
LastSendMsgTime int64 `json:"LastSendMsgTime,omitempty"` // 最后发送消息的时间
NameCard string `json:"NameCard,omitempty"` // 群名片
ShutUpUntil int64 `json:"ShutUpUntil"` // 禁言截至时间
UnreadMsgNum int `json:"UnreadMsgNum,omitempty"` // 待导入群成员的未读消息计数
AppMemberDefinedData []*customDataItem `json:"AppMemberDefinedData,omitempty"` // 群成员自定义数据
}
// 解散群(请求)
destroyGroupReq struct {
GroupId string `json:"GroupId"` // (必填)操作的群 ID
}
// 响应过滤器
responseFilter struct {
GroupBaseInfoFilter []string `json:"GroupBaseInfoFilter,omitempty"`
MemberInfoFilter []string `json:"MemberInfoFilter,omitempty"`
GroupCustomDataFilter []string `json:"AppDefinedDataFilter_Group,omitempty"`
MemberCustomDataFilter []string `json:"AppDefinedDataFilter_GroupMember,omitempty"`
SelfInfoFilter []string `json:"SelfInfoFilter,omitempty"`
}
// 获取群详细资料(请求)
getGroupsReq struct {
GroupIds []string `json:"GroupIdList"`
ResponseFilter *responseFilter `json:"ResponseFilter,omitempty"`
}
// 获取群详细资料(响应)
getGroupsResp struct {
types.ActionBaseResp
GroupInfos []*groupInfo `json:"GroupInfo"`
}
groupInfo struct {
GroupId string `json:"GroupId"`
ErrorCode int `json:"ErrorCode"`
ErrorInfo string `json:"ErrorInfo"`
Type Type `json:"Type"`
Name string `json:"Name"`
AppId int `json:"Appid"`
Introduction string `json:"Introduction"`
Notification string `json:"Notification"`
FaceUrl string `json:"FaceUrl"`
OwnerUserId string `json:"Owner_Account"`
CreateTime int64 `json:"CreateTime"`
LastInfoTime int64 `json:"LastInfoTime"`
LastMsgTime int64 `json:"LastMsgTime"`
NextMsgSeq int `json:"NextMsgSeq"`
MemberNum uint `json:"MemberNum"`
MaxMemberNum uint `json:"MaxMemberNum"`
ApplyJoinOption string `json:"ApplyJoinOption"`
ShutUpAllMember string `json:"ShutUpAllMember"`
AppDefinedData []customDataItem `json:"AppDefinedData"`
MemberList []memberItem `json:"MemberList"`
MemberInfo *memberItem `json:"SelfInfo,omitempty"` // 成员在群中的信息(仅在获取用户所加入的群组接口返回)
}
// 获取群成员详细资料(请求)
fetchMembersReq struct {
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"` // 获取到的群成员列表,其中包含了全部或者指定的群成员信息,成员信息字段详情请参阅 群成员资料
}
// FetchMembersRet 拉取群成员结果
FetchMembersRet struct {
Total int // 成员数量
HasMore bool // 是否还有更多数据
List []*Member // 成员列表
}
// PullMembersArg 续拉取群成员(参数)
PullMembersArg struct {
GroupId string // (必填)需要拉取成员信息的群组的 ID
Limit int // 选填一次最多获取多少个成员的资料不得超过6000。如果不填则获取群内全部成员的信息
Filter *Filter // (选填)返回过滤器
}
// 修改群基础资料(请求)
updateGroupReq struct {
GroupId string `json:"GroupId"`
Name string `json:"Name,omitempty"`
Introduction string `json:"Introduction,omitempty"`
Notification string `json:"Notification,omitempty"`
FaceUrl string `json:"FaceUrl,omitempty"`
MaxMemberNum uint `json:"MaxMemberNum,omitempty"`
ApplyJoinOption string `json:"ApplyJoinOption,omitempty"`
ShutUpAllMember string `json:"ShutUpAllMember,omitempty"`
AppDefinedData []customDataItem `json:"AppDefinedData,omitempty"`
}
// 添加群成员(请求)
addMembersReq struct {
GroupId string `json:"GroupId"`
Silence int `json:"Silence,omitempty"`
MemberList []addMemberItem `json:"MemberList"`
}
// 添加群成员(响应)
addMembersResp struct {
types.ActionBaseResp
MemberList []AddMembersResult `json:"MemberList"`
}
addMemberItem struct {
UserId string `json:"Member_Account"`
}
// AddMembersResult 添加群成员结果
AddMembersResult struct {
UserId string `json:"Member_Account"`
Result int `json:"Result"`
}
// 删除群成员(请求)
deleteMembersReq struct {
GroupId string `json:"GroupId"` // 必填操作的群ID
Silence int `json:"Silence"` // (选填)是否静默删人
Reason string `json:"Reason"` // (选填)踢出用户原因
UserIds []string `json:"MemberToDel_Account"` // (必填)待删除的群成员
}
// 修改群成员资料(请求)
updateMemberReq struct {
GroupId string `json:"GroupId"` // 必填群ID
UserId string `json:"Member_Account"` // 必填群成员ID
Role string `json:"Role,omitempty"` // (选填)群内身份
NameCard string `json:"NameCard,omitempty"` // (选填)群名片
MsgFlag string `json:"MsgFlag,omitempty"` // (选填)消息接收选项
ShutUpUntil *int64 `json:"ShutUpUntil,omitempty"` // (选填)禁言截至时间
AppMemberDefinedData []customDataItem `json:"AppMemberDefinedData,omitempty"` // (选填)群成员自定义数据
}
// FetchMemberGroupsArg 拉取用户所加入的群组(参数)
FetchMemberGroupsArg struct {
UserId string // 必填用户ID
Limit int // (选填)单次拉取的群组数量,如果不填代表所有群组
Offset int // (选填)从第多少个群组开始拉取
Type Type // (选填)拉取哪种群组类型
Filter *Filter // (选填)过滤器
IsWithNoActiveGroups bool // (选填)是否获取用户已加入但未激活的 Private即新版本中 Work好友工作群) 群信息
IsWithLiveRoomGroups bool // (选填)是否获取用户加入的 AVChatRoom(直播群)
}
// FetchMemberGroupsRet 拉取用户所加入的群组(返回)
FetchMemberGroupsRet struct {
Total int // 群组总数
HasMore bool // 是否还有更多数据
List []*Group // 列表
}
// PullMemberGroupsArg 续拉取用户所加入的群组(参数)
PullMemberGroupsArg struct {
UserId string // 必填用户ID
Limit int // (选填)单次拉取的群组数量,如果不填代表所有群组
Type Type // (选填)拉取哪种群组类型
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"` // (选填)从第多少个群组开始拉取
Type Type `json:"Type,omitempty"` // (选填)拉取哪种群组类型
WithHugeGroups int `json:"WithHugeGroups,omitempty"`
WithNoActiveGroups int `json:"WithNoActiveGroups,omitempty"`
ResponseFilter *responseFilter `json:"ResponseFilter,omitempty"` // (选填)响应过滤
}
// 拉取用户所加入的群组(响应)
fetchMemberGroupsResp struct {
types.ActionBaseResp
TotalCount int `json:"TotalCount"`
GroupList []groupInfo `json:"GroupIdList"`
}
// 获取
getRolesInGroupReq struct {
GroupId string `json:"GroupId"`
UserIds []string `json:"User_Account"`
}
getRolesInGroupResp struct {
types.ActionBaseResp
MemberRoleList []memberRole `json:"UserIdList"`
}
memberRole struct {
UserId string `json:"Member_Account"`
Role string `json:"Role"`
}
// 批量禁言(请求)
forbidSendMessageReq struct {
GroupId string `json:"GroupId"` // (必填)需要查询的群组 ID
UserIds []string `json:"Members_Account"` // 必填需要禁言的用户帐号最多支持500个帐号
ShutUpTime int64 `json:"ShutUpTime"` // 必填需禁言时间单位为秒为0时表示取消禁言4294967295为永久禁言。
}
// 获取被禁言群成员列表(请求)
getShuttedUpMembersReq struct {
GroupId string `json:"GroupId"` // (必填)需要获取被禁言成员列表的群组 ID
}
// 获取被禁言群成员列表(响应)
getShuttedUpMembersResp struct {
types.ActionBaseResp
ShuttedUpList []shuttedUp `json:"ShuttedUinList"`
}
// 被禁言信息
shuttedUp struct {
UserId string `json:"Member_Account"` // 用户ID
ShuttedUntil int64 `json:"ShuttedUntil"` // 禁言到的时间(使用 UTC 时间,即世界协调时间)
}
// 在群组中发送普通消息(请求)
sendMessageReq struct {
GroupId string `json:"GroupId"` // (必填)向哪个群组发送消息
Random uint32 `json:"Random"` // 必填无符号32位整数
MsgPriority string `json:"MsgPriority,omitempty"` // (选填)消息的优先级
FromUserId string `json:"From_Account,omitempty"` // (选填)消息来源帐号
MsgBody []*types.MsgBody `json:"MsgBody"` // (必填)消息体
OnlineOnlyFlag int `json:"MsgOnlineOnlyFlag,omitempty"` // 选填1表示消息仅发送在线成员默认0表示发送所有成员AVChatRoom(直播群)不支持该参数
SendMsgControl []string `json:"SendMsgControl,omitempty"` // 选填消息发送权限NoLastMsg 只对单条消息有效表示不更新最近联系人会话NoUnread 不计未读,只对单条消息有效。(如果该消息 MsgOnlineOnlyFlag 设置为1则不允许使用该字段。
ForbidCallbackControl []string `json:"ForbidCallbackControl,omitempty"` // (选填)消息回调禁止开关,只对单条消息有效
OfflinePushInfo *types.OfflinePushInfo `json:"OfflinePushInfo,omitempty"` // (选填)离线推送信息配置
CloudCustomData string `json:"CloudCustomData,omitempty"` // (选填)消息自定义数据(云端保存,会发送到对端,程序卸载重装后还能拉取到)
GroupAtInfo []atInfo `json:"GroupAtInfo,omitempty"` // (选填)@某个用户或者所有人
}
// 在群组中发送普通消息(响应)
sendMessageResp struct {
types.ActionBaseResp
MsgTime int `json:"MsgTime"`
MsgSeq int `json:"MsgSeq"`
}
// SendMessageRet 发送消息结果
SendMessageRet struct {
MsgSeq int // 消息唯一标识用于撤回。长度不超过50个字符
MsgTime int // 消息时间戳UNIX 时间戳
}
atInfo struct {
GroupAtAllFlag int `json:"GroupAtAllFlag"`
GroupAtUserId string `json:"GroupAt_Account,omitempty"`
}
// 在群组中发送系统通知(请求)
sendNotificationReq struct {
GroupId string `json:"GroupId"` // (必填)向哪个群组发送系统通知
Content string `json:"Content"` // (必填)系统通知的内容
UserIds []string `json:"ToMembers_Account,omitempty"` // (选填)接收者群成员列表,请填写接收者 UserID不填或为空表示全员下发
}
// 转让群主(请求)
changeGroupOwnerReq struct {
GroupId string `json:"GroupId"`
OwnerUserId string `json:"NewOwner_Account"`
}
msgSeqItem struct {
MsgSeq int `json:"MsgSeq"` // 请求撤回的消息seq
}
// 撤销消息(请求)
revokeMessagesReq struct {
GroupId string `json:"GroupId"` // 必填操作的群ID
MsgSeqList []msgSeqItem `json:"MsgSeqList"` // (必填)被撤回的消息 seq 列表
}
// 撤销消息(响应)
revokeMessagesResp struct {
types.ActionBaseResp
Results []revokeMessageResult `json:"Results"` // 撤销结果列表
}
// 撤销消息结果
revokeMessageResult struct {
MsgSeq int `json:"MsgSeq"` // 单个被撤回消息的 seq
RetCode int `json:"RetCode"` // 单个消息的被撤回结果0表示成功其它表示失败
}
// 导入群基础资料(请求)
importGroupReq struct {
OwnerUserId string `json:"Owner_Account,omitempty"` // (选填)群主 ID需是 已导入 的账号)。填写后自动添加到群成员中;如果不填,群没有群主
GroupId string `json:"GroupId,omitempty"` // (选填)为了使得群组 ID 更加简单,便于记忆传播,腾讯云支持 App 在通过 REST API 创建群组时 自定义群组 ID
Type Type `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"` // (选填)群组的创建时间
}
// 导入群基础资料(响应)
importGroupResp struct {
types.ActionBaseResp
GroupId string `json:"GroupId"` // 群ID
}
// 消息信息
messageItem struct {
FromUserId string `json:"From_Account"` // (必填)消息来源帐号
MsgBody []*types.MsgBody `json:"MsgBody"` // (必填)消息体
SendTime int64 `json:"SendTime"` // (必填)消息发送时间
Random uint32 `json:"Random,omitempty"` // 选填无符号32位整数
}
// 导入群消息(请求)
importMessagesReq struct {
GroupId string `json:"GroupId"` // 必填要导入消息的群ID
Messages []messageItem `json:"MsgList"` // (必填)导入的消息列表
}
// 导入群消息(响应)
importMessagesResp struct {
types.ActionBaseResp
Results []ImportMessagesResult `json:"ImportMsgResult"` // 导入群消息结果
}
// ImportMessagesResult 导入群消息结果
ImportMessagesResult struct {
MsgSeq int `json:"MsgSeq"` // 消息序列号,唯一标示一条消息
MsgTime int `json:"MsgTime"` // 消息的时间戳
Result int `json:"Result"` // 单条消息导入结果 0表示单条消息成功 10004表示单条消息发送时间无效 80001表示单条消息包含脏字拒绝存储此消息 80002表示为消息内容过长目前支持8000字节的消息请调整消息长度
}
// 导入群成员(请求)
importMembersReq struct {
GroupId string `json:"GroupId"` // 必填操作的群ID
Members []*memberItem `json:"MemberList"` // (必填)添加的群成员数组
}
// 导入群成员(响应)
importMembersResp struct {
types.ActionBaseResp
Results []ImportMemberResult `json:"MemberList"` // 添加的群成员结果
}
// ImportMemberResult 导入成员结果
ImportMemberResult struct {
UserId string `json:"Member_Account"` // 群成员帐号
Result int `json:"Result"` // 导入结果0表示失败1表示成功2表示已经是群成员
}
// 设置成员未读消息计数(请求)
setMemberUnreadMsgNumReq struct {
GroupId string `json:"GroupId"` // (必填)操作的群 ID
UserId string `json:"Member_Account"` // (必填)要操作的群成员
UnreadMsgNum int `json:"UnreadMsgNum"` // (必填)成员未读消息数
}
// 撤回指定用户发送的消息(请求)
revokeMemberMessagesReq struct {
GroupId string `json:"GroupId"` // (必填)要撤回消息的群 ID
UserId string `json:"Sender_Account"` // (必填)被撤回消息的发送者 ID
}
// 拉取群历史消息(请求)
fetchMessagesReq struct {
GroupId string `json:"GroupId"` // (必填)要拉取历史消息的群组 ID
ReqMsgSeq int `json:"ReqMsgSeq"` // 选填拉取消息的最大seq
ReqMsgNumber int `json:"ReqMsgNumber,omitempty"` // 必填拉取的历史消息的条数目前一次请求最多返回20条历史消息所以这里最好小于等于20
}
// 拉取群历史消息(响应)
fetchMessagesResp struct {
types.ActionBaseResp
GroupId string `json:"GroupId"`
IsFinished int `json:"IsFinished"`
RspMsgList []rspMsgItem `json:"RspMsgList"`
}
FetchMessagesRet struct {
IsFinished int // 是否返回了请求区间的全部消息 当成功返回了请求区间的全部消息时值为1; 当消息长度太长或者区间太大超过20导致无法返回全部消息时值为0; 当消息长度太长或者区间太大超过20且所有消息都过期时值为2
HasMore bool // 是否还有更多数据
NextSeq int // 下一个消息Seq
List []*Message // 列表
}
rspMsgItem struct {
FromUserId string `json:"From_Account"`
IsPlaceMsg int `json:"IsPlaceMsg"`
MsgBody []types.MsgBody `json:"MsgBody"`
MsgPriority int `json:"MsgPriority"`
MsgRandom uint32 `json:"MsgRandom"`
MsgSeq int `json:"MsgSeq"`
MsgTimeStamp int64 `json:"MsgTimeStamp"`
}
// 获取直播群在线人数(请求)
getOnlineMemberNumReq struct {
GroupId string `json:"GroupId"` // 必填操作的群ID
}
// 获取直播群在线人数(响应)
getOnlineMemberNumResp struct {
types.ActionBaseResp
OnlineMemberNum int `json:"OnlineMemberNum"` // 该群组的在线人数
}
)