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
|
||||
api: http://127.0.0.1:2008/voice
|
||||
im:
|
||||
# three choice: shell|api|wechat
|
||||
# five choice: shell|api|wechat|wechat_robot|dingtalk_robot
|
||||
way: shell
|
||||
worker: 10
|
||||
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/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/wechat"
|
||||
)
|
||||
|
@ -50,6 +51,10 @@ func sendIm(message *dataobj.Message) {
|
|||
sendImByShell(message)
|
||||
case "wechat":
|
||||
sendImByWeChat(message)
|
||||
case "wechat_robot":
|
||||
sendImByWeChatRobot(message)
|
||||
case "dingtalk_robot":
|
||||
sendImByDingTalkRobot(message)
|
||||
default:
|
||||
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
|
||||
}
|
||||
|
||||
// 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