wechat_push.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. log "github.com/sirupsen/logrus"
  6. "github.com/spf13/cast"
  7. "io"
  8. "net/http"
  9. "os"
  10. "pmail/config"
  11. "pmail/dto/parsemail"
  12. "pmail/hooks/framework"
  13. "pmail/utils/context"
  14. "strings"
  15. "time"
  16. )
  17. type accessTokenRes struct {
  18. AccessToken string `db:"access_token" json:"access_token"`
  19. ExpiresIn int `db:"expires_in" json:"expires_in"`
  20. }
  21. type WeChatPushHook struct {
  22. appId string
  23. secret string
  24. token string
  25. tokenExpires int64
  26. templateId string
  27. pushUser string
  28. mainConfig *config.Config
  29. }
  30. func (w *WeChatPushHook) SendBefore(ctx *context.Context, email *parsemail.Email) {
  31. }
  32. func (w *WeChatPushHook) SendAfter(ctx *context.Context, email *parsemail.Email, err map[string]error) {
  33. }
  34. func (w *WeChatPushHook) ReceiveParseBefore(ctx *context.Context, email *[]byte) {
  35. }
  36. func (w *WeChatPushHook) ReceiveParseAfter(ctx *context.Context, email *parsemail.Email) {
  37. if w.appId == "" || w.secret == "" || w.pushUser == "" {
  38. return
  39. }
  40. content := string(email.Text)
  41. if content == "" {
  42. content = email.Subject
  43. }
  44. w.sendUserMsg(nil, w.pushUser, content)
  45. }
  46. func (w *WeChatPushHook) getWxAccessToken() string {
  47. if w.tokenExpires > time.Now().Unix() {
  48. return w.token
  49. }
  50. resp, err := http.Get(fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s", w.appId, w.secret))
  51. if err != nil {
  52. return ""
  53. }
  54. body, _ := io.ReadAll(resp.Body)
  55. var ret accessTokenRes
  56. _ = json.Unmarshal(body, &ret)
  57. if ret.AccessToken != "" {
  58. w.token = ret.AccessToken
  59. w.tokenExpires = time.Now().Unix() + cast.ToInt64(ret.ExpiresIn)
  60. }
  61. return ret.AccessToken
  62. }
  63. type sendMsgRequest struct {
  64. Touser string `db:"touser" json:"touser"`
  65. Template_id string `db:"template_id" json:"template_id"`
  66. Url string `db:"url" json:"url"`
  67. Data SendData `db:"data" json:"data"`
  68. }
  69. type SendData struct {
  70. Content DataItem `json:"Content"`
  71. }
  72. type DataItem struct {
  73. Value string `json:"value"`
  74. Color string `json:"color"`
  75. }
  76. func (w *WeChatPushHook) sendUserMsg(ctx *context.Context, userId string, content string) {
  77. url := w.mainConfig.WebDomain
  78. if w.mainConfig.HttpsEnabled > 1 {
  79. url = "http://" + url
  80. } else {
  81. url = "https://" + url
  82. }
  83. sendMsgReq, _ := json.Marshal(sendMsgRequest{
  84. Touser: userId,
  85. Template_id: w.templateId,
  86. Url: url,
  87. Data: SendData{Content: DataItem{Value: content, Color: "#000000"}},
  88. })
  89. _, err := http.Post("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token="+w.getWxAccessToken(), "application/json", strings.NewReader(string(sendMsgReq)))
  90. if err != nil {
  91. log.WithContext(ctx).Errorf("wechat push error %+v", err)
  92. }
  93. }
  94. type Config struct {
  95. WeChatPushAppId string `json:"weChatPushAppId"`
  96. WeChatPushSecret string `json:"weChatPushSecret"`
  97. WeChatPushTemplateId string `json:"weChatPushTemplateId"`
  98. WeChatPushUserId string `json:"weChatPushUserId"`
  99. }
  100. func NewWechatPushHook() *WeChatPushHook {
  101. var cfgData []byte
  102. var err error
  103. cfgData, err = os.ReadFile("../config/config.json")
  104. if err != nil {
  105. panic(err)
  106. }
  107. var mainConfig *config.Config
  108. err = json.Unmarshal(cfgData, &mainConfig)
  109. if err != nil {
  110. panic(err)
  111. }
  112. var pluginConfig *Config
  113. if _, err := os.Stat("./wechat_push_config.json"); err == nil {
  114. cfgData, err = os.ReadFile("./wechat_push_config.json")
  115. if err != nil {
  116. panic(err)
  117. }
  118. err = json.Unmarshal(cfgData, &pluginConfig)
  119. if err != nil {
  120. panic(err)
  121. }
  122. }
  123. appid := ""
  124. secret := ""
  125. templateId := ""
  126. userId := ""
  127. if pluginConfig != nil {
  128. appid = pluginConfig.WeChatPushAppId
  129. secret = pluginConfig.WeChatPushSecret
  130. templateId = pluginConfig.WeChatPushTemplateId
  131. userId = pluginConfig.WeChatPushUserId
  132. } else {
  133. appid = mainConfig.WeChatPushAppId
  134. secret = mainConfig.WeChatPushSecret
  135. templateId = mainConfig.WeChatPushTemplateId
  136. userId = mainConfig.WeChatPushUserId
  137. }
  138. ret := &WeChatPushHook{
  139. appId: appid,
  140. secret: secret,
  141. templateId: templateId,
  142. pushUser: userId,
  143. mainConfig: mainConfig,
  144. }
  145. return ret
  146. }
  147. func main() {
  148. framework.CreatePlugin(NewWechatPushHook()).Run()
  149. }