fix(notify): fix and optimize task execution log notification #133
This commit is contained in:
@@ -375,6 +375,88 @@ func (s *NotificationService) getDefaultMessage(eventType string, payload map[st
|
|||||||
return title, text
|
return title, text
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// resolveEvent 解析不同事件类型,返回对应的模板Key、静态内容(非模板事件)和原始任务输出
|
||||||
|
func (s *NotificationService) resolveEvent(eventType string, payload map[string]interface{}) (tmplTitleKey, tmplTextKey, title, text, rawOutput string, ok bool) {
|
||||||
|
switch eventType {
|
||||||
|
case constant.EventUserLogin:
|
||||||
|
tmplTitleKey = constant.KeyNotifyTemplateUserLoginTitle
|
||||||
|
tmplTextKey = constant.KeyNotifyTemplateUserLoginText
|
||||||
|
// 特殊处理登录状态
|
||||||
|
status, _ := payload["status"].(string)
|
||||||
|
if status == "success" {
|
||||||
|
payload["status_label"] = "成功"
|
||||||
|
} else {
|
||||||
|
payload["status_label"] = "失败"
|
||||||
|
}
|
||||||
|
|
||||||
|
case constant.EventBruteForceLogin:
|
||||||
|
tmplTitleKey = constant.KeyNotifyTemplateBruteForceLoginTitle
|
||||||
|
tmplTextKey = constant.KeyNotifyTemplateBruteForceLoginText
|
||||||
|
|
||||||
|
case constant.EventPasswordChanged:
|
||||||
|
tmplTitleKey = constant.KeyNotifyTemplatePasswordChangedTitle
|
||||||
|
tmplTextKey = constant.KeyNotifyTemplatePasswordChangedText
|
||||||
|
|
||||||
|
case constant.EventTaskSuccess, constant.EventTaskFailed, constant.EventTaskTimeout:
|
||||||
|
switch eventType {
|
||||||
|
case constant.EventTaskSuccess:
|
||||||
|
tmplTitleKey = constant.KeyNotifyTemplateTaskSuccessTitle
|
||||||
|
tmplTextKey = constant.KeyNotifyTemplateTaskSuccessText
|
||||||
|
case constant.EventTaskFailed:
|
||||||
|
tmplTitleKey = constant.KeyNotifyTemplateTaskFailedTitle
|
||||||
|
tmplTextKey = constant.KeyNotifyTemplateTaskFailedText
|
||||||
|
case constant.EventTaskTimeout:
|
||||||
|
tmplTitleKey = constant.KeyNotifyTemplateTaskTimeoutTitle
|
||||||
|
tmplTextKey = constant.KeyNotifyTemplateTaskTimeoutText
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理输出内容,避免过长
|
||||||
|
if output, ok := payload["output"].(string); ok {
|
||||||
|
rawOutput = output
|
||||||
|
// trimmed := utils.TrimLastRunes(output, 1000)
|
||||||
|
// if len(trimmed) < len(output) {
|
||||||
|
// payload["output"] = trimmed + "\n...(截断)"
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
case constant.EventSystemNotice:
|
||||||
|
title, _ = payload["title"].(string)
|
||||||
|
text, _ = payload["content"].(string)
|
||||||
|
default:
|
||||||
|
return "", "", "", "", "", false
|
||||||
|
}
|
||||||
|
return tmplTitleKey, tmplTextKey, title, text, rawOutput, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// buildMessage 匹配并解析模板内容,提供兜底消息并拼接全局前缀
|
||||||
|
func (s *NotificationService) buildMessage(eventType string, tmplTitleKey, tmplTextKey, defaultTitle, defaultText, prefix string, payload map[string]interface{}) (title, text string) {
|
||||||
|
title = defaultTitle
|
||||||
|
text = defaultText
|
||||||
|
|
||||||
|
if tmplTitleKey != "" {
|
||||||
|
tmplTitle := s.settingsService.Get(constant.SectionNotify, tmplTitleKey)
|
||||||
|
tmplText := s.settingsService.Get(constant.SectionNotify, tmplTextKey)
|
||||||
|
|
||||||
|
if tmplTitle != "" {
|
||||||
|
title = s.parseTemplate(tmplTitle, payload)
|
||||||
|
}
|
||||||
|
if tmplText != "" {
|
||||||
|
text = s.parseTemplate(tmplText, payload)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果模板为空,使用兜底默认逻辑(保持向上兼容)
|
||||||
|
if title == "" || text == "" {
|
||||||
|
title, text = s.getDefaultMessage(eventType, payload)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加全局前缀
|
||||||
|
if prefix != "" && title != "" {
|
||||||
|
title = fmt.Sprintf("%s %s", prefix, title)
|
||||||
|
}
|
||||||
|
return title, text
|
||||||
|
}
|
||||||
|
|
||||||
// handleEvent 处理事件订阅并发送通知
|
// handleEvent 处理事件订阅并发送通知
|
||||||
func (s *NotificationService) handleEvent(bindingType string) eventbus.Handler {
|
func (s *NotificationService) handleEvent(bindingType string) eventbus.Handler {
|
||||||
return func(e eventbus.Event) {
|
return func(e eventbus.Event) {
|
||||||
@@ -388,89 +470,27 @@ func (s *NotificationService) handleEvent(bindingType string) eventbus.Handler {
|
|||||||
dataID = id
|
dataID = id
|
||||||
}
|
}
|
||||||
|
|
||||||
var title, text string
|
// 获取全局前缀并解析事件数据
|
||||||
|
|
||||||
// 获取全局前缀和模板配置
|
|
||||||
prefix := s.settingsService.Get(constant.SectionNotify, constant.KeyNotifyPrefix)
|
prefix := s.settingsService.Get(constant.SectionNotify, constant.KeyNotifyPrefix)
|
||||||
var tmplTitleKey, tmplTextKey string
|
tmplTitleKey, tmplTextKey, title, text, rawOutput, ok := s.resolveEvent(e.Type, payload)
|
||||||
|
if !ok {
|
||||||
switch e.Type {
|
|
||||||
case constant.EventUserLogin:
|
|
||||||
tmplTitleKey = constant.KeyNotifyTemplateUserLoginTitle
|
|
||||||
tmplTextKey = constant.KeyNotifyTemplateUserLoginText
|
|
||||||
// 特殊处理登录状态
|
|
||||||
status, _ := payload["status"].(string)
|
|
||||||
if status == "success" {
|
|
||||||
payload["status_label"] = "成功"
|
|
||||||
} else {
|
|
||||||
payload["status_label"] = "失败"
|
|
||||||
}
|
|
||||||
|
|
||||||
case constant.EventBruteForceLogin:
|
|
||||||
tmplTitleKey = constant.KeyNotifyTemplateBruteForceLoginTitle
|
|
||||||
tmplTextKey = constant.KeyNotifyTemplateBruteForceLoginText
|
|
||||||
|
|
||||||
case constant.EventPasswordChanged:
|
|
||||||
tmplTitleKey = constant.KeyNotifyTemplatePasswordChangedTitle
|
|
||||||
tmplTextKey = constant.KeyNotifyTemplatePasswordChangedText
|
|
||||||
|
|
||||||
case constant.EventTaskSuccess, constant.EventTaskFailed, constant.EventTaskTimeout:
|
|
||||||
switch e.Type {
|
|
||||||
case constant.EventTaskSuccess:
|
|
||||||
tmplTitleKey = constant.KeyNotifyTemplateTaskSuccessTitle
|
|
||||||
tmplTextKey = constant.KeyNotifyTemplateTaskSuccessText
|
|
||||||
case constant.EventTaskFailed:
|
|
||||||
tmplTitleKey = constant.KeyNotifyTemplateTaskFailedTitle
|
|
||||||
tmplTextKey = constant.KeyNotifyTemplateTaskFailedText
|
|
||||||
case constant.EventTaskTimeout:
|
|
||||||
tmplTitleKey = constant.KeyNotifyTemplateTaskTimeoutTitle
|
|
||||||
tmplTextKey = constant.KeyNotifyTemplateTaskTimeoutText
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理输出内容,避免过长
|
|
||||||
if output, ok := payload["output"].(string); ok {
|
|
||||||
// 如果输出包含了压缩后的 Base64 (以 "base64:" 开头),由于是推送到通知,我们尽量不发大段 Base64
|
|
||||||
// 这里简单处理:如果过长则截断,或者如果是压缩的则记录一下
|
|
||||||
trimmed := utils.TrimLastRunes(output, 1000)
|
|
||||||
if len(trimmed) < len(output) {
|
|
||||||
payload["output"] = trimmed + "\n...(截断)"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
case constant.EventSystemNotice:
|
|
||||||
title, _ = payload["title"].(string)
|
|
||||||
text, _ = payload["content"].(string)
|
|
||||||
default:
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if tmplTitleKey != "" {
|
// 构建最终的通知标题和正文文本
|
||||||
tmplTitle := s.settingsService.Get(constant.SectionNotify, tmplTitleKey)
|
title, text = s.buildMessage(e.Type, tmplTitleKey, tmplTextKey, title, text, prefix, payload)
|
||||||
tmplText := s.settingsService.Get(constant.SectionNotify, tmplTextKey)
|
|
||||||
|
|
||||||
if tmplTitle != "" {
|
|
||||||
title = s.parseTemplate(tmplTitle, payload)
|
|
||||||
}
|
|
||||||
if tmplText != "" {
|
|
||||||
text = s.parseTemplate(tmplText, payload)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 如果模板为空,使用兜底默认逻辑(保持向上兼容)
|
|
||||||
if title == "" || text == "" {
|
|
||||||
title, text = s.getDefaultMessage(e.Type, payload)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加全局前缀
|
|
||||||
if prefix != "" {
|
|
||||||
title = fmt.Sprintf("%s %s", prefix, title)
|
|
||||||
}
|
|
||||||
|
|
||||||
bindings := s.GetBindingsByEvent(bindingType, e.Type, dataID)
|
bindings := s.GetBindingsByEvent(bindingType, e.Type, dataID)
|
||||||
if len(bindings) == 0 {
|
if len(bindings) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var cleanLog string
|
||||||
|
if rawOutput != "" {
|
||||||
|
// cleanLog = stripAnsi(rawOutput)
|
||||||
|
cleanLog = rawOutput
|
||||||
|
}
|
||||||
|
|
||||||
channels := s.GetChannels()
|
channels := s.GetChannels()
|
||||||
channelMap := make(map[string]NotifyChannel)
|
channelMap := make(map[string]NotifyChannel)
|
||||||
for _, ch := range channels {
|
for _, ch := range channels {
|
||||||
@@ -498,18 +518,12 @@ func (s *NotificationService) handleEvent(bindingType string) eventbus.Handler {
|
|||||||
|
|
||||||
// 如果开启了日志推送
|
// 如果开启了日志推送
|
||||||
if extra.EnableLog {
|
if extra.EnableLog {
|
||||||
if output, ok := payload["output"].(string); ok && output != "" {
|
if cleanLog != "" {
|
||||||
// 仅保留指定字数的日志内容并移除 ANSI 颜色代码
|
trimmed := utils.TrimLastRunes(cleanLog, extra.LogLimit)
|
||||||
logSnippet := stripAnsi(output)
|
if len(trimmed) < len(cleanLog) {
|
||||||
|
trimmed = "...\n" + trimmed
|
||||||
trimmed := utils.TrimLastRunes(logSnippet, extra.LogLimit)
|
|
||||||
if len(trimmed) < len(logSnippet) {
|
|
||||||
logSnippet = "...\n" + trimmed
|
|
||||||
} else {
|
|
||||||
logSnippet = trimmed
|
|
||||||
}
|
}
|
||||||
|
currentText += "\n\n[执行日志]\n" + trimmed
|
||||||
currentText += "\n\n[执行日志]\n" + logSnippet
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user