package wx_mp import ( "encoding/json" "fmt" "github.com/astaxie/beego" "bytes" "fohow.com/libs/tool" "io/ioutil" "net/http" ) type SessionKey struct { Openid string `json:"openid"` //用户唯一标识 SessionKey string `json:"session_key"` //会话密钥 Unionid string `json:"unionid"` //用户在开放平台的唯一标识符。本字段在满足一定条件的情况下才返回。 } type SessionKeyError struct { Errcode int64 `json:"errcode"` //用户唯一标识 Errmsg string `json:"errmsg"` //会话密钥 } // appId :小程序唯一标识 // appSecret: 小程序的 app secret // code: 登录时获取的 code func GetXcxSessionKey(appId, appSecret, code string) *SessionKey { url := fmt.Sprintf("https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code", appId, appSecret, code) resp := tool.HttpCall(url, "GET", nil, nil) var key *SessionKey //beego.BeeLogger.Warn("GetXcxSessionKey resp: %s", resp) if err := json.Unmarshal([]byte(resp), &key); err != nil { beego.BeeLogger.Error("GetXcxSessionKey parse query error:", err) } if key == nil || key.Openid == "" || key.SessionKey == "" { var keyError *SessionKeyError if err := json.Unmarshal([]byte(resp), &keyError); err != nil { beego.BeeLogger.Error("GetXcxSessionKey parse query error:", err) } beego.BeeLogger.Error("GetXcxSessionKey get session key error:%s", keyError) return nil } return key } type TemplateMessage struct { ToUser string `json:"touser"` // 必须, 接受者OpenID TemplateId string `json:"template_id"` // 必须, 模版ID URL string `json:"url,omitempty"` // 可选, 用户点击后跳转的URL, 该URL必须处于开发者在公众平台网站中设置的域中 TopColor string `json:"topcolor,omitempty"` // 可选, 整个消息的颜色, 可以不设置 Data json.RawMessage `json:"data"` // 必须, JSON 格式的 []byte, 满足特定的模板需求 } func (msg *TemplateMessage) ToJson() { b, err := json.Marshal(msg) if err != nil { fmt.Println(err) return } fmt.Println(string(b)) } type DataKeywordValue struct { Value string `json:"value"` Color string `json:"color"` } func NewDataKeywordValue(value string, color string) *DataKeywordValue { if color == "" { color = "#FFFFFF" } return &DataKeywordValue{Value: value, Color: color} } type OrderDispatchdMessageData struct { Amount DataKeywordValue `json:"keyword1"` Datetime DataKeywordValue `json:"keyword2"` Reason DataKeywordValue `json:"keyword3"` Remark DataKeywordValue `json:"keyword4"` } type BalanceChangedMessageData struct { Amount DataKeywordValue `json:"keyword1"` Datetime DataKeywordValue `json:"keyword2"` Reason DataKeywordValue `json:"keyword3"` Remark DataKeywordValue `json:"keyword4"` } type ProductLogisticsChangedMessageData struct { DispatchTime DataKeywordValue `json:"keyword1"` ProductName DataKeywordValue `json:"keyword2"` OrderId DataKeywordValue `json:"keyword3"` ExpressCompany DataKeywordValue `json:"keyword4"` ExpressOrderNo DataKeywordValue `json:"keyword5"` Remark DataKeywordValue `json:"keyword6"` } type OrderCreatedMessageData struct { OrderId DataKeywordValue `json:"keyword1"` Created_at DataKeywordValue `json:"keyword2"` ProductName DataKeywordValue `json:"keyword3"` Count DataKeywordValue `json:"keyword4"` OrderStatus DataKeywordValue `json:"keyword5"` Remark DataKeywordValue `json:"keyword6"` } type SelfUseNotifyMessageData struct { ProductName DataKeywordValue `json:"keyword1"` SelfUseCount DataKeywordValue `json:"keyword2"` WarmTip DataKeywordValue `json:"keyword3"` ServicePerson DataKeywordValue `json:"keyword4"` } type Template3MessageData struct { Kerword1 DataKeywordValue `json:"keyword1"` Kerword2 DataKeywordValue `json:"keyword2"` Kerword3 DataKeywordValue `json:"keyword3"` } type SubscribeDataValue struct { Value string `json:"value"` } type SubscribeMessage struct { ToUser string `json:"touser"` TemplateId string `json:"template_id"` Page string `json:"page,omitempty"` Data json.RawMessage `json:"data"` Lang string `json:"lang,omitempty"` MiniProgram string `json:"miniprogram_state,omitempty"` } type SubscribeMessageResponse struct { ErrCode int64 `json:"errcode"` ErrMsg string `json:"errmsg"` } func SendTemplateMessage(toUserOpenId string, templateId string, page string, formId string, data json.RawMessage, emphasisKeyword string) { token := GetAccessToken(beego.AppConfig.String("WxFohowXcxAppId"), beego.AppConfig.String("WxFohowXcxAppSecret")) beego.BeeLogger.Info("TestSendingTemplatemsgController got token: %s", token) template := `{ "touser": "%s", "template_id": "%s", "page": "%s", "form_id": "%s", "data": %s, "emphasis_keyword": "%s" }` postData := fmt.Sprintf(template, toUserOpenId, templateId, page, formId, data, emphasisKeyword) apiUrl := fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=%s", token) var jsonStr = []byte(postData) req, err := http.NewRequest("POST", apiUrl, bytes.NewBuffer(jsonStr)) req.Header.Set("Content-Type", "application/json") client := &http.Client{} resp, err := client.Do(req) if err != nil { beego.BeeLogger.Error(err.Error()) } beego.BeeLogger.Warn("wx_mp.SendTemplateMessage, resp is null : %v", resp == nil) if resp != nil { defer resp.Body.Close() body, _ := ioutil.ReadAll(resp.Body) fmt.Println("response Body:", string(body)) return } beego.BeeLogger.Warn("wx_mp.SendTemplateMessage, finished") } func SendXcxSubscribeMessage(toUserOpenId string, templateId string, page string, data interface{}) error { token := GetAccessToken(beego.AppConfig.String("WxFohowXcxAppId"), beego.AppConfig.String("WxFohowXcxAppSecret")) if token == "" { return fmt.Errorf("xcx subscribe message access token is empty") } jsonTemplateData, err := json.Marshal(data) if err != nil { return err } msg := SubscribeMessage{ ToUser: toUserOpenId, TemplateId: templateId, Page: page, Data: jsonTemplateData, Lang: "zh_CN", } postData, err := json.Marshal(msg) if err != nil { return err } apiUrl := fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=%s", token) req, err := http.NewRequest("POST", apiUrl, bytes.NewBuffer(postData)) if err != nil { return err } req.Header.Set("Content-Type", "application/json") resp, err := (&http.Client{}).Do(req) if err != nil { return err } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { return err } beego.BeeLogger.Warn("wx_mp.SendXcxSubscribeMessage response: %s", string(body)) ret := new(SubscribeMessageResponse) if err := json.Unmarshal(body, ret); err != nil { return err } if ret.ErrCode != 0 { return fmt.Errorf("wechat subscribe message errcode=%d errmsg=%s", ret.ErrCode, ret.ErrMsg) } return nil } func formatFen(amount int64) string { return fmt.Sprintf("%.2f元", float64(amount)/100) }