|
@@ -0,0 +1,793 @@
|
|
|
+package quanshi
|
|
|
+
|
|
|
+import (
|
|
|
+ "encoding/json"
|
|
|
+ "errors"
|
|
|
+ "fmt"
|
|
|
+ "hongze/hongze_open_api/services/alarm_msg"
|
|
|
+ "hongze/hongze_open_api/utils"
|
|
|
+ "io/ioutil"
|
|
|
+ "net/http"
|
|
|
+ "strconv"
|
|
|
+ "strings"
|
|
|
+ "time"
|
|
|
+)
|
|
|
+
|
|
|
+const (
|
|
|
+ QsAppID = "ed1cc7c87c97089263fc899fbab193b0"
|
|
|
+ QsSecretKey = "d92b91265dbbc5e3af44edfb82503635"
|
|
|
+
|
|
|
+ //UserId = 9821234
|
|
|
+ //UserName = "hzhu@hzinsights.com"
|
|
|
+
|
|
|
+ UserId = 19896481
|
|
|
+ UserName = "pyan@hzinsights.com"
|
|
|
+ //UserId = 20804877
|
|
|
+ //UserName = "ljjiang@hzinsights.com"
|
|
|
+
|
|
|
+ //有效期24小时
|
|
|
+ Token = "8563737a3c6be564b91be8cab8881058"
|
|
|
+)
|
|
|
+
|
|
|
+// QsResp 全时数据返回结构体
|
|
|
+type QsResp struct {
|
|
|
+ Code int64 `json:"code"`
|
|
|
+ Data interface{} `json:"data"`
|
|
|
+ Msg string `json:"msg"`
|
|
|
+ RequestID string `json:"requestId"`
|
|
|
+ TimeStamp int64 `json:"timeStamp"`
|
|
|
+}
|
|
|
+
|
|
|
+// TokenResp 获取token的结构体
|
|
|
+type TokenResp struct {
|
|
|
+ CreateDate string `json:"createDate"`
|
|
|
+ CreateTime int64 `json:"createTime"`
|
|
|
+ CustomerCode string `json:"customerCode"`
|
|
|
+ Expire int64 `json:"expire"`
|
|
|
+ ProductID interface{} `json:"productId"`
|
|
|
+ Token string `json:"token"`
|
|
|
+ UserID int64 `json:"userId"`
|
|
|
+ UserName string `json:"userName"`
|
|
|
+}
|
|
|
+
|
|
|
+// getToken 获取token
|
|
|
+func getToken() (dataResp TokenResp, err error) {
|
|
|
+ defer func() {
|
|
|
+ if err != nil {
|
|
|
+ go alarm_msg.SendAlarmMsg("获取全时token失败;ERR:"+err.Error(), 3)
|
|
|
+ }
|
|
|
+ }()
|
|
|
+ user := new(QsUser)
|
|
|
+ user.UserId = UserId
|
|
|
+ user.UserName = UserName
|
|
|
+
|
|
|
+ postData, err := json.Marshal(user)
|
|
|
+ if err != nil {
|
|
|
+ utils.FileLog.Info("PostData json.Marshal Err:" + err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ utils.FileLog.Info("Qs PostData:" + string(postData))
|
|
|
+
|
|
|
+ postUrl := `https://events-openapi.quanshi.com/eventopenapi/token/create`
|
|
|
+ respData, err, errMsg := postCurl(postUrl, string(postData), 1, false)
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println("err:", err, ";errMsg:", errMsg)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ bodyBytes, _ := json.Marshal(respData.Data)
|
|
|
+ err = json.Unmarshal(bodyBytes, &dataResp)
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+// postCurl post请求上海接口
|
|
|
+func postCurl(urlStr string, postDataStr string, num int, isNeedToken bool) (respData QsResp, err error, errMsg string) {
|
|
|
+ logMsg := ``
|
|
|
+ utils.FileLog.Info("Qs PostData:" + postDataStr)
|
|
|
+ client := &http.Client{}
|
|
|
+ req, err := http.NewRequest("POST", urlStr, strings.NewReader(postDataStr))
|
|
|
+ if err != nil {
|
|
|
+ // handle error
|
|
|
+ }
|
|
|
+ nonce := utils.GetRandStringNoSpecialChar(32)
|
|
|
+ curTime := time.Now().Local().UnixNano() / 1e6
|
|
|
+ curTimeStr := strconv.FormatInt(curTime, 10)
|
|
|
+ checkSumStr := QsSecretKey + nonce + curTimeStr
|
|
|
+ checkSum := utils.Sha1(checkSumStr)
|
|
|
+
|
|
|
+ if isNeedToken {
|
|
|
+ token, tmpErr := GetQsToken(false)
|
|
|
+ if tmpErr != nil {
|
|
|
+ err = tmpErr
|
|
|
+ }
|
|
|
+ req.Header.Set("token", token)
|
|
|
+ }
|
|
|
+ req.Header.Set("AppKey", QsAppID)
|
|
|
+ req.Header.Set("Content-Type", "application/json")
|
|
|
+ req.Header.Set("accept", "application/json")
|
|
|
+ req.Header.Set("Nonce", nonce)
|
|
|
+ req.Header.Set("CurTime", curTimeStr)
|
|
|
+ req.Header.Set("CheckSum", checkSum)
|
|
|
+
|
|
|
+ resp, err := client.Do(req)
|
|
|
+ if err != nil {
|
|
|
+ logMsg = fmt.Sprint("post err; request:", postDataStr, "; errMsg:", err.Error())
|
|
|
+ utils.FileLog.Info(logMsg)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ defer resp.Body.Close()
|
|
|
+
|
|
|
+ body, err := ioutil.ReadAll(resp.Body)
|
|
|
+ if err != nil {
|
|
|
+ logMsg = fmt.Sprint("post err; request:", postDataStr, "; errMsg:", err.Error())
|
|
|
+ utils.FileLog.Info(logMsg)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ utils.FileLog.Info(fmt.Sprint("Qs Post Result", ";url:", urlStr, ";\nparams:", postDataStr, ";\nresponse:", string(body)))
|
|
|
+ err = json.Unmarshal(body, &respData)
|
|
|
+ if err != nil {
|
|
|
+ utils.FileLog.Info("post Err:", err.Error(), ";url:", urlStr, ";params:", postDataStr, ";response:", string(body))
|
|
|
+ err = errors.New("Unmarshal Err:" + err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ //如果是token失效,同时只是第一次请求(没有尝试强制刷新token,那么重新请求)
|
|
|
+ if respData.Code == 4100 && num <= 0 {
|
|
|
+ //token失效
|
|
|
+ _, tmpErr := refreshAccessToken()
|
|
|
+ if tmpErr != nil {
|
|
|
+ err = tmpErr
|
|
|
+ }
|
|
|
+ num++
|
|
|
+ return postCurl(urlStr, postDataStr, num, isNeedToken)
|
|
|
+ } else if respData.Code != 200 {
|
|
|
+ utils.FileLog.Info(fmt.Sprint("post data err", ";url:", urlStr, ";params:", postDataStr, ";response:", string(body)))
|
|
|
+ err = errors.New(respData.Msg)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+// refreshAccessToken 强制刷新获取accessToken
|
|
|
+func refreshAccessToken() (token string, err error) {
|
|
|
+ defer func() {
|
|
|
+ if err != nil {
|
|
|
+ go alarm_msg.SendAlarmMsg("刷新上海的token失败;ERR:"+err.Error(), 3)
|
|
|
+ //go utils.SendEmail(utils.APPNAME+"刷新上海的token失败:"+time.Now().Format("2006-01-02 15:04:05"), err.Error(), utils.EmailSendToUsers)
|
|
|
+ }
|
|
|
+ }()
|
|
|
+ tokenResp, tmpErr := getToken()
|
|
|
+ if tmpErr != nil {
|
|
|
+ err = tmpErr
|
|
|
+ return
|
|
|
+ }
|
|
|
+ token = tokenResp.Token
|
|
|
+
|
|
|
+ //token存入redis
|
|
|
+ err = utils.Rc.Put("QS_TOKEN", token, time.Duration(tokenResp.Expire-600)*time.Second)
|
|
|
+ if err != nil {
|
|
|
+ go alarm_msg.SendAlarmMsg("获取全时的token失败;全时token存入redis失败,ERR:"+err.Error(), 3)
|
|
|
+ }
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+type QsUser struct {
|
|
|
+ UserId int `json:"userId"`
|
|
|
+ UserName string `json:"userName"`
|
|
|
+}
|
|
|
+
|
|
|
+// GetQsToken 获取全时的token
|
|
|
+func GetQsToken(isRefresh bool) (token string, err error) {
|
|
|
+ defer func() {
|
|
|
+ if err != nil {
|
|
|
+ go alarm_msg.SendAlarmMsg("获取上海的token失败,ERR:"+err.Error(), 3)
|
|
|
+ //go utils.SendEmail(utils.APPNAME+"获取上海的token失败:"+time.Now().Format("2006-01-02 15:04:05"), err.Error(), utils.EmailSendToUsers)
|
|
|
+ }
|
|
|
+ }()
|
|
|
+ token, redisErr := utils.Rc.RedisString("QS_TOKEN")
|
|
|
+ //如果从redis中accessToken 获取失败或者token为空了,再或者需要强制刷新了,那么重新获取accessToken
|
|
|
+ if redisErr != nil || token == `` || isRefresh {
|
|
|
+ return refreshAccessToken()
|
|
|
+ }
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+// EventListParam 获取会议列表请求参数据结构
|
|
|
+type EventListParam struct {
|
|
|
+ //Token string `json:"token"`
|
|
|
+ //HostId int `description:"主持人ID 如果主持人ID为空,则查询所有创建的直播会议" json:"hostId"`
|
|
|
+ StartTime int64 `description:"查询开始时间(时间戳,单位秒)默认为当前时间" json:"startTime"`
|
|
|
+ EndTime int64 `description:"查询结束时间(时间戳,单位秒)默认为当前时间之后3个月" json:"endTime"`
|
|
|
+ Limit int `description:"每页返回多少条记录,默认值10" json:"limit"`
|
|
|
+}
|
|
|
+
|
|
|
+// EventListResp 会议列表返回数据结构
|
|
|
+type EventListResp struct {
|
|
|
+ AllowH323 int64 `json:"allowH323" description:""`
|
|
|
+ AttendeeJoinURL string `json:"attendeeJoinUrl" description:"参会人入会链接"`
|
|
|
+ AudienceUnionURL string `json:"audienceUnionUrl" description:"观众落地页链接"`
|
|
|
+ BillingCode string `json:"billingCode" description:"云会议计费BC"`
|
|
|
+ CallbackURL string `json:"callbackUrl" description:"会议回调地址"`
|
|
|
+ ConfNodeType int64 `json:"confNodeType" description:"会议节点类型 0: 保密会议,1: 标准会议(默认)"`
|
|
|
+ ConferenceID string `json:"conferenceId" description:"云会议ID"`
|
|
|
+ CustomStr interface{} `json:"customStr" description:"自定义内容"`
|
|
|
+ CustomerCode string `json:"customerCode" description:"客户编码"`
|
|
|
+ EndDate string `json:"endDate" description:"会议结束时间(格式:年月日时分秒)"`
|
|
|
+ EndTime int64 `json:"endTime" description:"会议结束时间(时间戳,单位秒)"`
|
|
|
+ EventForm int64 `json:"eventForm" description:"会议形式 1: 电话活动,3: 网络会议,7: 大型直播活动"`
|
|
|
+ EventID int64 `json:"eventId" description:"直播会议ID"`
|
|
|
+ EventWatchword string `json:"eventWatchword" description:""`
|
|
|
+ GuestJoinURL string `json:"guestJoinUrl" description:"嘉宾入会链接"`
|
|
|
+ HostID int64 `json:"hostId" description:"主持人ID"`
|
|
|
+ HostJoinURL string `json:"hostJoinUrl" description:"创建人入会链接"`
|
|
|
+ HostName string `json:"hostName" description:"主持人姓名"`
|
|
|
+ JoinHostURL string `json:"joinHostUrl" description:"助理主持人链接"`
|
|
|
+ JointHostURL string `json:"jointHostUrl" description:""`
|
|
|
+ Labels []string `json:"labels" description:"活动标签"`
|
|
|
+ Length int64 `json:"length" description:"会议时长(时间戳,单位分钟)"`
|
|
|
+ LiveCover string `json:"liveCover" description:"活动间(直播)封面图URL"`
|
|
|
+ LiveLag int64 `json:"liveLag" description:"直播延迟设置(0:正常延迟,1:无延迟,默认0)"`
|
|
|
+ LiveOpenFlag int64 `json:"liveOpenFlag" description:"开启实时互动直播 0: 否, 1: 是(默认值0,仅针对eventForm=3有效)"`
|
|
|
+ LivePullURL string `json:"livePullUrl" description:"直播链接"`
|
|
|
+ LiveScreen int64 `json:"liveScreen" description:"云活动手机屏幕显示方式,0:横屏(默认)1:竖屏"`
|
|
|
+ ManualService int64 `json:"manualService" description:"是否需要项目经理开关,1:开启,2:关闭,默认2"`
|
|
|
+ ModifyDate string `json:"modifyDate" description:""`
|
|
|
+ ModifyTime int64 `json:"modifyTime" description:""`
|
|
|
+ OpenWatchword int64 `json:"openWatchword" description:""`
|
|
|
+ Pcode1 string `json:"pcode1" description:""`
|
|
|
+ Pcode2 string `json:"pcode2" description:""`
|
|
|
+ StartDate string `json:"startDate" description:"会议开始时间(格式:年月日时分秒)"`
|
|
|
+ StartTime int64 `json:"startTime" description:"会议开始时间(时间戳,单位秒)"`
|
|
|
+ Summary string `json:"summary" description:"会议概要"`
|
|
|
+ Title string `json:"title" description:"会议主题"`
|
|
|
+ WcallURL string `json:"wcallUrl" description:"云会议电话会议链接"`
|
|
|
+ WebMeetURL string `json:"webMeetUrl" description:""`
|
|
|
+ WebRTCUrl string `json:"webRTCUrl" description:"webRTC 入会链接"`
|
|
|
+}
|
|
|
+
|
|
|
+// GetQsEventList 获取会议列表
|
|
|
+func GetQsEventList(createTime, endTime time.Time) (dataResp []EventListResp, err error) {
|
|
|
+ params := EventListParam{
|
|
|
+ //HostId: 0,
|
|
|
+ StartTime: createTime.Unix(),
|
|
|
+ EndTime: endTime.Unix(),
|
|
|
+ Limit: 10,
|
|
|
+ }
|
|
|
+
|
|
|
+ postData, err := json.Marshal(params)
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println("PostData json.Marshal Err:" + err.Error())
|
|
|
+ utils.FileLog.Info("PostData json.Marshal Err:" + err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ fmt.Println("postData:" + string(postData))
|
|
|
+ utils.FileLog.Info("Qs PostData:" + string(postData))
|
|
|
+
|
|
|
+ postUrl := `https://events-openapi.quanshi.com/eventopenapi/event/list`
|
|
|
+ respData, err, errMsg := postCurl(postUrl, string(postData), 1, true)
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println("err:", err, ";errMsg:", errMsg)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ bodyBytes, _ := json.Marshal(respData.Data)
|
|
|
+ err = json.Unmarshal(bodyBytes, &dataResp)
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+// EventCreateParams 全时会议创建请求参数据结构
|
|
|
+type EventCreateParams struct {
|
|
|
+ HostId int64 `json:"hostId" description:"主持人ID"`
|
|
|
+ Title string `json:"title" description:"会议主题, 主题不能超过30个字"`
|
|
|
+ StartTime int64 `json:"startTime" description:"开始时间(时间戳,单位秒)"`
|
|
|
+ Length int `json:"length" description:"会议时长(单位分钟)会议时长的取值只接受30的倍数,并且最大为720分钟. 如果填写的时长不符合要求,系统自动取最接近的分钟数. 例如输入时长40分钟,则系统自动转换成30分钟;而输入时长50分钟,系统会调整为60分钟"`
|
|
|
+ EventForm int `json:"eventForm" description:"会议形式 1: 电话会议,3: 网络会议,7: 大型直播活动;电话会议 :通过电话的方式召开的活动,可进行声音的实时互动,无资料共享。;网络会议:适用于有资料共享的实时互动活动,所有参会用户都可查看共享的资料,可选择电话/网络语音进行互动讨论。;大型直播活动:适用于宣讲路演、带货推广、年会、在线发布会,所有参会用户可通过网页/小程序观看直播,可通过文字或举手方式进行互动讨论。"`
|
|
|
+ CallbackUrl string `json:"callbackUrl" description:"会议回调地址"`
|
|
|
+ JoinLimit int `json:"joinLimit" description:"观众直播入会限制 0: 公开, 1: 白名单(默认, 并且非白名单(电话入会)拒绝入会)"`
|
|
|
+ ManualService int `json:"manualService" description:"是否需要项目经理开关,1: 开启,2: 关闭(默认1)"`
|
|
|
+}
|
|
|
+
|
|
|
+// EventCreateResp 全时会议创建 返回 参数据结构
|
|
|
+type EventCreateResp struct {
|
|
|
+ AttendeeJoinURL string `json:"attendeeJoinUrl" description:"参会人入会链接"`
|
|
|
+ AudienceUnionURL string `json:"audienceUnionUrl" description:"观众落地页链接"`
|
|
|
+ BillingCode string `json:"billingCode" description:"云会议计费BC"`
|
|
|
+ CallbackURL string `json:"callbackUrl" description:"会议回调地址"`
|
|
|
+ ConfNodeType int64 `json:"confNodeType" description:"会议节点类型 0: 保密会议,1: 标准会议(默认)"`
|
|
|
+ ConferenceID string `json:"conferenceId" description:"云会议ID"`
|
|
|
+ CustomStr string `json:"customStr" description:"自定义内容"`
|
|
|
+ EventForm int64 `json:"eventForm" description:"会议形式 1: 电话活动,3: 网络会议,7: 大型直播活动"`
|
|
|
+ EventID int64 `json:"eventId" description:"直播会议ID"`
|
|
|
+ GuestJoinURL string `json:"guestJoinUrl" description:"嘉宾入会链接"`
|
|
|
+ HostID int64 `json:"hostId" description:"主持人ID"`
|
|
|
+ HostJoinURL string `json:"hostJoinUrl" description:"主持人入会链接"`
|
|
|
+ JoinHostURL string `json:"joinHostUrl" description:"助理主持人链接"`
|
|
|
+ JoinLimit int64 `json:"joinLimit" description:"观众直播入会限制 0: 公开, 1: 白名单(默认值1, 并且非白名单(电话入会)拒绝入会)"`
|
|
|
+ Labels []string `json:"labels" description:"活动标签"`
|
|
|
+ Length int64 `json:"length" description:"会议时长(单位分钟);会议时长的取值只接受30的倍数,并且最大为720分钟. 如果填写的时长不符合要求,系统自动取最接近的分钟数. 例如输入时长40分钟,则系统自动转换成30分钟;而输入时长50分钟,系统会调整为60分钟"`
|
|
|
+ LiveCover string `json:"liveCover" description:"会议封面图URL 尺寸1280x720px 图片小于2MB(jpg、png)"`
|
|
|
+ LiveLag int64 `json:"liveLag" description:"直播延迟设置 0: 正常延迟,1: 无延迟(默认0)"`
|
|
|
+ LiveOpenFlag int64 `json:"liveOpenFlag" description:"开启实时互动直播 0: 否, 1: 是(默认值0,仅针对eventForm=3有效)"`
|
|
|
+ LiveScreen int64 `json:"liveScreen" description:"云活动手机屏幕显示方式,0: 横屏,1: 竖屏(默认0)"`
|
|
|
+ ManualService int64 `json:"manualService" description:"是否需要项目经理开关,1: 开启,2: 关闭(默认2)"`
|
|
|
+ Pcode1 string `json:"pcode1" description:"主持人入会密码"`
|
|
|
+ Pcode2 string `json:"pcode2" description:"参会人入会密码"`
|
|
|
+ StartTime int64 `json:"startTime" description:"会议开始时间(时间戳,单位秒)"`
|
|
|
+ Summary string `json:"summary" description:"会议概要"`
|
|
|
+ Title string `json:"title" description:"会议主题"`
|
|
|
+ Wcallurl string `json:"wcallurl" description:"云会议电话会议链接"`
|
|
|
+}
|
|
|
+
|
|
|
+// QsEventCreate 全时会议创建
|
|
|
+func QsEventCreate(title string, meetingTime, eventForm int, startTime time.Time, callbackUrl string) (dataResp EventCreateResp, err error) {
|
|
|
+ defer func() {
|
|
|
+ if err != nil {
|
|
|
+ go alarm_msg.SendAlarmMsg("创建全时会议失败;ERR:"+err.Error(), 3)
|
|
|
+ }
|
|
|
+ }()
|
|
|
+ isManualService := 2 //是否需要项目经理提醒(默认不需要)
|
|
|
+ joinLimit := 0
|
|
|
+ params := EventCreateParams{
|
|
|
+ HostId: UserId,
|
|
|
+ Title: title,
|
|
|
+ StartTime: startTime.Unix(),
|
|
|
+ Length: meetingTime,
|
|
|
+ EventForm: eventForm,
|
|
|
+ CallbackUrl: callbackUrl,
|
|
|
+ JoinLimit: joinLimit,
|
|
|
+ ManualService: isManualService,
|
|
|
+ }
|
|
|
+ postData, err := json.Marshal(params)
|
|
|
+ if err != nil {
|
|
|
+ utils.FileLog.Info("PostData json.Marshal Err:" + err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ postUrl := `https://events-openapi.quanshi.com/eventopenapi/event/create`
|
|
|
+ respData, err, errMsg := postCurl(postUrl, string(postData), 1, true)
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println("err:", err, ";errMsg:", errMsg)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ bodyBytes, _ := json.Marshal(respData.Data)
|
|
|
+ err = json.Unmarshal(bodyBytes, &dataResp)
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+// EventCancelParams 全时会议取消请求参数据结构
|
|
|
+type EventCancelParams struct {
|
|
|
+ EventId int64 `json:"eventId" description:"全时会议id"`
|
|
|
+}
|
|
|
+
|
|
|
+// QsEventCancel 取消全时会议
|
|
|
+func QsEventCancel(eventId int) (err error) {
|
|
|
+ defer func() {
|
|
|
+ if err != nil {
|
|
|
+ go alarm_msg.SendAlarmMsg("取消全时会议失败;ERR:"+err.Error(), 3)
|
|
|
+ }
|
|
|
+ }()
|
|
|
+ params := EventCancelParams{
|
|
|
+ EventId: int64(eventId),
|
|
|
+ }
|
|
|
+
|
|
|
+ postData, err := json.Marshal(params)
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println("PostData json.Marshal Err:" + err.Error())
|
|
|
+ utils.FileLog.Info("PostData json.Marshal Err:" + err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ postUrl := `https://events-openapi.quanshi.com/eventopenapi/event/cancel`
|
|
|
+ _, err, errMsg := postCurl(postUrl, string(postData), 1, true)
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println("err:", err, ";errMsg:", errMsg)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+// EventUpdateParams 全时会议修改请求参数据结构
|
|
|
+type EventUpdateParams struct {
|
|
|
+ Title string `json:"title"`
|
|
|
+ StartTime int64 `json:"startTime"`
|
|
|
+ Length int `json:"length"`
|
|
|
+ EventId int64 `json:"eventId"`
|
|
|
+ UseWaitingRoom int64 `json:"useWaitingRoom"`
|
|
|
+}
|
|
|
+
|
|
|
+// EventUpdateResp 全时会议修改 返回 数据结构
|
|
|
+type EventUpdateResp struct {
|
|
|
+ AttendeeJoinURL string `json:"attendeeJoinUrl"`
|
|
|
+ AudienceUnionURL string `json:"audienceUnionUrl"`
|
|
|
+ BillingCode string `json:"billingCode"`
|
|
|
+ CallbackURL string `json:"callbackUrl"`
|
|
|
+ ConfNodeType int64 `json:"confNodeType"`
|
|
|
+ ConferenceID string `json:"conferenceId"`
|
|
|
+ CustomStr string `json:"customStr"`
|
|
|
+ EventForm int64 `json:"eventForm"`
|
|
|
+ EventID int64 `json:"eventId"`
|
|
|
+ GuestJoinURL string `json:"guestJoinUrl"`
|
|
|
+ HostID int64 `json:"hostId"`
|
|
|
+ HostJoinURL string `json:"hostJoinUrl"`
|
|
|
+ JoinHostURL string `json:"joinHostUrl"`
|
|
|
+ JoinLimit int64 `json:"joinLimit"`
|
|
|
+ Labels []string `json:"labels"`
|
|
|
+ Length int64 `json:"length"`
|
|
|
+ LiveCover string `json:"liveCover"`
|
|
|
+ LiveLag int64 `json:"liveLag"`
|
|
|
+ LiveOpenFlag int64 `json:"liveOpenFlag"`
|
|
|
+ LiveScreen int64 `json:"liveScreen"`
|
|
|
+ ManualService int64 `json:"manualService"`
|
|
|
+ Pcode1 string `json:"pcode1"`
|
|
|
+ Pcode2 string `json:"pcode2"`
|
|
|
+ StartTime int64 `json:"startTime"`
|
|
|
+ Summary string `json:"summary"`
|
|
|
+ Title string `json:"title"`
|
|
|
+ Wcallurl string `json:"wcallurl"`
|
|
|
+}
|
|
|
+
|
|
|
+// QsEventUpdate 全时会议修改
|
|
|
+func QsEventUpdate(eventId, length int, title string, startTime time.Time) (dataResp EventUpdateResp, err error) {
|
|
|
+ params := EventUpdateParams{
|
|
|
+ EventId: int64(eventId),
|
|
|
+ Title: title,
|
|
|
+ StartTime: startTime.Unix(),
|
|
|
+ Length: length,
|
|
|
+ }
|
|
|
+
|
|
|
+ postData, err := json.Marshal(params)
|
|
|
+ if err != nil {
|
|
|
+ utils.FileLog.Info("PostData json.Marshal Err:" + err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ postUrl := `https://events-openapi.quanshi.com/eventopenapi/event/update`
|
|
|
+ respData, err, errMsg := postCurl(postUrl, string(postData), 1, true)
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println("err:", err, ";errMsg:", errMsg)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ bodyBytes, _ := json.Marshal(respData.Data)
|
|
|
+ err = json.Unmarshal(bodyBytes, &dataResp)
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+// UserEmailParams 全时 根据邮箱获取用户信息 请求参数据结构
|
|
|
+type UserEmailParams struct {
|
|
|
+ Email string `json:"email"`
|
|
|
+}
|
|
|
+
|
|
|
+// UserInfoResp 全时用户信息 返回 数据结构
|
|
|
+type UserInfoResp struct {
|
|
|
+ AccountType int64 `json:"accountType" description:"账号类型 0: 个人账号(个人站点或电商站点下的账号); 1: 企业账号(非个人站点、电商站点的账号)"`
|
|
|
+ CountryCode string `json:"countryCode" description:"国家码"`
|
|
|
+ CustomerCode string `json:"customerCode" description:"客户编码"`
|
|
|
+ CustomerName string `json:"customerName" description:"客户名称"`
|
|
|
+ DisplayName string `json:"displayName" description:"显示名称"`
|
|
|
+ Email string `json:"email" description:"邮箱"`
|
|
|
+ FirstName string `json:"firstName" description:"首部名称"`
|
|
|
+ LastName string `json:"lastName" description:"尾部名称"`
|
|
|
+ LoginName string `json:"loginName" description:"登录名"`
|
|
|
+ MiddleName string `json:"middleName" description:"中间名称"`
|
|
|
+ Mobile string `json:"mobile" description:"手机"`
|
|
|
+ ProductStatus int64 `json:"productStatus" description:"产品类型 0: 未知状态 1: 已开通 2: 未开通 默认为0"`
|
|
|
+ Products []struct {
|
|
|
+ AccountCostStatus int64 `json:"accountCostStatus" description:"费用状态 82-正式,9-试用,91-过期,81-欠费,71-合同终止;过期或者欠费的不能启用产品,需要先由qsboss系统修改为正式或者试用账号,61-免费账号,62-付费账号"`
|
|
|
+ AccountStatus int64 `json:"accountStatus" description:"账号状态 9:试用 82:正式 91:过期 81:欠费 0:禁用"`
|
|
|
+ ProductID int64 `json:"productId" description:" 产品ID"`
|
|
|
+ } `json:"products" description:"产品列表"`
|
|
|
+ UserID int64 `json:"userId" description:"用户ID"`
|
|
|
+ UserStatus int64 `json:"userStatus" description:"用户状态 0:未激活; 1:已激活; 2:已关闭"`
|
|
|
+}
|
|
|
+
|
|
|
+// GetQsUserInfoByEmail 根据邮箱号获取全时用户信息
|
|
|
+func GetQsUserInfoByEmail(email string) (dataResp UserInfoResp, err error) {
|
|
|
+ userEmailItem := UserEmailParams{
|
|
|
+ Email: email,
|
|
|
+ }
|
|
|
+ postData, err := json.Marshal(userEmailItem)
|
|
|
+ if err != nil {
|
|
|
+ utils.FileLog.Info("PostData json.Marshal Err:" + err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ postUrl := `https://events-openapi.quanshi.com/eventopenapi/user/search/email`
|
|
|
+ respData, err, errMsg := postCurl(postUrl, string(postData), 1, true)
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println("err:", err, ";errMsg:", errMsg)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ bodyBytes, _ := json.Marshal(respData.Data)
|
|
|
+ err = json.Unmarshal(bodyBytes, &dataResp)
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+type UserInfo struct {
|
|
|
+ Mobiles []*UserMobile `json:"mobiles"`
|
|
|
+}
|
|
|
+
|
|
|
+type UserMobile struct {
|
|
|
+ PhoneNumber string `json:"phoneNumber"`
|
|
|
+}
|
|
|
+
|
|
|
+func GetQsUserInfoByPhone() {
|
|
|
+ userMobileItem := new(UserMobile)
|
|
|
+ userMobileItem.PhoneNumber = "17521741003"
|
|
|
+
|
|
|
+ userInfoItem := new(UserInfo)
|
|
|
+ userInfoItem.Mobiles = append(userInfoItem.Mobiles, userMobileItem)
|
|
|
+
|
|
|
+ postData, err := json.Marshal(userInfoItem)
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println("PostData json.Marshal Err:" + err.Error())
|
|
|
+ utils.FileLog.Info("PostData json.Marshal Err:" + err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ fmt.Println("postData:" + string(postData))
|
|
|
+ utils.FileLog.Info("Qs PostData:" + string(postData))
|
|
|
+
|
|
|
+ client := &http.Client{}
|
|
|
+ postUrl := `https://events-openapi.quanshi.com//eventopenapi/user/search/mobiles`
|
|
|
+ req, err := http.NewRequest("POST", postUrl, strings.NewReader(string(postData)))
|
|
|
+ if err != nil {
|
|
|
+ // handle error
|
|
|
+ }
|
|
|
+ nonce := utils.GetRandStringNoSpecialChar(32)
|
|
|
+ curTime := time.Now().Local().UnixNano() / 1e6
|
|
|
+ curTimeStr := strconv.FormatInt(curTime, 10)
|
|
|
+ checkSumStr := QsSecretKey + nonce + curTimeStr
|
|
|
+ checkSum := utils.Sha1(checkSumStr)
|
|
|
+
|
|
|
+ req.Header.Set("AppKey", QsAppID)
|
|
|
+ req.Header.Set("Content-Type", "application/json")
|
|
|
+ req.Header.Set("accept", "application/json")
|
|
|
+ req.Header.Set("Nonce", nonce)
|
|
|
+ req.Header.Set("CurTime", curTimeStr)
|
|
|
+ req.Header.Set("CheckSum", checkSum)
|
|
|
+
|
|
|
+ resp, err := client.Do(req)
|
|
|
+
|
|
|
+ defer resp.Body.Close()
|
|
|
+
|
|
|
+ body, err := ioutil.ReadAll(resp.Body)
|
|
|
+ if err != nil {
|
|
|
+ // handle error
|
|
|
+ }
|
|
|
+
|
|
|
+ utils.FileLog.Info("Qs Result:" + string(body))
|
|
|
+
|
|
|
+ fmt.Println(string(body))
|
|
|
+}
|
|
|
+
|
|
|
+// EventStatusParams 查看会议状态请求结构体
|
|
|
+type EventStatusParams struct {
|
|
|
+ EventId int64 `json:"eventId"`
|
|
|
+}
|
|
|
+
|
|
|
+// EventStatusResp 查看会议状态结果返回结构体
|
|
|
+type EventStatusResp struct {
|
|
|
+ AdvanceHours string `json:"advanceHours"`
|
|
|
+ Attendees int64 `json:"attendees"`
|
|
|
+ EventID int64 `json:"eventId"`
|
|
|
+ EventStatus int64 `json:"eventStatus"`
|
|
|
+ MayJoin int64 `json:"mayJoin"`
|
|
|
+}
|
|
|
+
|
|
|
+// QsEventStatus 查看会议状态
|
|
|
+func QsEventStatus(eventId int64) (dataResp EventStatusResp, err error) {
|
|
|
+ params := EventStatusParams{EventId: eventId}
|
|
|
+
|
|
|
+ postData, err := json.Marshal(params)
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println("PostData json.Marshal Err:" + err.Error())
|
|
|
+ utils.FileLog.Info("PostData json.Marshal Err:" + err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ postUrl := `https://events-openapi.quanshi.com/eventopenapi/event/status`
|
|
|
+ respData, err, errMsg := postCurl(postUrl, string(postData), 1, true)
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println("err:", err, ";errMsg:", errMsg)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ bodyBytes, _ := json.Marshal(respData.Data)
|
|
|
+ err = json.Unmarshal(bodyBytes, &dataResp)
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+// EventDetailParams 查看会议详情请求结构体
|
|
|
+type EventDetailParams struct {
|
|
|
+ EventId int64 `json:"eventId"`
|
|
|
+}
|
|
|
+
|
|
|
+// EventDetailResp 查看会议详情结果返回结构体
|
|
|
+type EventDetailResp struct {
|
|
|
+ AdvanceHours string `json:"advanceHours"`
|
|
|
+ Attendees int64 `json:"attendees"`
|
|
|
+ EventID int64 `json:"eventId"`
|
|
|
+ EventStatus int64 `json:"eventStatus"`
|
|
|
+ MayJoin int64 `json:"mayJoin"`
|
|
|
+}
|
|
|
+
|
|
|
+// QsEventDetail 查看会议详情
|
|
|
+func QsEventDetail(eventId int64) (dataResp EventUpdateResp, err error) {
|
|
|
+ params := EventDetailParams{EventId: eventId}
|
|
|
+
|
|
|
+ postData, err := json.Marshal(params)
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println("PostData json.Marshal Err:" + err.Error())
|
|
|
+ utils.FileLog.Info("PostData json.Marshal Err:" + err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ postUrl := `https://events-openapi.quanshi.com/eventopenapi/event/info`
|
|
|
+ respData, err, errMsg := postCurl(postUrl, string(postData), 1, true)
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println("err:", err, ";errMsg:", errMsg)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ bodyBytes, _ := json.Marshal(respData.Data)
|
|
|
+ err = json.Unmarshal(bodyBytes, &dataResp)
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+// QsEventReportSummaryParams 查看会议汇总数据请求结构体
|
|
|
+type QsEventReportSummaryParams struct {
|
|
|
+ EventId int64 `json:"eventId" description:"直播会议ID"`
|
|
|
+ SortBy string `json:"sortBy" description:"汇总去重条件 默认值 extId; email: 根据邮箱汇总; mobile: 根据手机汇总; name: 根据姓名汇总; extId: 根据第三方ID汇总"`
|
|
|
+}
|
|
|
+
|
|
|
+// QsEventReportSummaryResp 查看会议汇总数据结果返回结构体
|
|
|
+type QsEventReportSummaryResp struct {
|
|
|
+ EventID int64 `json:"eventId"`
|
|
|
+ SortBy string `json:"sortBy"`
|
|
|
+ Summary map[string]struct {
|
|
|
+ BillingCode string `json:"billingCode"`
|
|
|
+ ConferenceID string `json:"conferenceId"`
|
|
|
+ Duration int64 `json:"duration"`
|
|
|
+ Email string `json:"email"`
|
|
|
+ ExtID string `json:"extId"`
|
|
|
+ HostID string `json:"hostId"`
|
|
|
+ Mobile string `json:"mobile"`
|
|
|
+ Name string `json:"name"`
|
|
|
+ OfflineDate string `json:"offline_date"`
|
|
|
+ OfflineTime int64 `json:"offline_time"`
|
|
|
+ OnlineDate string `json:"online_date"`
|
|
|
+ OnlineTime int64 `json:"online_time"`
|
|
|
+ } `json:"summary"`
|
|
|
+}
|
|
|
+
|
|
|
+// QsEventReportSummary 查看会议汇总数据
|
|
|
+func QsEventReportSummary(eventId int) (dataResp QsEventReportSummaryResp, err error) {
|
|
|
+ sortBy := `mobile`
|
|
|
+ params := QsEventReportSummaryParams{
|
|
|
+ EventId: int64(eventId),
|
|
|
+ SortBy: sortBy,
|
|
|
+ }
|
|
|
+
|
|
|
+ postData, err := json.Marshal(params)
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println("PostData json.Marshal Err:" + err.Error())
|
|
|
+ utils.FileLog.Info("PostData json.Marshal Err:" + err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ postUrl := `https://events-openapi.quanshi.com/eventopenapi/event/report/summary`
|
|
|
+ respData, err, errMsg := postCurl(postUrl, string(postData), 1, true)
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println("err:", err, ";errMsg:", errMsg)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ bodyBytes, _ := json.Marshal(respData.Data)
|
|
|
+ err = json.Unmarshal(bodyBytes, &dataResp)
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+// QsEventReportQueryParams 批量查询会议状态和录制数据请求结构体
|
|
|
+type QsEventReportQueryParams struct {
|
|
|
+ EventIds []int64 `json:"eventIds" description:"直播会议ID"`
|
|
|
+ QueryType int64 `json:"queryType" description:"查询的数据类别(1: 会议状态; 2: 会议录制; 3: 会议状态+会议录制)"`
|
|
|
+ RecordType int `json:"recordType" description:"录制类型(queryType=2时有效)1:会议录制或电话录制; 5:直播录制; 默认全查"`
|
|
|
+}
|
|
|
+
|
|
|
+// QsEventReportQueryResp 批量查询会议状态和录制数据结果返回结构体
|
|
|
+type QsEventReportQueryResp struct {
|
|
|
+ Records map[string]struct {
|
|
|
+ RecordID int64 `json:"recordId"`
|
|
|
+ RecordType int64 `json:"recordType"`
|
|
|
+ RecordingEndDate string `json:"recordingEndDate"`
|
|
|
+ RecordingEndtime int64 `json:"recordingEndtime"`
|
|
|
+ RecordingStartDate string `json:"recordingStartDate"`
|
|
|
+ RecordingStarttime int64 `json:"recordingStarttime"`
|
|
|
+ Thumb string `json:"thumb"`
|
|
|
+ Title string `json:"title"`
|
|
|
+ VideoLength int64 `json:"videoLength"`
|
|
|
+ VideoSize int64 `json:"videoSize"`
|
|
|
+ VideoStreamURL string `json:"videoStreamUrl"`
|
|
|
+ VideoURL string `json:"videoURL"`
|
|
|
+ } `json:"records"`
|
|
|
+ Status map[string]struct {
|
|
|
+ ConferenceID string `json:"conferenceId"`
|
|
|
+ Status int64 `json:"status"`
|
|
|
+ TempConferenceID string `json:"tempConferenceId"`
|
|
|
+ UserID int64 `json:"userId"`
|
|
|
+ } `json:"status"`
|
|
|
+}
|
|
|
+
|
|
|
+// QsEventReportQueryVideo 批量查询会议录制数据
|
|
|
+func QsEventReportQueryVideo(eventId int64) (dataResp QsEventReportQueryResp, err error) {
|
|
|
+ params := QsEventReportQueryParams{
|
|
|
+ EventIds: []int64{eventId},
|
|
|
+ QueryType: 2,
|
|
|
+ RecordType: 1,
|
|
|
+ }
|
|
|
+
|
|
|
+ postData, err := json.Marshal(params)
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println("PostData json.Marshal Err:" + err.Error())
|
|
|
+ utils.FileLog.Info("PostData json.Marshal Err:" + err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ postUrl := `https://events-openapi.quanshi.com/eventopenapi/event/report/query`
|
|
|
+ respData, err, errMsg := postCurl(postUrl, string(postData), 1, true)
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println("err:", err, ";errMsg:", errMsg)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ bodyBytes, _ := json.Marshal(respData.Data)
|
|
|
+ err = json.Unmarshal(bodyBytes, &dataResp)
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+// QsEventReportQuery 批量查询会议状态和录制数据
|
|
|
+func QsEventReportQuery(eventId, queryType int64) (dataResp QsEventReportQueryResp, err error) {
|
|
|
+ //recordType := 0
|
|
|
+ params := QsEventReportQueryParams{
|
|
|
+ EventIds: []int64{eventId},
|
|
|
+ QueryType: queryType,
|
|
|
+ //RecordType: recordType,
|
|
|
+ }
|
|
|
+
|
|
|
+ postData, err := json.Marshal(params)
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println("PostData json.Marshal Err:" + err.Error())
|
|
|
+ utils.FileLog.Info("PostData json.Marshal Err:" + err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ postUrl := `https://events-openapi.quanshi.com/eventopenapi/event/report/query`
|
|
|
+ respData, err, errMsg := postCurl(postUrl, string(postData), 1, true)
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println("err:", err, ";errMsg:", errMsg)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ bodyBytes, _ := json.Marshal(respData.Data)
|
|
|
+ err = json.Unmarshal(bodyBytes, &dataResp)
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+// 弘则全时的回调签名秘钥
|
|
|
+const QS_HONGZE_KEY = "hongZe20220601QSROc"
|
|
|
+
|
|
|
+// GetSign 获取签名
|
|
|
+func GetSign(signStr string) string {
|
|
|
+ signStr += "&key=" + QS_HONGZE_KEY
|
|
|
+ return utils.MD5(signStr)
|
|
|
+}
|
|
|
+
|
|
|
+//func Qsinit() {
|
|
|
+// fmt.Println("start")
|
|
|
+// nonce := utils.GetRandStringNoSpecialChar(32)
|
|
|
+// curTime := time.Now().Local().UnixNano()/1e6
|
|
|
+// curTimeStr := strconv.FormatInt(curTime, 10)
|
|
|
+// checkSumStr := QsSecretKey + nonce + curTimeStr
|
|
|
+// fmt.Println("nonce:" + nonce)
|
|
|
+// fmt.Println("curTimeStr:" + curTimeStr)
|
|
|
+// fmt.Println("QsSecretKey:" + QsSecretKey)
|
|
|
+// checkSum := utils.Sha1(checkSumStr)
|
|
|
+// fmt.Println(checkSum)
|
|
|
+// fmt.Println("end")
|
|
|
+//}
|