package tencentNlu import ( "bytes" "crypto/hmac" "crypto/sha256" "encoding/base64" "encoding/json" "errors" "fmt" "io/ioutil" "net/http" "speech-nlu-parse/global" "speech-nlu-parse/model" "speech-nlu-parse/pkg/logger" "time" ) type TencentNluV2 struct { SemanticReq *model.SemanticReq // tokenSearchResponse *model.TokenSearchResponse } // 腾讯新接口 func (this *TencentNluV2) GetTNluDataAndParse(data *model.SemanticReq, bot *model.DingDangBot) []byte { content, err := this.GetTencentNluDataV2(data, bot) if err != nil { global.Logger.WithFields(logger.Fields{ "mac": data.MacWifi, "mid": data.Mid, "vender": data.Vender, "requestId": this.SemanticReq.RequestId, }).Error("GetTencentNluDataV2 error.") return replyWithChat(error_reply, "doudi") } // 解析原始的 return this.ParseTNluData(content, data) } func (this *TencentNluV2) ParseTNluData(jsonData []byte, data *model.SemanticReq) []byte { tencentNlpResp := model.TencentNlpResp{} err := json.Unmarshal(jsonData, &tencentNlpResp) if err != nil { global.Logger.WithFields(logger.Fields{ "data": map[string]interface{}{"requestBody": string(jsonData)}, "mac": data.MacWifi, "mid": data.Mid, "vender": data.Vender, "requestId": this.SemanticReq.RequestId, }).Error("ParseTNluData Unmarshal error.") return replyWithChat(error_reply, "doudi") } if !tencentNlpResp.CheckHeader() { // Header不存在 global.Logger.WithFields(logger.Fields{ "data": map[string]interface{}{"requestBody": string(jsonData)}, "mac": data.MacWifi, "mid": data.Mid, "vender": data.Vender, "requestId": this.SemanticReq.RequestId, }).Error("ParseTNluData response code error.") return replyWithChat(error_reply, "doudi") } code := tencentNlpResp.GetCode() // 解析 if code != 0 { // 状态码异常 打印log global.Logger.WithFields(logger.Fields{ "data": map[string]interface{}{"requestBody": string(jsonData)}, "mac": data.MacWifi, "mid": data.Mid, "vender": data.Vender, "requestId": this.SemanticReq.RequestId, }).Error("ParseTNluData response code error.") return replyWithChat(error_reply, "doudi") } domainStr := tencentNlpResp.GetDomain() if domainStr == "" { // domain不存在, 打印log global.Logger.WithFields(logger.Fields{"data": map[string]interface{}{"requestBody": string(jsonData)}, "mac": data.MacWifi, "mid": data.Mid, "vender": data.Vender, "requestId": this.SemanticReq.RequestId}).Error("ParseTNluData domain is not exist.") return replyWithChat(error_reply, "doudi") } var jsonByte []byte reply_when_tencent_empty = replyMessage[getRandom(len(replyMessage))] params := &model.DomainParamsV2{ TencentNlpResp: &tencentNlpResp, // TokenSearchResponse: this.tokenSearchResponse, Mac: this.SemanticReq.MacWifi, Domain: domainStr, Mid: this.SemanticReq.Mid, Query: this.SemanticReq.Query, RequestId: this.SemanticReq.RequestId, } // fmt.Println(global.GetLimitedSetting("6400").ShieldedDomainList) // 根据mid屏蔽部分domain, 并返回 if IsContain(domainStr, global.GetLimitedSetting(this.SemanticReq.Mid).ShieldedDomainList) { jsonByte = ShieldedDomainV2(params) return jsonByte } if value, ok := getHandlerV2(domainStr); ok { jsonByte = value(params) } else { // 其他domain进行兜底 global.Logger.WithFields(logger.Fields{"data": map[string]interface{}{"requestBody": string(jsonData)}, "mac": data.MacWifi, "mid": data.Mid, "vender": data.Vender, "requestId": this.SemanticReq.RequestId}).Error("ParseTNluData domain handler is not exist.") jsonByte = OtherDomainV2(params) } return jsonByte } func (this *TencentNluV2) GetTencentNluDataV2(data *model.SemanticReq, bot *model.DingDangBot) ([]byte, error) { // 获取botkey 和 botsecret var botKey, botSecret string var auth, dsn string // var guid string var qua string = "QV=3&PL=ADR&PR=chvoice&VE=7.6&VN=3350&PP=com.geli.mtt&DE=SPEAKER&SP=3" // 默认 botKey = bot.Key // 默认 botSecret = bot.Secret // 默认 // 存在鉴权信息 if data.Appkey != "" && data.AccessToken != "" { botKey = data.Appkey botSecret = data.AccessToken } if data.Qua != "" { qua = data.Qua } if data.Auth != "" && data.Dsn != "" { auth = data.Auth dsn = data.Dsn } else { // 不存在鉴权信息则从dmsdk查询, 直接報錯 return []byte(""), errors.New("auth or dsn is not exist.") } // fmt.Println("exist:", data.Exist) // fmt.Println("appkey:", botKey) // fmt.Println("accessToken:", botSecret) // fmt.Println("qua:", qua) // fmt.Println("auth:", auth) // fmt.Println("dsn:", dsn) // fmt.Println("guid:", guid) // this.tokenSearchResponse = tokenSearchResponse timeStamp := time.Now().Unix() // url := "https://gwgray.tvs.qq.com/v2/ai/nlp" url := fmt.Sprintf("%s%s", global.TencentGwSetting.Gw.GwHost, "/ai/nlp") reqBody := model.TencentNlp{} reqBody.Header.DSN = dsn reqBody.Header.QUA = qua // reqBody.Header.Authorization = auth // reqBody.Header.GUID = guid // reqBody.Header.IP = data.Ip var location *model.Location if data.Lbs != nil { location = &model.Location{ Longitude: float32(data.Lbs.Longitude), Latitude: float32(data.Lbs.Latitude), } } reqBody.Header.Location = location reqBody.Payload.Semantic.Query = data.Query rb, err := json.Marshal(&reqBody) if err != nil { // TODO: 错误返回 global.Logger.WithFields(logger.Fields{ "data": map[string]interface{}{"jsonStr": string(rb)}, "requestId": data.RequestId, "mac": data.MacWifi, "mid": data.Mid, "vender": data.Vender, }).Error("GetTencentNLUDataV2: Marshal error. " + err.Error()) return []byte(""), err } req, err := http.NewRequest(http.MethodPost, url, bytes.NewBuffer(rb)) query := req.URL.Query() query.Add("appkey", botKey) query.Add("requestid", data.TRequestId) // 增加腾讯requestId query.Add("signature", HmacSha256AndBase64(fmt.Sprintf("appkey=%s&requestid=%s×tamp=%d", botKey, data.TRequestId, timeStamp), botSecret)) query.Add("timestamp", fmt.Sprintf("%d", timeStamp)) req.URL.RawQuery = query.Encode() req.Header.Set("Content-Type", "application/json;charset=utf-8") req.Header.Set("X-Forwarded-For", data.Ip) req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", auth)) global.Logger.WithFields(logger.Fields{ "url": url, "data": map[string]interface{}{"requestBody": string(rb)}, "requestId": data.RequestId, "mac": data.MacWifi, "mid": data.Mid, "vender": data.Vender, }).Info("tencent-nlu-v2-http-post request.") client := &http.Client{} resp, err := client.Do(req) if nil != err { global.Logger.WithFields(logger.Fields{"data": map[string]interface{}{"jsonStr": string(rb)}, "mac": data.MacWifi, "mid": data.Mid, "vender": data.Vender, "requestId": data.RequestId}).Error("GetTencentNLUDataV2: Get TencentNLU data error. " + err.Error()) return []byte(""), err } defer resp.Body.Close() content, err := ioutil.ReadAll(resp.Body) if nil != err { global.Logger.WithFields(logger.Fields{"requestId": data.RequestId, "mac": data.MacWifi, "mid": data.Mid, "vender": data.Vender}).Error("GetTencentNLUData: Read response data body error." + err.Error()) return []byte(""), err } global.Logger.WithFields(logger.Fields{ "data": map[string]interface{}{"responseBody": string(content)}, "requestId": data.RequestId, "mac": data.MacWifi, "mid": data.Mid, "vender": data.Vender, "sessionId": string(resp.Header.Get("sessionid")), }).Info("tencent-nlu-v2-http-post response.") return content, nil } func HmacSha256AndBase64(message string, secret string) string { h := hmac.New(sha256.New, []byte(secret)) h.Write([]byte(message)) return base64.StdEncoding.EncodeToString(h.Sum(nil)) } // 屏蔽处理 func ShieldedDomainV2(params *model.DomainParamsV2) []byte { domainStr := params.TencentNlpResp.Payload.Semantic.Results[0].Nlu.Domain intentStr := params.TencentNlpResp.Payload.Semantic.Results[0].Nlu.Intent // 暂不支持此功能 resultTextStr := shielded_reply return replyWithChat(resultTextStr, domainStr+"."+intentStr) } // 不进行register func OtherDomainV2(params *model.DomainParamsV2) []byte { resultText := reply_when_tencent_empty domain := params.TencentNlpResp.GetDomain() // chat回复需修改 return replyWithChat(resultText, domain) }