123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- package channel
- import (
- "bytes"
- "encoding/json"
- "errors"
- "fmt"
- "message-pusher/common"
- "message-pusher/model"
- "net/http"
- "strings"
- "time"
- )
- type wechatCorpAccountResponse struct {
- ErrorCode int `json:"errcode"`
- ErrorMessage string `json:"errmsg"`
- AccessToken string `json:"access_token"`
- ExpiresIn int `json:"expires_in"`
- }
- type WeChatCorpAccountTokenStoreItem struct {
- CorpId string
- AgentSecret string
- AgentId string
- AccessToken string
- }
- func (i *WeChatCorpAccountTokenStoreItem) Key() string {
- return i.CorpId + i.AgentId + i.AgentSecret
- }
- func (i *WeChatCorpAccountTokenStoreItem) IsShared() bool {
- appId := fmt.Sprintf("%s|%s", i.CorpId, i.AgentId)
- var count int64 = 0
- model.DB.Model(&model.Channel{}).Where("secret = ? and app_id = ? and type = ?",
- i.AgentSecret, appId, model.TypeWeChatCorpAccount).Count(&count)
- return count > 1
- }
- func (i *WeChatCorpAccountTokenStoreItem) IsFilled() bool {
- return i.CorpId != "" && i.AgentSecret != "" && i.AgentId != ""
- }
- func (i *WeChatCorpAccountTokenStoreItem) Token() string {
- return i.AccessToken
- }
- func (i *WeChatCorpAccountTokenStoreItem) Refresh() {
- // https://work.weixin.qq.com/api/doc/90000/90135/91039
- client := http.Client{
- Timeout: 5 * time.Second,
- }
- req, err := http.NewRequest("GET", fmt.Sprintf("https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=%s&corpsecret=%s",
- i.CorpId, i.AgentSecret), 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 wechatCorpAccountResponse
- err = json.NewDecoder(responseData.Body).Decode(&res)
- if err != nil {
- common.SysError("failed to decode wechatCorpAccountResponse: " + err.Error())
- return
- }
- if res.ErrorCode != 0 {
- common.SysError(res.ErrorMessage)
- return
- }
- i.AccessToken = res.AccessToken
- common.SysLog("access token refreshed")
- }
- type wechatCorpMessageRequest struct {
- MessageType string `json:"msgtype"`
- ToUser string `json:"touser"`
- AgentId string `json:"agentid"`
- TextCard struct {
- Title string `json:"title"`
- Description string `json:"description"`
- URL string `json:"url"`
- } `json:"textcard"`
- Text struct {
- Content string `json:"content"`
- } `json:"text"`
- Markdown struct {
- Content string `json:"content"`
- } `json:"markdown"`
- }
- type wechatCorpMessageResponse struct {
- ErrorCode int `json:"errcode"`
- ErrorMessage string `json:"errmsg"`
- }
- func parseWechatCorpAccountAppId(appId string) (string, string, error) {
- parts := strings.Split(appId, "|")
- if len(parts) != 2 {
- return "", "", errors.New("无效的微信企业号配置")
- }
- return parts[0], parts[1], nil
- }
- func SendWeChatCorpMessage(message *model.Message, user *model.User, channel_ *model.Channel) error {
- // https://developer.work.weixin.qq.com/document/path/90236
- corpId, agentId, err := parseWechatCorpAccountAppId(channel_.AppId)
- if err != nil {
- return err
- }
- userId := channel_.AccountId
- clientType := channel_.Other
- agentSecret := channel_.Secret
- messageRequest := wechatCorpMessageRequest{
- ToUser: userId,
- AgentId: agentId,
- }
- if message.To != "" {
- messageRequest.ToUser = message.To
- }
- if message.Content == "" {
- if message.Title == "" {
- messageRequest.MessageType = "text"
- messageRequest.Text.Content = message.Description
- } else {
- messageRequest.MessageType = "textcard"
- messageRequest.TextCard.Title = message.Title
- messageRequest.TextCard.Description = message.Description
- messageRequest.TextCard.URL = common.ServerAddress
- }
- } else {
- if clientType == "plugin" {
- messageRequest.MessageType = "textcard"
- messageRequest.TextCard.Title = message.Title
- messageRequest.TextCard.Description = message.Description
- messageRequest.TextCard.URL = message.URL
- } else {
- messageRequest.MessageType = "markdown"
- messageRequest.Markdown.Content = message.Content
- }
- }
- jsonData, err := json.Marshal(messageRequest)
- if err != nil {
- return err
- }
- key := fmt.Sprintf("%s%s%s", corpId, agentId, agentSecret)
- accessToken := TokenStoreGetToken(key)
- resp, err := http.Post(fmt.Sprintf("https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=%s", accessToken), "application/json",
- bytes.NewBuffer(jsonData))
- if err != nil {
- return err
- }
- var res wechatCorpMessageResponse
- err = json.NewDecoder(resp.Body).Decode(&res)
- if err != nil {
- return err
- }
- if res.ErrorCode != 0 {
- return errors.New(res.ErrorMessage)
- }
- return nil
- }
|