im add wechat_robot and dingtalk_robot (#332)
* im wechat * im wechat * im add wechat_robot dingtalk_robot Co-authored-by: alickliming <alickliming@didi.global.com>
This commit is contained in:
parent
8c5e9534b2
commit
e84d7f8741
|
@ -73,7 +73,7 @@ sender:
|
||||||
worker: 10
|
worker: 10
|
||||||
api: http://127.0.0.1:2008/voice
|
api: http://127.0.0.1:2008/voice
|
||||||
im:
|
im:
|
||||||
# three choice: shell|api|wechat
|
# five choice: shell|api|wechat|wechat_robot|dingtalk_robot
|
||||||
way: shell
|
way: shell
|
||||||
worker: 10
|
worker: 10
|
||||||
api: http://127.0.0.1:2008/im
|
api: http://127.0.0.1:2008/im
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
|
|
||||||
"github.com/didi/nightingale/src/common/dataobj"
|
"github.com/didi/nightingale/src/common/dataobj"
|
||||||
"github.com/didi/nightingale/src/modules/rdb/config"
|
"github.com/didi/nightingale/src/modules/rdb/config"
|
||||||
|
"github.com/didi/nightingale/src/modules/rdb/dingtalk"
|
||||||
"github.com/didi/nightingale/src/modules/rdb/redisc"
|
"github.com/didi/nightingale/src/modules/rdb/redisc"
|
||||||
"github.com/didi/nightingale/src/modules/rdb/wechat"
|
"github.com/didi/nightingale/src/modules/rdb/wechat"
|
||||||
)
|
)
|
||||||
|
@ -50,6 +51,10 @@ func sendIm(message *dataobj.Message) {
|
||||||
sendImByShell(message)
|
sendImByShell(message)
|
||||||
case "wechat":
|
case "wechat":
|
||||||
sendImByWeChat(message)
|
sendImByWeChat(message)
|
||||||
|
case "wechat_robot":
|
||||||
|
sendImByWeChatRobot(message)
|
||||||
|
case "dingtalk_robot":
|
||||||
|
sendImByDingTalkRobot(message)
|
||||||
default:
|
default:
|
||||||
logger.Errorf("not support %s to send im, im: %+v", config.Config.Sender["im"].Way, message)
|
logger.Errorf("not support %s to send im, im: %+v", config.Config.Sender["im"].Way, message)
|
||||||
}
|
}
|
||||||
|
@ -103,3 +108,62 @@ func sendImByWeChat(message *dataobj.Message) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func sendImByWeChatRobot(message *dataobj.Message) {
|
||||||
|
cnt := len(message.Tos)
|
||||||
|
if cnt == 0 {
|
||||||
|
logger.Warningf("im send wechat_robot fail, empty tos, message: %+v", message)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < cnt; i++ {
|
||||||
|
toUser := strings.TrimSpace(message.Tos[i])
|
||||||
|
if toUser == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
mess := wechat.Message{
|
||||||
|
ToUser: toUser,
|
||||||
|
MsgType: "text",
|
||||||
|
Text: wechat.Content{Content: message.Content},
|
||||||
|
}
|
||||||
|
|
||||||
|
err := wechat.RobotSend(mess)
|
||||||
|
if err != nil {
|
||||||
|
logger.Warningf("im wechat_robot send to %s fail: %v", message.Tos[i], err)
|
||||||
|
} else {
|
||||||
|
logger.Infof("im wechat_robot send to %s succ", message.Tos[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func sendImByDingTalkRobot(message *dataobj.Message) {
|
||||||
|
cnt := len(message.Tos)
|
||||||
|
if cnt == 0 {
|
||||||
|
logger.Warningf("im send dingtalk_robot fail, empty tos, message: %+v", message)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
nodupDingCluster := make(map[string]bool, cnt)
|
||||||
|
for i := 0; i < cnt; i++ {
|
||||||
|
toUser := strings.TrimSpace(message.Tos[i])
|
||||||
|
if toUser == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := nodupDingCluster[toUser]; !ok {
|
||||||
|
nodupDingCluster[toUser] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for tokenUser, ok := range nodupDingCluster {
|
||||||
|
if ok {
|
||||||
|
err := dingtalk.RobotSend(tokenUser, message.Content)
|
||||||
|
if err != nil {
|
||||||
|
logger.Warningf("im dingtalk_robot send to %s fail: %v", tokenUser, err)
|
||||||
|
} else {
|
||||||
|
logger.Infof("im dingtalk_robot send to %s succ", tokenUser)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
package dingtalk
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Result struct {
|
||||||
|
ErrCode int `json:"errcode"`
|
||||||
|
ErrMsg string `json:"errmsg"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type dingReqData struct {
|
||||||
|
Msgtype string `json:"msgtype"`
|
||||||
|
Text *textContent `json:"text"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type textContent struct {
|
||||||
|
Content string `json:"content"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// RobotSend robot发送信息
|
||||||
|
func RobotSend(tokenUser, sendContent string) error {
|
||||||
|
url := "https://oapi.dingtalk.com/robot/send?access_token=" + tokenUser
|
||||||
|
|
||||||
|
dingReqData := new(dingReqData)
|
||||||
|
dingReqData.Msgtype = "text"
|
||||||
|
reqContent := new(textContent)
|
||||||
|
reqContent.Content = sendContent
|
||||||
|
dingReqData.Text = reqContent
|
||||||
|
|
||||||
|
content, err := json.Marshal(dingReqData)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("dingtalk marshal req data err: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
data := bytes.NewReader(content)
|
||||||
|
req, err := http.NewRequest("POST", url, data)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("dingtalk create new req err: %v", err)
|
||||||
|
}
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
|
r, err := http.DefaultClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("dingtalk do req err: %v", err)
|
||||||
|
}
|
||||||
|
defer r.Body.Close()
|
||||||
|
|
||||||
|
resp, err := ioutil.ReadAll(r.Body)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("dingtalk read req body err: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
result := Result{}
|
||||||
|
err = json.Unmarshal(resp, &result)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("dingtalk unmarshal req content err: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if result.ErrCode != 0 {
|
||||||
|
err = fmt.Errorf("dingtalk req return ErrCode = %d ErrMsg = %s", result.ErrCode, result.ErrMsg)
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
|
@ -179,3 +179,29 @@ func encodeJSON(v interface{}) ([]byte, error) {
|
||||||
}
|
}
|
||||||
return buf.Bytes(), nil
|
return buf.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RobotSend robot发送信息
|
||||||
|
func RobotSend(msg Message) error {
|
||||||
|
url := "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=" + msg.ToUser
|
||||||
|
|
||||||
|
resultByte, err := jsonPost(url, msg)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("invoke send api fail: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
result := Result{}
|
||||||
|
err = json.Unmarshal(resultByte, &result)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("parse send api response fail: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if result.ErrCode != 0 {
|
||||||
|
err = fmt.Errorf("invoke send api return ErrCode = %d", result.ErrCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
if result.InvalidUser != "" || result.InvalidParty != "" || result.InvalidTag != "" {
|
||||||
|
err = fmt.Errorf("invoke send api partial fail, invalid user: %s, invalid party: %s, invalid tag: %s", result.InvalidUser, result.InvalidParty, result.InvalidTag)
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue