notification-dingtalk/dingtalk_notification.go (122 lines of code) (raw):

/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package dingtalk import ( "embed" "strings" dingtalkI18n "github.com/apache/answer-plugins/notification-dingtalk/i18n" "github.com/apache/answer-plugins/util" "github.com/apache/answer/plugin" "github.com/go-resty/resty/v2" "github.com/segmentfault/pacman/i18n" "github.com/segmentfault/pacman/log" ) //go:embed info.yaml var Info embed.FS type Notification struct { Config *NotificationConfig UserConfigCache *UserConfigCache } func init() { uc := &Notification{ Config: &NotificationConfig{}, UserConfigCache: NewUserConfigCache(), } plugin.Register(uc) } func (n *Notification) Info() plugin.Info { info := &util.Info{} info.GetInfo(Info) return plugin.Info{ Name: plugin.MakeTranslator(dingtalkI18n.InfoName), SlugName: info.SlugName, Description: plugin.MakeTranslator(dingtalkI18n.InfoDescription), Author: info.Author, Version: info.Version, Link: info.Link, } } // GetNewQuestionSubscribers returns the subscribers of the new question notification func (n *Notification) GetNewQuestionSubscribers() (userIDs []string) { for userID, conf := range n.UserConfigCache.userConfigMapping { if conf.AllNewQuestions { userIDs = append(userIDs, userID) } } return userIDs } // Notify sends a notification to the user func (n *Notification) Notify(msg plugin.NotificationMessage) { log.Debugf("try to send notification %+v", msg) if !n.Config.Notification { return } // get user config userConfig, err := n.getUserConfig(msg.ReceiverUserID) if err != nil { log.Errorf("get user config failed: %v", err) return } if userConfig == nil { log.Debugf("user %s has no config", msg.ReceiverUserID) return } // check if the notification is enabled switch msg.Type { case plugin.NotificationNewQuestion: if !userConfig.AllNewQuestions { log.Debugf("user %s not config the new question", msg.ReceiverUserID) return } case plugin.NotificationNewQuestionFollowedTag: if !userConfig.NewQuestionsForFollowingTags { log.Debugf("user %s not config the new question followed tag", msg.ReceiverUserID) return } default: if !userConfig.InboxNotifications { log.Debugf("user %s not config the inbox notification", msg.ReceiverUserID) return } } log.Debugf("user %s config the notification", msg.ReceiverUserID) if len(userConfig.WebhookURL) == 0 { log.Errorf("user %s has no webhook url", msg.ReceiverUserID) return } notificationMsg, notificationTitle := renderNotification(msg) // no need to send empty message if len(notificationMsg) == 0 { log.Debugf("this type of notification will be drop, the type is %s", msg.Type) return } // Create a Resty Client client := resty.New() resp, err := client.R(). SetHeader("Content-Type", "application/json"). SetBody(NewWebhookReq(notificationMsg, notificationTitle)). Post(userConfig.WebhookURL) if err != nil { log.Errorf("send message failed: %v %v", err, resp) } else { log.Infof("send message to %s success, resp: %s", msg.ReceiverUserID, resp.String()) } } func renderNotification(msg plugin.NotificationMessage) (string, string) { lang := i18n.Language(msg.ReceiverLang) switch msg.Type { case plugin.NotificationUpdateQuestion: return plugin.TranslateWithData(lang, dingtalkI18n.TplUpdateQuestion, msg), plugin.TranslateWithData(lang, dingtalkI18n.TplUpdateQuestionTitle, nil) case plugin.NotificationAnswerTheQuestion: return plugin.TranslateWithData(lang, dingtalkI18n.TplAnswerTheQuestion, msg), plugin.TranslateWithData(lang, dingtalkI18n.TplAnswerTheQuestionTitle, nil) case plugin.NotificationUpdateAnswer: return plugin.TranslateWithData(lang, dingtalkI18n.TplUpdateAnswer, msg), plugin.TranslateWithData(lang, dingtalkI18n.TplUpdateAnswerTitle, nil) case plugin.NotificationAcceptAnswer: return plugin.TranslateWithData(lang, dingtalkI18n.TplAcceptAnswer, msg), plugin.TranslateWithData(lang, dingtalkI18n.TplAcceptAnswerTitle, nil) case plugin.NotificationCommentQuestion: return plugin.TranslateWithData(lang, dingtalkI18n.TplCommentQuestion, msg), plugin.TranslateWithData(lang, dingtalkI18n.TplCommentQuestionTitle, nil) case plugin.NotificationCommentAnswer: return plugin.TranslateWithData(lang, dingtalkI18n.TplCommentAnswer, msg), plugin.TranslateWithData(lang, dingtalkI18n.TplCommentAnswerTitle, nil) case plugin.NotificationReplyToYou: return plugin.TranslateWithData(lang, dingtalkI18n.TplReplyToYou, msg), plugin.TranslateWithData(lang, dingtalkI18n.TplReplyToYouTitle, nil) case plugin.NotificationMentionYou: return plugin.TranslateWithData(lang, dingtalkI18n.TplMentionYou, msg), plugin.TranslateWithData(lang, dingtalkI18n.TplMentionYouTitle, nil) case plugin.NotificationInvitedYouToAnswer: return plugin.TranslateWithData(lang, dingtalkI18n.TplInvitedYouToAnswer, msg), plugin.TranslateWithData(lang, dingtalkI18n.TplInvitedYouToAnswerTitle, nil) case plugin.NotificationNewQuestion, plugin.NotificationNewQuestionFollowedTag: msg.QuestionTags = strings.Join(strings.Split(msg.QuestionTags, ","), ", ") return plugin.TranslateWithData(lang, dingtalkI18n.TplNewQuestion, msg), plugin.TranslateWithData(lang, dingtalkI18n.TplNewQuestionTitle, nil) } return "", "" }