From a308ddfd8b7c91a38cefcabff85663651f58031f Mon Sep 17 00:00:00 2001 From: JustSong Date: Fri, 18 Nov 2022 17:17:53 +0800 Subject: [PATCH] feat: channel WeChat test account is done --- channel/main.go | 1 + channel/token-store.go | 9 ++++-- channel/wechat-test-account.go | 52 ++++++++++++++++++++++++++++++++++ model/user.go | 5 ++++ 4 files changed, 65 insertions(+), 2 deletions(-) diff --git a/channel/main.go b/channel/main.go index d3d59d1..e2b1b33 100644 --- a/channel/main.go +++ b/channel/main.go @@ -28,6 +28,7 @@ func (message *Message) Send(user *model.User) error { case TypeEmail: return SendEmailMessage(message, user) case TypeWeChatTestAccount: + return SendWeChatTestMessage(message, user) case TypeWeChatCorpAccount: case TypeLark: case TypeDingTalk: diff --git a/channel/token-store.go b/channel/token-store.go index ef32709..42511e9 100644 --- a/channel/token-store.go +++ b/channel/token-store.go @@ -25,7 +25,7 @@ func TokenStoreInit() { s.Map = make(map[string]*TokenStoreItem) s.ExpirationSeconds = 2 * 60 * 60 go func() { - users, err := model.GetAllUsers() + users, err := model.GetAllUsersWithSecrets() if err != nil { common.FatalLog(err.Error()) } @@ -93,5 +93,10 @@ func TokenStoreRemoveItem(item *TokenStoreItem) { func TokenStoreGetToken(key string) string { s.Mutex.RLock() defer s.Mutex.RUnlock() - return (*s.Map[key]).Token() + item, ok := s.Map[key] + if ok { + return (*item).Token() + } + common.SysError("token for " + key + " is blank!") + return "" } diff --git a/channel/wechat-test-account.go b/channel/wechat-test-account.go index 3ae4f3f..eb7390a 100644 --- a/channel/wechat-test-account.go +++ b/channel/wechat-test-account.go @@ -1,9 +1,12 @@ package channel import ( + "bytes" "encoding/json" + "errors" "fmt" "message-pusher/common" + "message-pusher/model" "net/http" "time" ) @@ -59,3 +62,52 @@ func (i *WeChatTestAccountTokenStoreItem) Refresh() { i.AccessToken = res.AccessToken common.SysLog("access token refreshed") } + +type wechatTestMessageRequest struct { + ToUser string `json:"touser"` + TemplateId string `json:"template_id"` + URL string `json:"url"` + Data struct { + Text struct { + Value string `json:"value"` + } `json:"text"` + } `json:"data"` +} + +type wechatTestMessageResponse struct { + ErrorCode int `json:"errcode"` + ErrorMessage string `json:"errmsg"` +} + +func SendWeChatTestMessage(message *Message, user *model.User) error { + if user.WeChatTestAccountId == "" { + return errors.New("未配置微信测试号消息推送方式") + } + values := wechatTestMessageRequest{ + ToUser: user.WeChatTestAccountOpenId, + TemplateId: user.WeChatTestAccountTemplateId, + URL: "", + } + // TODO: render content and set URL + values.Data.Text.Value = message.Description + jsonData, err := json.Marshal(values) + if err != nil { + return err + } + key := fmt.Sprintf("%s%s", user.WeChatTestAccountId, user.WeChatTestAccountSecret) + 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 +} diff --git a/model/user.go b/model/user.go index 36564bc..cb20ce1 100644 --- a/model/user.go +++ b/model/user.go @@ -40,6 +40,11 @@ func GetAllUsers() (users []*User, err error) { return users, err } +func GetAllUsersWithSecrets() (users []*User, err error) { + err = DB.Find(&users).Error + return users, err +} + func SearchUsers(keyword string) (users []*User, err error) { err = DB.Select([]string{"id", "username", "display_name", "role", "status", "email"}).Where("id = ? or username LIKE ? or email LIKE ? or display_name LIKE ?", keyword, keyword+"%", keyword+"%", keyword+"%").Find(&users).Error return users, err