fix(notify): fix and optimize task execution log notification #133

This commit is contained in:
duorameng
2026-06-22 17:40:34 +08:00
parent ff90837f24
commit ea4cbb0370
+55 -41
View File
@@ -375,26 +375,9 @@ func (s *NotificationService) getDefaultMessage(eventType string, payload map[st
return title, text return title, text
} }
// handleEvent 处理事件订阅并发送通知 // resolveEvent 解析不同事件类型,返回对应的模板Key、静态内容(非模板事件)和原始任务输出
func (s *NotificationService) handleEvent(bindingType string) eventbus.Handler { func (s *NotificationService) resolveEvent(eventType string, payload map[string]interface{}) (tmplTitleKey, tmplTextKey, title, text, rawOutput string, ok bool) {
return func(e eventbus.Event) { switch eventType {
payload, ok := e.Payload.(map[string]interface{})
if !ok {
return
}
var dataID string
if id, ok := payload["task_id"].(string); ok {
dataID = id
}
var title, text string
// 获取全局前缀和模板配置
prefix := s.settingsService.Get(constant.SectionNotify, constant.KeyNotifyPrefix)
var tmplTitleKey, tmplTextKey string
switch e.Type {
case constant.EventUserLogin: case constant.EventUserLogin:
tmplTitleKey = constant.KeyNotifyTemplateUserLoginTitle tmplTitleKey = constant.KeyNotifyTemplateUserLoginTitle
tmplTextKey = constant.KeyNotifyTemplateUserLoginText tmplTextKey = constant.KeyNotifyTemplateUserLoginText
@@ -415,7 +398,7 @@ func (s *NotificationService) handleEvent(bindingType string) eventbus.Handler {
tmplTextKey = constant.KeyNotifyTemplatePasswordChangedText tmplTextKey = constant.KeyNotifyTemplatePasswordChangedText
case constant.EventTaskSuccess, constant.EventTaskFailed, constant.EventTaskTimeout: case constant.EventTaskSuccess, constant.EventTaskFailed, constant.EventTaskTimeout:
switch e.Type { switch eventType {
case constant.EventTaskSuccess: case constant.EventTaskSuccess:
tmplTitleKey = constant.KeyNotifyTemplateTaskSuccessTitle tmplTitleKey = constant.KeyNotifyTemplateTaskSuccessTitle
tmplTextKey = constant.KeyNotifyTemplateTaskSuccessText tmplTextKey = constant.KeyNotifyTemplateTaskSuccessText
@@ -429,20 +412,26 @@ func (s *NotificationService) handleEvent(bindingType string) eventbus.Handler {
// 处理输出内容,避免过长 // 处理输出内容,避免过长
if output, ok := payload["output"].(string); ok { if output, ok := payload["output"].(string); ok {
// 如果输出包含了压缩后的 Base64 (以 "base64:" 开头),由于是推送到通知,我们尽量不发大段 Base64 rawOutput = output
// 这里简单处理:如果过长则截断,或者如果是压缩的则记录一下 // trimmed := utils.TrimLastRunes(output, 1000)
trimmed := utils.TrimLastRunes(output, 1000) // if len(trimmed) < len(output) {
if len(trimmed) < len(output) { // payload["output"] = trimmed + "\n...(截断)"
payload["output"] = trimmed + "\n...(截断)" // }
}
} }
case constant.EventSystemNotice: case constant.EventSystemNotice:
title, _ = payload["title"].(string) title, _ = payload["title"].(string)
text, _ = payload["content"].(string) text, _ = payload["content"].(string)
default: default:
return 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 != "" { if tmplTitleKey != "" {
tmplTitle := s.settingsService.Get(constant.SectionNotify, tmplTitleKey) tmplTitle := s.settingsService.Get(constant.SectionNotify, tmplTitleKey)
@@ -457,20 +446,51 @@ func (s *NotificationService) handleEvent(bindingType string) eventbus.Handler {
// 如果模板为空,使用兜底默认逻辑(保持向上兼容) // 如果模板为空,使用兜底默认逻辑(保持向上兼容)
if title == "" || text == "" { if title == "" || text == "" {
title, text = s.getDefaultMessage(e.Type, payload) title, text = s.getDefaultMessage(eventType, payload)
} }
} }
// 添加全局前缀 // 添加全局前缀
if prefix != "" { if prefix != "" && title != "" {
title = fmt.Sprintf("%s %s", prefix, title) title = fmt.Sprintf("%s %s", prefix, title)
} }
return title, text
}
// handleEvent 处理事件订阅并发送通知
func (s *NotificationService) handleEvent(bindingType string) eventbus.Handler {
return func(e eventbus.Event) {
payload, ok := e.Payload.(map[string]interface{})
if !ok {
return
}
var dataID string
if id, ok := payload["task_id"].(string); ok {
dataID = id
}
// 获取全局前缀并解析事件数据
prefix := s.settingsService.Get(constant.SectionNotify, constant.KeyNotifyPrefix)
tmplTitleKey, tmplTextKey, title, text, rawOutput, ok := s.resolveEvent(e.Type, payload)
if !ok {
return
}
// 构建最终的通知标题和正文文本
title, text = s.buildMessage(e.Type, tmplTitleKey, tmplTextKey, title, text, prefix, payload)
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
} }
} }