// 腾讯云im即时通信 package tencent import ( "encoding/json" "errors" "fmt" "github.com/tencentyun/tls-sig-api-v2-golang/tencentyun" "live/app/lib/client" "live/app/lib/config" "net/url" "strconv" ) const ( baseurl = "https://console.tim.qq.com/" ErrCodeSuc = 0 ErrSignTimeOut = 70001 action_useradd = "v4/im_open_login_svc/account_import" // 会员添加 action_userprofile = "v4/profile/portrait_set" // 会员资料信息修改 action_groupadd = "v4/group_open_http_svc/create_group" // 群组添加 action_groupdel = "v4/group_open_http_svc/destroy_group" // 群组解散 action_groupmessage = "v4/group_open_http_svc/send_group_system_notification" // 群组系统消息 ) type im struct { sdkAppId int identifier string expire int userBuf string key string sign string } var Im *im func init() { Im = &im{ sdkAppId: config.Config.Section("tencent").Key("sdkAppId").MustInt(), identifier: config.Config.Section("tencent").Key("identifier").String(), expire: config.Config.Section("tencent").Key("expire").MustInt(), userBuf: config.Config.Section("tencent").Key("userBuf").String(), key: config.Config.Section("tencent").Key("key").String(), } // 获取管理员签名串 Im.sign = Im.GetSign(Im.identifier) } // @Title 获取im签名串 // @Param userId string true "im会员id" func (i *im) GetSign(userId string) string { sign, _ := tencentyun.GenSig(i.sdkAppId, i.key, userId, i.expire) return sign } // @Title 添加会员到腾讯im // @Param userId string true "im会员id" // @Param nickName string true "会员昵称" // @Param faceUrl string true "头像链接地址" func (i *im) AddUser(userId, nickName, faceUrl string) error { jsonData, err := json.Marshal(map[string]string{ "Identifier": userId, "Nick": nickName, "FaceUrl": faceUrl, }) if err != nil { return err } return i.Exec(action_useradd, string(jsonData)) } type ProfileItem struct { Tag string // 修改的字段名 Value string // 修改的字段值 } // @Title 设置im会员资料 // @Param userId string true "im会员id" // @Param profileItems []ProfileItem] true "需要修改的信息" func (i *im) UserProfile(userId string, profileItems []ProfileItem) error { if len(profileItems) == 0 { return errors.New("修改的会员信息不能为空") } jsonData, err := json.Marshal(map[string]interface{}{ "From_Account": userId, "ProfileItem": profileItems, }) if err != nil { return err } return i.Exec(action_userprofile, string(jsonData)) } // @Title 创建直播群 // @Param userId string true "im会员id" // @Param name string true "直播群名称" // @Param groupId string true "直播群id" func (i *im) AddLiveGroup(userId, name, groupId string) error { jsonData, err := json.Marshal(map[string]string{ "Owner_Account": userId, "Type": "AVChatRoom", "Name": name, "GroupId": groupId, }) if err != nil { return err } return i.Exec(action_groupadd, string(jsonData)) } // @Title 解散直播群 // @Param userId string true "im会员id" // @Param name string true "直播群名称" // @Param groupId string true "直播群id" func (i *im) DelLiveGroup(groupId string) error { jsonData, err := json.Marshal(map[string]string{ "GroupId": groupId, }) if err != nil { return err } return i.Exec(action_groupdel, string(jsonData)) } // @Title 直播群发送消息 // @Param groupId string true "直播群id" // @Param message string true "消息内容" func (i *im) SendLiveGroupMessage(groupId, message string) error { jsonData, err := json.Marshal(map[string]interface{}{ "GroupId": groupId, "Content": message, }) if err != nil { return err } return i.Exec(action_groupmessage, string(jsonData)) } // @Title 获取公共参数 func (i *im) getPublicParam() string { sign, err := tencentyun.GenSig(i.sdkAppId, i.key, i.identifier, i.expire) if err != nil { return "" } return url.Values{ "sdkappid": []string{strconv.Itoa(i.sdkAppId)}, "identifier": []string{i.identifier}, "usersig": []string{sign}, "contenttype": []string{"json"}, }.Encode() } type imResult struct { ActionStatus string ErrorCode int ErrorInfo string } // @Title 执行请求 // @Param action string true "请求方法" // @Param data string true "请求数据" func (i *im) Exec(action string, data string) error { getUrl := fmt.Sprintf("%v%v?%v", baseurl, action, i.getPublicParam()) result, err := client.Request(client.Post, getUrl, data) if err != nil { return err } res := imResult{} err = json.Unmarshal(result, &res) if err != nil { return err } // 签名过期,重新签名 if res.ErrorCode == ErrSignTimeOut { i.sign = i.GetSign(i.identifier) return i.Exec(action, data) } // 调用失败 if res.ErrorCode != ErrCodeSuc { return errors.New(res.ErrorInfo) } // 调用成功 return nil }