123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- package sender
- import (
- "bytes"
- "encoding/json"
- "errors"
- "io/ioutil"
- "log"
- "net/http"
- "os/exec"
- "path"
- "strings"
- "syscall"
- "time"
- "github.com/710leo/urlooker/dataobj"
- "github.com/710leo/urlooker/modules/alarm/backend"
- "github.com/710leo/urlooker/modules/alarm/cache"
- "github.com/710leo/urlooker/modules/alarm/g"
- "github.com/710leo/urlooker/modules/web/api"
- "github.com/toolkits/file"
- "github.com/toolkits/smtp"
- "github.com/toolkits/sys"
- )
- var (
- SmsWorkerChan chan int
- MailWorkerChan chan int
- WeChatWorkerChan chan int
- requestError = errors.New("request error,check url or network")
- )
- const (
- // 发送消息使用导的url
- sendUrl = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token="
- // 获取token使用导的url
- getToken = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid="
- )
- func Init() {
- workerConfig := g.Config.Worker
- SmsWorkerChan = make(chan int, workerConfig.Sms)
- MailWorkerChan = make(chan int, workerConfig.Mail)
- WeChatWorkerChan = make(chan int, workerConfig.WeChat)
- }
- func SendEvent(event *dataobj.Event) {
- mail := make([]string, 0)
- sms := make([]string, 0)
- weChat := make([]string, 0)
- users := getUsers(event.StrategyId)
- mailContent := BuildMail(event)
- smsContent := BuildSms(event)
- weChatContent := BuildWeChat(event)
- for _, user := range users {
- mail = append(mail, user.Email)
- sms = append(sms, user.Phone)
- weChat = append(weChat, user.Wechat)
- }
- WriteSms(sms, smsContent)
- WriteMail(mail, smsContent, mailContent)
- WriteWeChat(weChat, weChatContent)
- }
- func sendSms(phone string, sms string) {
- defer func() {
- <-SmsWorkerChan
- }()
- smsShell := path.Join(file.SelfDir(), "script", "sms.sh")
- if !file.IsExist(smsShell) {
- log.Printf("%s not found", smsShell)
- return
- }
- cmd := exec.Command(smsShell, phone, "'"+sms+"'")
- cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
- err := cmd.Start()
- if err != nil {
- log.Printf("start cmd err: %v shell:%v", err, smsShell)
- }
- err, isTimeout := sys.CmdRunWithTimeout(cmd, time.Second*10)
- log.Printf("%s %s %s", smsShell, phone, sms)
- if err != nil {
- log.Printf("err: %v, isTimeout: %v", err, isTimeout)
- }
- return
- }
- func sendMail(mail *g.Mail) {
- defer func() {
- <-MailWorkerChan
- }()
- //s := smtp.New(g.Config.Smtp.Addr, g.Config.Smtp.Username, g.Config.Smtp.Password)
- s := smtp.NewSMTP(g.Config.Smtp.Addr, g.Config.Smtp.Username, g.Config.Smtp.Password, g.Config.Smtp.Tls, false, false)
- err := s.SendMail(g.Config.Smtp.From, strings.Replace(mail.Tos, ",", ";", -1), mail.Subject, mail.Content, "text")
- if err != nil {
- log.Printf("send mail err:%v tos:%v\n", err, mail.Tos)
- return
- }
- if g.Config.Debug {
- log.Println("==mail==>>>>", mail)
- }
- }
- func sendWeChat(weChat *g.WeChat) {
- defer func() {
- <-WeChatWorkerChan
- }()
- var msg = weChatMsg{
- ToUser: weChat.Tos,
- ToParty: g.Config.WeChat.ToParty,
- MsgType: "text",
- AgentId: g.Config.WeChat.AgentId,
- Text: map[string]string{"content": weChat.Content},
- }
- token, err := GetToken(g.Config.WeChat.CorpId, g.Config.WeChat.CorpSecret)
- buf, err := json.Marshal(msg)
- if err != nil {
- log.Println(err, "get weChat token error")
- }
- err = SendMsg(token.AccessToken, buf)
- if err != nil {
- log.Println(err, "send weChat")
- } else {
- log.Println("==weChat==>>>>", weChat)
- log.Println("<<<<==weChatMsg==", string(buf))
- }
- }
- func getUsers(sid int64) []*dataobj.User {
- var usersResp api.UsersResponse
- var users []*dataobj.User
- strategy, exists := cache.StrategyMap.Get(sid)
- if !exists {
- log.Printf("strategyId: %d not exists", sid)
- return users
- }
- err := backend.CallRpc("Web.GetUsersByTeam", strategy.Teams, &usersResp)
- if err != nil {
- log.Println("Web.GetUsersByTeam Error:", err)
- return users
- }
- if usersResp.Message != "" {
- log.Println("Web.GetUsersByTeam Error:", usersResp.Message)
- return users
- }
- users = usersResp.Data
- return users
- }
- // 定义微信文本消息结构体
- type weChatMsg struct {
- ToUser string `json:"touser"`
- ToParty string `json:"toparty"`
- MsgType string `json:"msgtype"`
- AgentId int `json:"agentid"`
- Text map[string]string `json:"text"`
- Safe int `json:"safe"`
- }
- // 定义微信错误返回结构体
- type sendMsgError struct {
- ErrCode int `json:"errcode`
- ErrMsg string `json:"errmsg"`
- }
- // 定义token结构体
- type accessToken struct {
- AccessToken string `json:"access_token"`
- ExpiresIn int `json:"expires_in"`
- }
- // 获取返回
- func GetToken(corpId, corpSecret string) (at accessToken, err error) {
- resp, err := http.Get(getToken + corpId + "&corpSecret=" + corpSecret)
- if err != nil {
- return
- }
- defer resp.Body.Close()
- if resp.StatusCode != 200 {
- err = requestError
- return
- }
- buf, _ := ioutil.ReadAll(resp.Body)
- err = json.Unmarshal(buf, &at)
- if at.AccessToken == "" {
- err = errors.New("微信企业号中的标识或者应用Secret错误")
- }
- return
- }
- // 发送微信
- func SendMsg(AccessToken string, msgBody []byte) error {
- body := bytes.NewBuffer(msgBody)
- resp, err := http.Post(sendUrl+AccessToken, "application/json", body)
- if resp.StatusCode != 200 {
- return requestError
- }
- buf, _ := ioutil.ReadAll(resp.Body)
- resp.Body.Close()
- var e sendMsgError
- err = json.Unmarshal(buf, &e)
- if err != nil {
- return err
- }
- if e.ErrCode != 0 && e.ErrMsg != "ok" {
- return errors.New(string(buf))
- }
- return nil
- }
|