Files
Message-Push-Nest/routers/api/v2/send_message.go
T

149 lines
4.2 KiB
Go

package v2
import (
"fmt"
"message-nest/models"
"message-nest/pkg/app"
"message-nest/pkg/e"
utilpkg "message-nest/pkg/util"
"message-nest/service/send_message_service"
"net/http"
"strings"
"github.com/gin-gonic/gin"
"github.com/sirupsen/logrus"
)
type SendMessageByTemplateReq struct {
Token string `json:"token" validate:"required" label:"模板token"`
Title string `json:"title" validate:"required" label:"消息标题"`
Placeholders map[string]interface{} `json:"placeholders" label:"占位符"`
Recipients []string `json:"recipients" label:"接收者列表"`
}
// DoSendMessageByTemplate 使用模板发送消息
func DoSendMessageByTemplate(c *gin.Context) {
var (
appG = app.Gin{C: c}
req SendMessageByTemplateReq
)
errCode, errMsg := app.BindJsonAndPlayValid(c, &req)
if errCode != e.SUCCESS {
appG.CResponse(errCode, errMsg, nil)
return
}
// 解析 token 为模板 ID
templateID, err := utilpkg.DecryptTokenHex(req.Token, 71) // 71 为简单对称密钥
if err != nil {
appG.CResponse(http.StatusBadRequest, fmt.Sprintf("token解析失败:%v", err), nil)
return
}
// 获取模板
template, err := models.GetTemplateByID(templateID)
if err != nil {
appG.CResponse(http.StatusBadRequest, fmt.Sprintf("模板不存在:%s", err), nil)
return
}
// 检查模板状态
if template.Status != "enabled" {
appG.CResponse(http.StatusBadRequest, "模板已禁用", nil)
return
}
// 替换占位符
textContent := replacePlaceholders(template.TextTemplate, req.Placeholders)
htmlContent := replacePlaceholders(template.HTMLTemplate, req.Placeholders)
markdownContent := replacePlaceholders(template.MarkdownTemplate, req.Placeholders)
// 解析@提醒配置
var atMobiles []string
var atUserIds []string
if template.AtMobiles != "" {
atMobiles = strings.Split(template.AtMobiles, ",")
// 去除空格
for i := range atMobiles {
atMobiles[i] = strings.TrimSpace(atMobiles[i])
}
}
if template.AtUserIds != "" {
atUserIds = strings.Split(template.AtUserIds, ",")
// 去除空格
for i := range atUserIds {
atUserIds[i] = strings.TrimSpace(atUserIds[i])
}
}
// 获取模板关联的实例列表
insList, err := models.GetTemplateInsList(templateID)
if err != nil || len(insList) == 0 {
appG.CResponse(http.StatusBadRequest, "模板没有配置发送实例", nil)
return
}
// 过滤启用的实例
var enabledCount int
for _, ins := range insList {
if ins.Enable == 1 {
enabledCount++
}
}
if enabledCount == 0 {
appG.CResponse(http.StatusBadRequest, "模板没有启用的发送实例", nil)
return
}
// 使用发送服务进行发送
// 将模板ID作为TaskID传入,用于日志记录
msgService := send_message_service.SendMessageService{
SendMode: send_message_service.SendModeTemplate, // 明确标记为模板模式
TaskID: templateID, // 使用模板ID作为TaskID(用于日志记录)
TemplateID: templateID, // 模板ID
Name: template.Name, // 模板名称
Title: req.Title,
Text: textContent,
HTML: htmlContent,
MarkDown: markdownContent,
CallerIp: c.ClientIP(),
AtMobiles: atMobiles,
AtUserIds: atUserIds,
AtAll: template.IsAtAll,
Recipients: req.Recipients, // 动态接收者列表
DefaultLogger: logrus.WithFields(logrus.Fields{
"prefix": "[Template Send]",
}),
}
// 发送前检查
task, err := msgService.SendPreCheck()
if err != nil {
appG.CResponse(http.StatusBadRequest, fmt.Sprintf("发送检查不通过:%s", err), nil)
return
}
// 异步发送
msgService.AsyncSend(task)
appG.CResponse(http.StatusOK, "success", map[string]interface{}{
"token": req.Token,
"count": enabledCount,
})
}
// replacePlaceholders 替换模板中的占位符
func replacePlaceholders(template string, placeholders map[string]interface{}) string {
if template == "" || placeholders == nil {
return template
}
result := template
for key, value := range placeholders {
placeholder := fmt.Sprintf("{{%s}}", key)
result = strings.ReplaceAll(result, placeholder, fmt.Sprintf("%v", value))
}
return result
}