package quanshi import ( "encoding/json" "errors" "fmt" "hongze/hz_crm_api/services/alarm_msg" "hongze/hz_crm_api/utils" "io/ioutil" "net/http" "strconv" "strings" "time" ) // 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 = utils.QsUserId user.UserName = utils.QsUserName 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 := utils.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", utils.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 int64 `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: utils.QsUserId, 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 := utils.QsSecretKey + nonce + curTimeStr checkSum := utils.Sha1(checkSumStr) req.Header.Set("AppKey", utils.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") //}