sender.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. package sender
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "errors"
  6. "io/ioutil"
  7. "log"
  8. "net/http"
  9. "os/exec"
  10. "path"
  11. "strings"
  12. "syscall"
  13. "time"
  14. "github.com/710leo/urlooker/dataobj"
  15. "github.com/710leo/urlooker/modules/alarm/backend"
  16. "github.com/710leo/urlooker/modules/alarm/cache"
  17. "github.com/710leo/urlooker/modules/alarm/g"
  18. "github.com/710leo/urlooker/modules/web/api"
  19. "github.com/toolkits/file"
  20. "github.com/toolkits/smtp"
  21. "github.com/toolkits/sys"
  22. )
  23. var (
  24. SmsWorkerChan chan int
  25. MailWorkerChan chan int
  26. WeChatWorkerChan chan int
  27. requestError = errors.New("request error,check url or network")
  28. )
  29. const (
  30. // 发送消息使用导的url
  31. sendUrl = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token="
  32. // 获取token使用导的url
  33. getToken = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid="
  34. )
  35. func Init() {
  36. workerConfig := g.Config.Worker
  37. SmsWorkerChan = make(chan int, workerConfig.Sms)
  38. MailWorkerChan = make(chan int, workerConfig.Mail)
  39. WeChatWorkerChan = make(chan int, workerConfig.WeChat)
  40. }
  41. func SendEvent(event *dataobj.Event) {
  42. mail := make([]string, 0)
  43. sms := make([]string, 0)
  44. weChat := make([]string, 0)
  45. users := getUsers(event.StrategyId)
  46. mailContent := BuildMail(event)
  47. smsContent := BuildSms(event)
  48. weChatContent := BuildWeChat(event)
  49. for _, user := range users {
  50. mail = append(mail, user.Email)
  51. sms = append(sms, user.Phone)
  52. weChat = append(weChat, user.Wechat)
  53. }
  54. WriteSms(sms, smsContent)
  55. WriteMail(mail, smsContent, mailContent)
  56. WriteWeChat(weChat, weChatContent)
  57. }
  58. func sendSms(phone string, sms string) {
  59. defer func() {
  60. <-SmsWorkerChan
  61. }()
  62. smsShell := path.Join(file.SelfDir(), "script", "sms.sh")
  63. if !file.IsExist(smsShell) {
  64. log.Printf("%s not found", smsShell)
  65. return
  66. }
  67. cmd := exec.Command(smsShell, phone, "'"+sms+"'")
  68. cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
  69. err := cmd.Start()
  70. if err != nil {
  71. log.Printf("start cmd err: %v shell:%v", err, smsShell)
  72. }
  73. err, isTimeout := sys.CmdRunWithTimeout(cmd, time.Second*10)
  74. log.Printf("%s %s %s", smsShell, phone, sms)
  75. if err != nil {
  76. log.Printf("err: %v, isTimeout: %v", err, isTimeout)
  77. }
  78. return
  79. }
  80. func sendMail(mail *g.Mail) {
  81. defer func() {
  82. <-MailWorkerChan
  83. }()
  84. //s := smtp.New(g.Config.Smtp.Addr, g.Config.Smtp.Username, g.Config.Smtp.Password)
  85. s := smtp.NewSMTP(g.Config.Smtp.Addr, g.Config.Smtp.Username, g.Config.Smtp.Password, g.Config.Smtp.Tls, false, false)
  86. err := s.SendMail(g.Config.Smtp.From, strings.Replace(mail.Tos, ",", ";", -1), mail.Subject, mail.Content, "text")
  87. if err != nil {
  88. log.Printf("send mail err:%v tos:%v\n", err, mail.Tos)
  89. return
  90. }
  91. if g.Config.Debug {
  92. log.Println("==mail==>>>>", mail)
  93. }
  94. }
  95. func sendWeChat(weChat *g.WeChat) {
  96. defer func() {
  97. <-WeChatWorkerChan
  98. }()
  99. var msg = weChatMsg{
  100. ToUser: weChat.Tos,
  101. ToParty: g.Config.WeChat.ToParty,
  102. MsgType: "text",
  103. AgentId: g.Config.WeChat.AgentId,
  104. Text: map[string]string{"content": weChat.Content},
  105. }
  106. token, err := GetToken(g.Config.WeChat.CorpId, g.Config.WeChat.CorpSecret)
  107. buf, err := json.Marshal(msg)
  108. if err != nil {
  109. log.Println(err, "get weChat token error")
  110. }
  111. err = SendMsg(token.AccessToken, buf)
  112. if err != nil {
  113. log.Println(err, "send weChat")
  114. } else {
  115. log.Println("==weChat==>>>>", weChat)
  116. log.Println("<<<<==weChatMsg==", string(buf))
  117. }
  118. }
  119. func getUsers(sid int64) []*dataobj.User {
  120. var usersResp api.UsersResponse
  121. var users []*dataobj.User
  122. strategy, exists := cache.StrategyMap.Get(sid)
  123. if !exists {
  124. log.Printf("strategyId: %d not exists", sid)
  125. return users
  126. }
  127. err := backend.CallRpc("Web.GetUsersByTeam", strategy.Teams, &usersResp)
  128. if err != nil {
  129. log.Println("Web.GetUsersByTeam Error:", err)
  130. return users
  131. }
  132. if usersResp.Message != "" {
  133. log.Println("Web.GetUsersByTeam Error:", usersResp.Message)
  134. return users
  135. }
  136. users = usersResp.Data
  137. return users
  138. }
  139. // 定义微信文本消息结构体
  140. type weChatMsg struct {
  141. ToUser string `json:"touser"`
  142. ToParty string `json:"toparty"`
  143. MsgType string `json:"msgtype"`
  144. AgentId int `json:"agentid"`
  145. Text map[string]string `json:"text"`
  146. Safe int `json:"safe"`
  147. }
  148. // 定义微信错误返回结构体
  149. type sendMsgError struct {
  150. ErrCode int `json:"errcode`
  151. ErrMsg string `json:"errmsg"`
  152. }
  153. // 定义token结构体
  154. type accessToken struct {
  155. AccessToken string `json:"access_token"`
  156. ExpiresIn int `json:"expires_in"`
  157. }
  158. // 获取返回
  159. func GetToken(corpId, corpSecret string) (at accessToken, err error) {
  160. resp, err := http.Get(getToken + corpId + "&corpSecret=" + corpSecret)
  161. if err != nil {
  162. return
  163. }
  164. defer resp.Body.Close()
  165. if resp.StatusCode != 200 {
  166. err = requestError
  167. return
  168. }
  169. buf, _ := ioutil.ReadAll(resp.Body)
  170. err = json.Unmarshal(buf, &at)
  171. if at.AccessToken == "" {
  172. err = errors.New("微信企业号中的标识或者应用Secret错误")
  173. }
  174. return
  175. }
  176. // 发送微信
  177. func SendMsg(AccessToken string, msgBody []byte) error {
  178. body := bytes.NewBuffer(msgBody)
  179. resp, err := http.Post(sendUrl+AccessToken, "application/json", body)
  180. if resp.StatusCode != 200 {
  181. return requestError
  182. }
  183. buf, _ := ioutil.ReadAll(resp.Body)
  184. resp.Body.Close()
  185. var e sendMsgError
  186. err = json.Unmarshal(buf, &e)
  187. if err != nil {
  188. return err
  189. }
  190. if e.ErrCode != 0 && e.ErrMsg != "ok" {
  191. return errors.New(string(buf))
  192. }
  193. return nil
  194. }