From 8069000956ab4b29bc466207f9700a552e0224db Mon Sep 17 00:00:00 2001 From: marvzhang Date: Tue, 14 Jan 2020 20:03:04 +0800 Subject: [PATCH] added dingtalk --- backend/services/notification/ding_talk.go | 84 ++++++++++++++++++++++ backend/services/task.go | 4 ++ frontend/src/views/setting/Setting.vue | 16 ++++- 3 files changed, 102 insertions(+), 2 deletions(-) create mode 100644 backend/services/notification/ding_talk.go diff --git a/backend/services/notification/ding_talk.go b/backend/services/notification/ding_talk.go new file mode 100644 index 00000000..0a1dac14 --- /dev/null +++ b/backend/services/notification/ding_talk.go @@ -0,0 +1,84 @@ +package notification + +import ( + "crawlab/model" + "crawlab/utils" + "errors" + "fmt" + "github.com/apex/log" + "github.com/imroc/req" + "runtime/debug" + "time" +) + +func SendDingTalkNotification(t model.Task, s model.Spider) error { + // 获取用户 + user, _ := model.GetUser(t.UserId) + + // 如果AppKey或AppSecret未设置,则返回错误 + if user.Setting.DingTalkAppKey == "" || user.Setting.DingTalkAppSecret == "" { + return errors.New("ding_talk_app_key or ding_talk_app_secret is empty") + } + + // 获取access_token + accessToken, err := GetDingTalkAccessToken(user) + if err != nil { + return err + } + + // 时间戳 + timestamp := time.Now().Unix() + + // 计算sign + signRawString := fmt.Sprintf("%d\n%s", timestamp, user.Setting.DingTalkAppSecret) + sign := utils.ComputeHmacSha256(signRawString, user.Setting.DingTalkAppSecret) + + // 请求数据 + url := fmt.Sprintf("https://oapi.dingtalk.com/robot/send?access_token=%s", accessToken) + header := req.Header{ + "Content-Type": "application/json", + "timestamp": fmt.Sprintf("%d000", timestamp), + "sign": sign, + } + data := req.Param{ + "msgtype": "text", + "text": req.Param{ + "text": "it works", + }, + } + res, err := req.Post(url, header, req.BodyJSON(&data)) + if err != nil { + log.Errorf("dingtalk notification error: " + err.Error()) + debug.PrintStack() + return err + } + log.Infof(fmt.Sprintf("%+v", res)) + return nil +} + +func GetDingTalkAccessToken(u model.User) (string, error) { + type ResBody struct { + ErrCode int `json:"errcode"` + ErrMsg string `json:"errmsg"` + AccessToken string `json:"access_token"` + } + + // 请求数据 + url := fmt.Sprintf("https://oapi.dingtalk.com/gettoken?appkey=%s&appsecret=%s", u.Setting.DingTalkAppKey, u.Setting.DingTalkAppSecret) + res, err := req.Get(url) + if err != nil { + log.Errorf("get dingtalk access_token error: " + err.Error()) + debug.PrintStack() + return "", err + } + + // 解析相应body + var resBody ResBody + if err := res.ToJSON(&resBody); err != nil { + log.Errorf("get dingtalk access_token error: " + err.Error()) + debug.PrintStack() + return "", err + } + + return resBody.AccessToken, nil +} diff --git a/backend/services/task.go b/backend/services/task.go index 16445213..12c3580a 100644 --- a/backend/services/task.go +++ b/backend/services/task.go @@ -519,6 +519,10 @@ func ExecuteTask(id int) { if user.Email != "" && user.Setting.NotificationTrigger == constants.NotificationTriggerOnTaskEnd { SendTaskEmail(user, t, spider) + if err := notification.SendDingTalkNotification(t, spider); err != nil { + log.Errorf(err.Error()) + debug.PrintStack() + } } // 保存任务 diff --git a/frontend/src/views/setting/Setting.vue b/frontend/src/views/setting/Setting.vue index 49a38700..4ca476a5 100644 --- a/frontend/src/views/setting/Setting.vue +++ b/frontend/src/views/setting/Setting.vue @@ -33,14 +33,16 @@ v-model="userInfo.setting.ding_talk_app_secret" :placeholder="$t('DingTalk AppSecret')" /> + + @@ -104,6 +106,9 @@ export default { this.$message.success(this.$t('Saved successfully')) } }) + }, + toggleDingTalkAppSecret () { + this.isShowDingTalkAppSecret = !this.isShowDingTalkAppSecret } }, async created () { @@ -121,4 +126,11 @@ export default { .setting-form .buttons { text-align: right; } + + .setting-form .icon { + top: calc(50% - 14px / 2); + right: 14px; + position: absolute; + color: #DCDFE6; + }