message-pusher/channel/wechat-test-account.go

134 lines
3.7 KiB
Go

package channel
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"message-pusher/common"
"message-pusher/model"
"net/http"
"time"
)
type wechatTestAccountResponse struct {
ErrorCode int `json:"errcode"`
ErrorMessage string `json:"errmsg"`
AccessToken string `json:"access_token"`
ExpiresIn int `json:"expires_in"`
}
type WeChatTestAccountTokenStoreItem struct {
AppID string
AppSecret string
AccessToken string
}
func (i *WeChatTestAccountTokenStoreItem) Key() string {
return i.AppID + i.AppSecret
}
func (i *WeChatTestAccountTokenStoreItem) IsShared() bool {
var count int64 = 0
model.DB.Model(&model.Channel{}).Where("secret = ? and app_id = ? and type = ?",
i.AppSecret, i.AppID, model.TypeWeChatTestAccount).Count(&count)
return count > 1
}
func (i *WeChatTestAccountTokenStoreItem) IsFilled() bool {
return i.AppID != "" && i.AppSecret != ""
}
func (i *WeChatTestAccountTokenStoreItem) Token() string {
return i.AccessToken
}
func (i *WeChatTestAccountTokenStoreItem) Refresh() {
// https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_access_token.html
client := http.Client{
Timeout: 5 * time.Second,
}
req, err := http.NewRequest("GET", fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s",
i.AppID, i.AppSecret), nil)
if err != nil {
common.SysError(err.Error())
return
}
responseData, err := client.Do(req)
if err != nil {
common.SysError("failed to refresh access token: " + err.Error())
return
}
defer responseData.Body.Close()
var res wechatTestAccountResponse
err = json.NewDecoder(responseData.Body).Decode(&res)
if err != nil {
common.SysError("failed to decode wechatTestAccountResponse: " + err.Error())
return
}
if res.ErrorCode != 0 {
common.SysError(res.ErrorMessage)
return
}
i.AccessToken = res.AccessToken
common.SysLog("access token refreshed")
}
type wechatTestAccountRequestValue struct {
Value string `json:"value"`
}
type wechatTestMessageRequest struct {
ToUser string `json:"touser"`
TemplateId string `json:"template_id"`
URL string `json:"url"`
Data struct {
Text wechatTestAccountRequestValue `json:"text"` // alias for description, for compatibility
Title wechatTestAccountRequestValue `json:"title"`
Description wechatTestAccountRequestValue `json:"description"`
Content wechatTestAccountRequestValue `json:"content"`
} `json:"data"`
}
type wechatTestMessageResponse struct {
ErrorCode int `json:"errcode"`
ErrorMessage string `json:"errmsg"`
}
func SendWeChatTestMessage(message *model.Message, user *model.User, channel_ *model.Channel) error {
// https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Template_Message_Interface.html
values := wechatTestMessageRequest{
ToUser: channel_.AccountId,
TemplateId: channel_.Other,
URL: "",
}
if message.To != "" {
values.ToUser = message.To
}
values.Data.Text.Value = message.Description
values.Data.Title.Value = message.Title
values.Data.Description.Value = message.Description
values.Data.Content.Value = message.Content
values.URL = message.URL
jsonData, err := json.Marshal(values)
if err != nil {
return err
}
key := fmt.Sprintf("%s%s", channel_.AppId, channel_.Secret)
accessToken := TokenStoreGetToken(key)
resp, err := http.Post(fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s", accessToken), "application/json",
bytes.NewBuffer(jsonData))
if err != nil {
return err
}
var res wechatTestMessageResponse
err = json.NewDecoder(resp.Body).Decode(&res)
if err != nil {
return err
}
if res.ErrorCode != 0 {
return errors.New(res.ErrorMessage)
}
return nil
}