Skip to content

Commit

Permalink
feat: enhancement on notification
Browse files Browse the repository at this point in the history
  • Loading branch information
tikazyq committed Jul 8, 2023
1 parent 7375718 commit 70ccfc4
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 173 deletions.
13 changes: 4 additions & 9 deletions constants/notification.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
package constants

const (
NotificationTriggerOnTaskEnd = "notification_trigger_on_task_end"
NotificationTriggerOnTaskError = "notification_trigger_on_task_error"
NotificationTriggerNever = "notification_trigger_never"
)

const (
NotificationTypeMail = "notification_type_mail"
NotificationTypeDingTalk = "notification_type_ding_talk"
NotificationTypeWechat = "notification_type_wechat"
NotificationTriggerTaskFinish = "task_finish"
NotificationTriggerTaskError = "task_error"
NotificationTriggerTaskEmptyResults = "task_empty_results"
NotificationTriggerTaskNever = "task_never"
)
14 changes: 0 additions & 14 deletions controllers/notification.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,6 @@ var NotificationController ActionController
func getNotificationActions() []Action {
ctx := newNotificationContext()
return []Action{
{
Method: http.MethodGet,
Path: "/triggers",
HandlerFunc: ctx.GetTriggerList,
},
{
Method: http.MethodGet,
Path: "/settings",
Expand Down Expand Up @@ -59,15 +54,6 @@ type notificationContext struct {
svc *notification.Service
}

func (ctx *notificationContext) GetTriggerList(c *gin.Context) {
res, total, err := ctx.svc.GetTriggerList()
if err != nil {
HandleErrorInternalServerError(c, err)
return
}
HandleSuccessWithListData(c, res, total)
}

func (ctx *notificationContext) GetSettingList(c *gin.Context) {
query := MustGetFilterQuery(c)
pagination := MustGetPagination(c)
Expand Down
1 change: 1 addition & 0 deletions models/models/setting.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

type Setting struct {
Id primitive.ObjectID `json:"_id" bson:"_id"`
Type string `json:"type" bson:"type"`
Key string `json:"key" bson:"key"`
Value bson.M `json:"value" bson:"value"`
}
Expand Down
2 changes: 1 addition & 1 deletion notification/mail.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func SendMail(s *Setting, to, cc, title, content string) error {
Product: hermes.Product{
Logo: "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzAwIiBoZWlnaHQ9IjMwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxnIGZpbGw9Im5vbmUiPgogICAgICAgIDxjaXJjbGUgY3g9IjE1MCIgY3k9IjE1MCIgcj0iMTMwIiBmaWxsPSJub25lIiBzdHJva2Utd2lkdGg9IjQwIiBzdHJva2U9IiM0MDllZmYiPgogICAgICAgIDwvY2lyY2xlPgogICAgICAgIDxjaXJjbGUgY3g9IjE1MCIgY3k9IjE1MCIgcj0iMTEwIiBmaWxsPSJ3aGl0ZSI+CiAgICAgICAgPC9jaXJjbGU+CiAgICAgICAgPGNpcmNsZSBjeD0iMTUwIiBjeT0iMTUwIiByPSI3MCIgZmlsbD0iIzQwOWVmZiI+CiAgICAgICAgPC9jaXJjbGU+CiAgICAgICAgPHBhdGggZD0iCiAgICAgICAgICAgIE0gMTUwLDE1MAogICAgICAgICAgICBMIDI4MCwyMjUKICAgICAgICAgICAgQSAxNTAsMTUwIDkwIDAgMCAyODAsNzUKICAgICAgICAgICAgIiBmaWxsPSIjNDA5ZWZmIj4KICAgICAgICA8L3BhdGg+CiAgICA8L2c+Cjwvc3ZnPgo=",
Name: "Crawlab",
Copyright: 2021 Crawlab-Team",
Copyright: 2023 Crawlab-Team",
},
}

Expand Down
13 changes: 1 addition & 12 deletions notification/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ type Setting struct {
Global bool `json:"global" bson:"global"`
Title string `json:"title,omitempty" bson:"title,omitempty"`
Template string `json:"template,omitempty" bson:"template,omitempty"`
Triggers []string `json:"triggers" bson:"triggers"`
Targets []SettingTarget `json:"targets" bson:"targets"` // TODO: implement
TaskTrigger string `json:"task_trigger" bson:"task_trigger"`
Mail SettingMail `json:"mail,omitempty" bson:"mail,omitempty"`
Mobile SettingMobile `json:"mobile,omitempty" bson:"mobile,omitempty"`
}
Expand All @@ -31,13 +30,3 @@ type SettingMail struct {
type SettingMobile struct {
Webhook string `json:"webhook" bson:"webhook"`
}

type SettingTarget struct {
Id primitive.ObjectID `json:"_id" bson:"_id"`
Model string `json:"model" bson:"model"`
}

type SettingTrigger struct {
Name string `json:"name" bson:"name"`
Event string `json:"event" bson:"event"`
}
175 changes: 38 additions & 137 deletions notification/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"github.com/crawlab-team/crawlab-core/entity"
"github.com/crawlab-team/crawlab-core/grpc/client"
"github.com/crawlab-team/crawlab-core/interfaces"
"github.com/crawlab-team/crawlab-core/models/delegate"
"github.com/crawlab-team/crawlab-core/models/models"
"github.com/crawlab-team/crawlab-core/models/service"
"github.com/crawlab-team/crawlab-core/node/config"
Expand Down Expand Up @@ -38,18 +37,17 @@ type Service struct {
}

func (svc *Service) Init() (err error) {
if !utils.IsPro() {
return nil
}

// handle events
go svc.handleEvents()

return nil
}

func (svc *Service) Start() (err error) {
// init plugin data
if err := svc.initPluginData(); err != nil {
return err
}

// start grpc client
if !svc.c.IsStarted() {
if err := svc.c.Start(); err != nil {
Expand Down Expand Up @@ -137,88 +135,6 @@ func (svc *Service) _subscribe() (err error) {
return
}

func (svc *Service) initPluginData() (err error) {
op := func() error {
if _, err := svc.modelSvc.GetPluginByName(PluginName); err != nil {
// error
if err.Error() != mongo.ErrNoDocuments.Error() {
return err
}

// not exists, add
pluginData := []byte(`{
"name": "notification",
"short_name": "plugin-notification",
"full_name": "crawlab-team/plugin-notification",
"description": "A plugin for handling notifications",
"proto": "http",
"cmd": "sh ./bin/start.sh",
"docker_cmd": "/app/plugins/bin/plugin-notification",
"docker_dir": "/app/plugins/plugin-notification",
"endpoint": "localhost:39999",
"event_key": {
"include": "^model:",
"exclude": "artifact"
},
"install_url": "https://github.com/crawlab-team/plugin-notification",
"deploy_mode": "master_only",
"auto_start": true,
"lang_url": "ui/lang",
"ui_components": [
{
"name": "notification-list",
"title": "Notifications",
"src": "ui/src/NotificationList.vue",
"type": "view",
"path": "notifications"
},
{
"name": "notification-detail",
"title": "Notifications",
"src": "ui/src/NotificationDetail.vue",
"type": "view",
"path": "notifications/:id"
}
],
"ui_sidebar_navs": [
{
"path": "/notifications",
"title": "plugins.notification.ui_sidebar_navs.title.notifications",
"icon": [
"fa",
"envelope"
]
}
],
"ui_assets": [
{
"path": "ui/public/simplemde/simplemde.js",
"type": "js"
},
{
"path": "ui/public/simplemde/simplemde.css",
"type": "css"
},
{
"path": "ui/public/css/style.css",
"type": "css"
}
]
}
`)
var p models.Plugin
_ = json.Unmarshal(pluginData, &p)
if err := delegate.NewModelDelegate(&p).Add(); err != nil {
return err
}
}

// exists, skip
return nil
}
return backoff.Retry(op, backoff.NewConstantBackOff(1*time.Second))
}

func (svc *Service) initData() (err error) {
total, err := svc.col.Count(nil)
if err != nil {
Expand All @@ -236,10 +152,8 @@ func (svc *Service) initData() (err error) {
Enabled: true,
Name: "Task Change (Mail)",
Description: "This is the default mail notification. You can edit it with your own settings",
Triggers: []string{
"model:tasks:change",
},
Title: "[Crawlab] Task Update: {{$.status}}",
TaskTrigger: constants.NotificationTriggerTaskError,
Title: "[Crawlab] Task Update: {{$.status}}",
Template: `Dear {{$.user.username}},
Please find the task data as below.
Expand Down Expand Up @@ -280,10 +194,8 @@ Please find the task data as below.
Enabled: true,
Name: "Task Change (Mobile)",
Description: "This is the default mobile notification. You can edit it with your own settings",
Triggers: []string{
"model:tasks:change",
},
Title: "[Crawlab] Task Update: {{$.status}}",
TaskTrigger: constants.NotificationTriggerTaskError,
Title: "[Crawlab] Task Update: {{$.status}}",
Template: `Dear {{$.user.username}},
Please find the task data as below.
Expand Down Expand Up @@ -386,43 +298,6 @@ func (svc *Service) sendMobile(s *Setting, entity bson.M) (err error) {
return nil
}

func (svc *Service) GetTriggerList() (res []string, total int, err error) {
modelList := []string{
interfaces.ModelColNameTag,
interfaces.ModelColNameNode,
interfaces.ModelColNameProject,
interfaces.ModelColNameSpider,
interfaces.ModelColNameTask,
interfaces.ModelColNameJob,
interfaces.ModelColNameSchedule,
interfaces.ModelColNameUser,
interfaces.ModelColNameSetting,
interfaces.ModelColNameToken,
interfaces.ModelColNameVariable,
interfaces.ModelColNameTaskStat,
interfaces.ModelColNamePlugin,
interfaces.ModelColNameSpiderStat,
interfaces.ModelColNameDataSource,
interfaces.ModelColNameDataCollection,
interfaces.ModelColNamePasswords,
}
actionList := []string{
interfaces.ModelDelegateMethodAdd,
interfaces.ModelDelegateMethodChange,
interfaces.ModelDelegateMethodDelete,
interfaces.ModelDelegateMethodSave,
}

var triggers []string
for _, m := range modelList {
for _, a := range actionList {
triggers = append(triggers, fmt.Sprintf("model:%s:%s", m, a))
}
}

return triggers, len(triggers), nil
}

func (svc *Service) GetSettingList(query bson.M, pagination *entity.Pagination, sort bson.D) (res []Setting, total int, err error) {
// get list
var list []Setting
Expand Down Expand Up @@ -537,17 +412,27 @@ func (svc *Service) handleEvents() {
// event name
eventName := data.Events[0]

// task event
if eventName != "model:tasks:change" {
continue
}

// task
var t models.Task
if err := json.Unmarshal(data.Data, &t); err != nil {
continue
}

// settings
var settings []Setting
if err := svc.col.Find(bson.M{
"enabled": true,
"triggers": eventName,
"enabled": true,
}, nil).All(&settings); err != nil || len(settings) == 0 {
continue
}

// handle events
if err := svc._handleEventModel(settings, data.Data); err != nil {
if err := svc._handleEventModel(settings, data.Data, t); err != nil {
trace.PrintError(err)
}
default:
Expand All @@ -556,13 +441,29 @@ func (svc *Service) handleEvents() {
}
}

func (svc *Service) _handleEventModel(settings []Setting, data []byte) (err error) {
func (svc *Service) _handleEventModel(settings []Setting, data []byte, t models.Task) (err error) {
var doc bson.M
if err := json.Unmarshal(data, &doc); err != nil {
return err
}

// task stat
ts, err := svc.modelSvc.GetTaskStatById(t.Id)
if err != nil {
return err
}

for _, s := range settings {
if s.TaskTrigger == constants.NotificationTriggerTaskNever {
continue
} else if s.TaskTrigger == constants.NotificationTriggerTaskFinish && t.Status != constants.TaskStatusFinished {
continue
} else if s.TaskTrigger == constants.NotificationTriggerTaskError && t.Status != constants.TaskStatusError {
continue
} else if s.TaskTrigger == constants.NotificationTriggerTaskEmptyResults && ((t.Status != constants.TaskStatusFinished && t.Status != constants.TaskStatusError) || ts.ResultCount > 0) {
continue
}

switch s.Type {
case TypeMail:
err = svc.sendMail(&s, doc)
Expand Down
7 changes: 7 additions & 0 deletions utils/system.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package utils

import "github.com/spf13/viper"

func IsPro() bool {
return viper.GetString("info.edition") == "global.edition.pro"
}

0 comments on commit 70ccfc4

Please sign in to comment.