package crontask import ( "bytes" "encoding/json" "fmt" "github.com/google/uuid" "github.com/zeromicro/go-zero/core/logx" "net/http" "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) 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 { continue } 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.Infof("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 { logx.Infof("botID: ", botID) logx.Infof("receiverID: ", receiverID) logx.Infof("fields: ", fields) c, _ := l.svcCtx.DB.Contact.Query().Where(contact.WxWxidEQ(botID), contact.WxidEQ(receiverID)).First(l.ctx) logx.Infof("c: ", c) if c == nil { return fmt.Errorf("Contact not find") } for _, field := range fields { 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 { _, err := l.svcCtx.DB.ContactField.Create(). SetContactID(c.ID). SetFormID(field.DataIndex). SetValue(field.Value). Save(l.ctx) if err != nil { return err } } } else { if field.Value != nil { if len(field.Value) == 0 { field.Value = []string{""} } _, err := l.svcCtx.DB.ContactField.UpdateOneID(f.ID). SetValue(field.Value). Save(l.ctx) if err != nil { return err } } } } 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 }