package crontask import ( "bytes" "encoding/json" "fmt" "github.com/google/uuid" "github.com/zeromicro/go-zero/core/logx" "net/http" "strconv" "time" "wechat-api/ent/contact" "wechat-api/ent/contactfield" "wechat-api/ent/contactfieldtemplate" "wechat-api/ent/custom_types" "wechat-api/ent/predicate" "wechat-api/ent/usagedetail" ) type ResponseItem struct { DataIndex string `json:"dataIndex"` Value []string `json:"value"` } type FieldPropsOptions struct { Label string `json:"label"` Value string `json:"value"` } type FieldProps struct { Options []FieldPropsOptions `json:"options"` } type FormData struct { Title string `json:"title"` DataIndex string `json:"dataIndex"` ValueType string `json:"valueType"` FieldProps FieldProps `json:"fieldProps"` } func (l *CronTask) analyze() { usageDetails := make(map[string]map[string]string) contactFieldTemplates := make(map[string][]custom_types.ContactFieldTemplate) template_type_text := "text" template_type_radio := "radio" template_type_date := "date" template_sex_id := "sex" template_sex_label := "性别" template_sex_options_man_label := "男" template_sex_options_man_value := "男" template_sex_options_woman_label := "女" template_sex_options_woman_value := "男" template_phone_id := "phone" template_phone_label := "手机号" template_name_id := "name" template_name_label := "姓名" template_age_id := "age" template_age_label := "年龄(以字符串形式返回阿拉伯数字)" template_area_id := "area" template_area_label := "地区" template_birthday_id := "birthday" template_birthday_label := "出生日期" template_birtharea_id := "birtharea" template_birtharea_label := "出生地" template_idcard_no_id := "idcard_no" template_idcard_no_label := "身份证号" template_title_id := "title" template_title_label := "称呼" contactBasicFieldTemplates := []custom_types.ContactFieldTemplate{ { Label: &template_sex_label, Id: &template_sex_id, Type: &template_type_radio, Options: []custom_types.ContactFieldTemplateOptions{ { Label: &template_sex_options_man_label, Value: &template_sex_options_man_value, }, { Label: &template_sex_options_woman_label, Value: &template_sex_options_woman_value, }, }, }, { Label: &template_phone_label, Id: &template_phone_id, Type: &template_type_text, }, { Label: &template_name_label, Id: &template_name_id, Type: &template_type_text, }, { Label: &template_age_label, Id: &template_age_id, Type: &template_type_text, }, { Label: &template_area_label, Id: &template_area_id, Type: &template_type_text, }, { Label: &template_birthday_label, Id: &template_birthday_id, Type: &template_type_date, }, { Label: &template_birtharea_label, Id: &template_birtharea_id, Type: &template_type_text, }, { Label: &template_idcard_no_label, Id: &template_idcard_no_id, Type: &template_type_text, }, { Label: &template_title_label, Id: &template_title_id, Type: &template_type_text, }, } var predicates []predicate.UsageDetail predicates = append(predicates, usagedetail.TypeIn(1, 3)) predicates = append(predicates, usagedetail.AppIn(1, 3, 4, 5)) yesterdayStart := time.Now().AddDate(0, 0, -1).Truncate(24 * time.Hour) yesterdayEnd := yesterdayStart.Add(24 * time.Hour) predicates = append(predicates, usagedetail.CreatedAtGTE(yesterdayStart)) predicates = append(predicates, usagedetail.CreatedAtLT(yesterdayEnd)) //todayStart := time.Now().AddDate(0, 0, 0).Truncate(24 * time.Hour) //todayEnd := todayStart.Add(24 * time.Hour) //predicates = append(predicates, usagedetail.CreatedAtGTE(todayStart)) //predicates = append(predicates, usagedetail.CreatedAtLT(todayEnd)) data, err := l.svcCtx.DB.UsageDetail.Query().Where(predicates...).All(l.ctx) logx.Info("usageDetails: ", data) if err != nil { return } for _, u := range data { if _, ok := contactFieldTemplates[u.BotID]; !ok { c, _ := l.svcCtx.DB.ContactFieldTemplate.Query().Where(contactfieldtemplate.OrganizationID(u.OrganizationID)).First(l.ctx) if c != nil { contactFieldTemplates[u.BotID] = c.Template } else { contactFieldTemplates[u.BotID] = nil } } if contactFieldTemplates[u.BotID] == nil { continue } if _, ok := usageDetails[u.BotID]; !ok { usageDetails[u.BotID] = make(map[string]string) } usageDetails[u.BotID][u.ReceiverID] += fmt.Sprintf("用户:%s\n机器人:%s\n", u.Request, u.Response) } logx.Info("contactFieldTemplates: ", contactFieldTemplates) logx.Info("usageDetails: ", usageDetails) for botID, template := range contactFieldTemplates { if template == nil { template = contactBasicFieldTemplates } else { template = append(template, contactBasicFieldTemplates...) } for receiverID, messages := range usageDetails[botID] { result, _ := openaiRequest(messages, template) logx.Info("result: ", result) if result == nil { continue } _ = l.UpdateContactFields(botID, receiverID, result) } } } func openaiRequest(messages string, template []custom_types.ContactFieldTemplate) ([]ResponseItem, error) { url := "https://toolsapi-debug.gkscrm.com/call_center/form/extract" bodyData := map[string]interface{}{ "form_data": ConvertFormData(template), "chat_history": messages, "external_id": uuid.New().String(), } logx.Info("bodyData: %+v", bodyData) bodyBytes, err := json.Marshal(bodyData) if err != nil { return nil, err } req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes)) if err != nil { return nil, err } req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxIn0.ZS9jnsLPCnmc8L_lu4yaQFp34vwWF1mHlHSBYrY5JVs") client := &http.Client{} resp, err := client.Do(req) if err != nil || resp == nil || resp.Body == nil { logx.Error("read body error: ", err) return nil, err } logx.Info("err: ", err) if err != nil { return nil, err } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode) } //var result []ResponseItem var fullResp struct { Data []ResponseItem `json:"data"` } err = json.NewDecoder(resp.Body).Decode(&fullResp) if err != nil { return nil, err } return fullResp.Data, nil } func (l *CronTask) UpdateContactFields(botID string, receiverID string, fields []ResponseItem) error { basic_ids := []string{"sex", "phone", "name", "age", "area", "birthday", "birtharea", "idcard_no", "title"} c, _ := l.svcCtx.DB.Contact.Query().Where(contact.WxWxidEQ(botID), contact.WxidEQ(receiverID)).First(l.ctx) if c == nil { return fmt.Errorf("Contact not find") } for _, field := range fields { if contains(basic_ids, field.DataIndex) { if len(field.Value) == 0 { continue } value := 0 if field.DataIndex == "sex" && c.Sex == 0 { if field.Value[0] == "男" { value = 1 } else if field.Value[0] == "女" { value = 2 } _, err := l.svcCtx.DB.Contact.Update(). Where(contact.WxidEQ(receiverID)). SetSex(value). Save(l.ctx) if err != nil { continue } } else if field.DataIndex == "phone" && c.Phone == "" { _, err := l.svcCtx.DB.Contact.Update(). Where(contact.WxidEQ(receiverID)). SetPhone(field.Value[0]). Save(l.ctx) if err != nil { continue } } else if field.DataIndex == "name" && c.Cname == "" { _, err := l.svcCtx.DB.Contact.Update(). Where(contact.WxidEQ(receiverID)). SetCname(field.Value[0]). Save(l.ctx) if err != nil { continue } } else if field.DataIndex == "age" && c.Cage == 0 { num, err := strconv.Atoi(field.Value[0]) if err != nil { continue } _, err = l.svcCtx.DB.Contact.Update(). Where(contact.WxidEQ(receiverID)). SetCage(num). Save(l.ctx) if err != nil { continue } } else if field.DataIndex == "area" && c.Carea == "" { _, err := l.svcCtx.DB.Contact.Update(). Where(contact.WxidEQ(receiverID)). SetCarea(field.Value[0]). Save(l.ctx) if err != nil { continue } } else if field.DataIndex == "birthday" && c.Cbirthday == "" { _, err := l.svcCtx.DB.Contact.Update(). Where(contact.WxidEQ(receiverID)). SetCbirthday(field.Value[0]). Save(l.ctx) if err != nil { continue } } else if field.DataIndex == "birtharea" && c.Cbirtharea == "" { _, err := l.svcCtx.DB.Contact.Update(). Where(contact.WxidEQ(receiverID)). SetCbirtharea(field.Value[0]). Save(l.ctx) if err != nil { continue } } else if field.DataIndex == "idcard_no" && c.CidcardNo == "" { _, err := l.svcCtx.DB.Contact.Update(). Where(contact.WxidEQ(receiverID)). SetCidcardNo(field.Value[0]). Save(l.ctx) if err != nil { continue } } else if field.DataIndex == "title" && c.Ctitle == "" { _, err := l.svcCtx.DB.Contact.Update(). Where(contact.WxidEQ(receiverID)). SetCtitle(field.Value[0]). Save(l.ctx) if err != nil { continue } } } else { f, _ := l.svcCtx.DB.ContactField.Query().Where(contactfield.ContactID(c.ID), contactfield.FormID(field.DataIndex)).First(l.ctx) if f == nil { if field.Value != nil && len(field.Value) > 0 && field.Value[0] != "" { _, err := l.svcCtx.DB.ContactField.Create(). SetContactID(c.ID). SetFormID(field.DataIndex). SetValue(field.Value). Save(l.ctx) if err != nil { continue } } } else { if field.Value != nil { if len(field.Value) == 0 || field.Value[0] == "" { continue } _, err := l.svcCtx.DB.ContactField.UpdateOneID(f.ID). SetValue(field.Value). Save(l.ctx) if err != nil { continue } } } } } return nil } func ConvertFormData(input []custom_types.ContactFieldTemplate) []FormData { result := make([]FormData, len(input)) for i, item := range input { options := make([]FieldPropsOptions, len(item.Options)) for j, opt := range item.Options { options[j] = FieldPropsOptions{ Label: *opt.Label, Value: *opt.Value, } } result[i] = FormData{ Title: *item.Label, DataIndex: *item.Id, ValueType: *item.Type, FieldProps: FieldProps{ Options: options, }, } } return result } func contains(strs []string, target string) bool { for _, s := range strs { if s == target { return true } } return false }