package service import ( "crypto/sha1" "encoding/xml" "fmt" "io/ioutil" "sort" "strings" "time" "github.com/gin-gonic/gin" "github.com/pkg/errors" "kpt.notice/apiserver/model" "kpt.notice/apiserver/model/http" "kpt.notice/pkg/log" "kpt.notice/pkg/util" ) func (svc *Service) UpdateMessage(msg *model.Message) (err error) { mtype := &http.MessageTypeReq{ SysName: msg.SysName, PastureID: msg.PastureID, ServiceID: msg.ServiceID, } if mtypes, e := svc.QueryMsgType(mtype); e != nil { err = e return } else if len(mtypes) == 0 { err = errors.New("没有匹配的消息类型") return } else { m := make(map[string]interface{}, 3) if mtypes[0].RemindType == 1 { m["status"] = 1 } else if mtypes[0].RemindType == 2 { if mtypes[0].CycleType == 1 || mtypes[0].CycleType == 3 { m["status"] = 1 } else { m["updated_at"] = time.Now() m["push_count"] = msg.PushCount + 1 if msg.PushCount+1 >= mtypes[0].PushLimit { m["status"] = 1 } } } else if mtypes[0].RemindType == 3 { m["push_count"] = msg.PushCount + 1 m["updated_at"] = time.Now() } if res := svc.DB.Table("message").Where("id=?", msg.ID).Updates(m); res.Error != nil { err = errors.Wrap(res.Error, "UpdateMessage.update=") log.Errorf("%v", err) } } return } func (svc *Service) UpdateMessageStatus(id int) (err error) { err = svc.DB.Exec(` update message set status = -1 where id = ? `, id).Error if err != nil { log.Error(err) return } return } func (svc *Service) QueryMsg() (msgs []model.Message, err error) { var sql2 string sql := `select sqltext from apisql where sqlname='getMessage' limit 1 ` svc.DB.Raw(sql).Scan(&sql2) if err = svc.DB.Raw(sql2).Scan(&msgs).Error; err != nil { err = errors.Wrap(err, "queryMsg{query msg exec sql err}==%v") log.Errorf("%v", err) return } return } func (svc *Service) InsertMessage(msg *http.MessageReq, body []byte) (resp *http.MessageResp, err error) { tmp := make(map[string]interface{}) tmp["miniprogram"] = msg.Miniprogram msgType := &http.MessageTypeReq{ SysName: msg.SysName, PastureID: msg.PastureID, ServiceID: msg.ServiceID, } sysuserList, e := svc.GetSysUser(msg.Target, msg.SysName, msg.PastureID) if err != nil { err = e return } var targetList []string for _, user := range sysuserList { targetList = append(targetList, user.Openid) } if mt, e := svc.QueryMsgType(msgType); e != nil { err = e return } else if len(mt) == 0 { err = errors.New("没有匹配的消息类型") return } else { tmp["template_id"] = mt[0].TemplateID } data := make(map[string]http.Tag) for i, v := range msg.Keys { data[v] = msg.Content[i] } tmp["data"] = data status := -1 for _, target := range targetList { if target != "" { status = 0 break } } msgDb := model.Message{ SysName: msg.SysName, PastureID: msg.PastureID, ServiceID: msg.ServiceID, Target: util.MarshalToString(targetList), MsgTypeID: msg.MsgTypeID, MsgContent: util.MarshalToString(tmp), UpdatedAt: time.Now(), BodyData: string(body), Status: status, } if err = svc.DB.Create(&msgDb).Error; err != nil { err = errors.Wrap(err, "InsertMessage{insert msg}==%v") log.Errorf("%v", err) return } resp = &http.MessageResp{ ID: msgDb.ID, } return } // query the id or remind_type of the message by name func (svc *Service) QueryRemindTypeID(name string) (int, error) { m := new(http.MessageTypeReq) tx := svc.DB.Table("message_type").Where("type_name = ?").First(m) if tx.RowsAffected == 0 { return 0, errors.New("没有匹配的类型") } return m.ID, nil } func (svc *Service) InsertMsgType(req *http.MessageTypeReq) (resp *http.MessageTypeResp, err error) { //固定模板 req.TemplateID = "1_zBqvbzD-edg0b-O5OD1kAEMefygikcmBZACSiwX0w" if query, e := svc.QueryMsgType(req); e != nil { err = e return } else { resp = new(http.MessageTypeResp) switch { case len(query) == 0: resp.Method = "insert" if res := svc.DB.Table("message_type").Create(req); res.Error != nil { err = errors.Wrap(res.Error, "InsertMsgType{create msg type===%v}") log.Errorf("%v", err) } else { resp.RowsAffected = int(res.RowsAffected) } break case len(query) > 0: resp.Method = "update" index := map[string]interface{}{ "service_id": req.ServiceID, "pasture_id": req.PastureID, "sys_name": req.SysName, } log.Infof("msg type update index%v", index) req.PastureID = 0 req.SysName = "" req.ServiceID = 0 log.Infof("msg type update value%v", req) if res := svc.DB.Table("message_type").Where(index).Updates(req); res.Error != nil { err = errors.Wrap(err, "InsertMsgType{update msg type ===%v}") log.Errorf("%v", err) } else { resp.RowsAffected = int(res.RowsAffected) } break } } return } func (svc *Service) QueryMsgType(req *http.MessageTypeReq) (m []http.MessageTypeReq, err error) { index := map[string]interface{}{} if req.ServiceID != 0 { index["service_id"] = req.ServiceID } if req.PastureID != 0 { index["pasture_id"] = req.PastureID } if req.SysName != "" { index["sys_name"] = req.SysName } log.Infof("query msg type===%v", index) if err = svc.DB.Table("message_type").Where(index).Find(&m).Error; err != nil { err = errors.Wrap(err, "QueryMsgType.find=") log.Errorf("%v", err) } return } type WechatMessage struct { ToUserName string `xml:"ToUserName"` FromUserName string `xml:"FromUserName"` CreateTime int64 `xml:"CreateTime"` MsgType string `xml:"MsgType"` Content string `xml:"Content"` } // type WechatTransferResponse struct { // XMLName xml.Name `xml:"xml"` // ToUserName string `xml:"ToUserName"` // FromUserName string `xml:"FromUserName"` // CreateTime int64 `xml:"CreateTime"` // MsgType string `xml:"MsgType"` // // TransInfo TransInfo `xml:"TransInfo"` // } type WechatResponse struct { XMLName xml.Name `xml:"xml"` ToUserName string `xml:"ToUserName"` FromUserName string `xml:"FromUserName"` CreateTime int64 `xml:"CreateTime"` MsgType string `xml:"MsgType"` Content string `xml:"Content"` } // func main() { // r := gin.Default() // r.GET("/wechat", handleVerification) // r.POST("/wechat", handleMessage) // fmt.Println("Server started on :80") // r.Run(":80") // } func (svc *Service) HandleVerification(c *gin.Context) (bool, string) { signature := c.Query("signature") timestamp := c.Query("timestamp") nonce := c.Query("nonce") echostr := c.Query("echostr") fmt.Println(signature) fmt.Println(timestamp) fmt.Println(nonce) fmt.Println(echostr) return checkSignature(signature, timestamp, nonce), echostr } func (svc *Service) HandleMessage(c *gin.Context) []byte { body, _ := ioutil.ReadAll(c.Request.Body) fmt.Println(string(body)) defer c.Request.Body.Close() var msg WechatMessage xml.Unmarshal(body, &msg) var count int64 svc.DB.Table("public").Where("`create` between DATE_SUB(NOW(), INTERVAL 10 MINUTE) and NOW() ").Where(" wxid = ? ", msg.ToUserName).Count(&count) p := new(http.Public) p.Wxid = msg.ToUserName p.Context = msg.Content p.Create = time.Now().Format("2006-01-02 15:04:05") svc.DB.Table("public").Create(p) var content string if count == 0 { content = `您好!感谢您关注科湃腾!您哪个系统需要服务? 👉精准饲喂 👉智能脖环 👉智能喷淋 👉系统开发服务 👉其他 专线: 021- 6630 1586` } else if p.Context == "精准饲喂" || p.Context == "智能脖环" || p.Context == "智能喷淋" || p.Context == "系统开发服务" || p.Context == "其他" { content = `您所属那个大区? 👉东北大区 👉西北大区 👉华北大区 👉南方大区` } else if p.Context == "东北大区" || p.Context == "西北大区" || p.Context == "华北大区" || p.Context == "南方大区" { content = `东北大区服务老师联系方式 谭佳悦:18888309870 喻旭超:13594927924 您可通过电话进行咨询,若您现在不方便电话联系,可以留下您的联系方式,简单描述一下问题或者拍照,我们安排服务人员在4小时内联系您,请您留意电话接听,祝您生活愉快!` // new(notice.MessageRequest) // notice.SendMessage(nil) } else { } response := WechatResponse{ ToUserName: msg.FromUserName, FromUserName: msg.ToUserName, CreateTime: time.Now().Unix(), MsgType: "text", Content: content, } responseXML, _ := xml.Marshal(response) return responseXML } func checkSignature(signature, timestamp, nonce string) bool { token := "e10adc3949ba59abbe56e057f20f883e" tmpList := []string{token, timestamp, nonce} sort.Strings(tmpList) tmpStr := strings.Join(tmpList, "") h := sha1.New() h.Write([]byte(tmpStr)) digest := fmt.Sprintf("%x", h.Sum(nil)) return digest == signature } type Message struct { ToUser string `json:"touser"` MsgType string `json:"msgtype"` Text struct { Content string `json:"content"` } `json:"text"` } // func sendCustomMessage(accessToken, openID, content string) error { // url := fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=%s", accessToken) // message := Message{ // ToUser: openID, // MsgType: "text", // Text: struct { // Content string `json:"content"` // }{ // Content: content, // }, // } // payload, err := json.Marshal(message) // if err != nil { // return err // } // resp, err := http1.Post(url, "application/json", bytes.NewBuffer(payload)) // if err != nil { // return err // } // defer resp.Body.Close() // var result map[string]interface{} // if err := json.NewDecoder(resp.Body).Decode(&result); err != nil { // return err // } // fmt.Println("Response:", result) // return nil // }