diff --git a/internal/sdk/message/pushplus.go b/internal/sdk/message/pushplus.go new file mode 100644 index 0000000..958430d --- /dev/null +++ b/internal/sdk/message/pushplus.go @@ -0,0 +1,73 @@ +package message + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "net/http" +) + +type PushPlus struct { + Token string `json:"token"` + Topic string `json:"topic,omitempty"` + Template string `json:"template,omitempty"` + Channel string `json:"channel,omitempty"` + Webhook string `json:"webhook,omitempty"` + CallbackUrl string `json:"callbackUrl,omitempty"` + To string `json:"to,omitempty"` +} + +type pushPlusData struct { + PushPlus + Title string `json:"title"` + Content string `json:"content"` +} + +type pushPlusResponse struct { + Code int `json:"code"` + Msg string `json:"msg"` + Data string `json:"data"` +} + +func (p *PushPlus) Request(title, content string) (string, error) { + url := "https://www.pushplus.plus/send" + + data := pushPlusData{ + PushPlus: *p, + Title: title, + Content: content, + } + + body, err := json.Marshal(data) + if err != nil { + return "", err + } + + resp, err := http.Post(url, "application/json", bytes.NewBuffer(body)) + if err != nil { + // Try old URL if first one fails or as fallback + urlOld := "http://pushplus.hxtrip.com/send" + resp, err = http.Post(urlOld, "application/json", bytes.NewBuffer(body)) + if err != nil { + return "", err + } + } + defer resp.Body.Close() + + respBody, err := io.ReadAll(resp.Body) + if err != nil { + return "", err + } + + var res pushPlusResponse + if err := json.Unmarshal(respBody, &res); err != nil { + return string(respBody), err + } + + if res.Code == 200 { + return string(respBody), nil + } + + return string(respBody), fmt.Errorf("PushPlus error: %s (code: %d)", res.Msg, res.Code) +} diff --git a/internal/sdk/messenger/channels/pushplus.go b/internal/sdk/messenger/channels/pushplus.go new file mode 100644 index 0000000..4512199 --- /dev/null +++ b/internal/sdk/messenger/channels/pushplus.go @@ -0,0 +1,32 @@ +package channels + +import "github.com/engigu/baihu-panel/internal/sdk/message" + +type PushPlusChannel struct{ *BaseChannel } + +func NewPushPlusChannel() Channel { + return &PushPlusChannel{NewBaseChannel(ChannelPushPlus, []string{FormatTypeText, FormatTypeHTML, FormatTypeMarkdown})} +} + +func (c *PushPlusChannel) Send(config ChannelConfig, msg *Message) (*Result, error) { + token := config.GetString("token") + if token == "" { + return SendError("pushplus config missing: token is required"), nil + } + + cli := message.PushPlus{ + Token: token, + Topic: config.GetString("topic"), + Template: config.GetString("template"), + Channel: config.GetString("channel"), + Webhook: config.GetString("webhook"), + CallbackUrl: config.GetString("callback_url"), + To: config.GetString("to"), + } + + res, err := cli.Request(msg.Title, msg.Text) + if err != nil { + return ErrorResult(string(res), err), nil + } + return SuccessResult(string(res)), nil +} diff --git a/internal/sdk/messenger/channels/types.go b/internal/sdk/messenger/channels/types.go index f8d69ce..1d67ee1 100644 --- a/internal/sdk/messenger/channels/types.go +++ b/internal/sdk/messenger/channels/types.go @@ -72,4 +72,5 @@ const ( ChannelPushMe = "PushMe" ChannelNtfy = "Ntfy" ChannelGotify = "Gotify" + ChannelPushPlus = "PushPlus" ) diff --git a/internal/sdk/messenger/messenger.go b/internal/sdk/messenger/messenger.go index a31eae2..46d55de 100644 --- a/internal/sdk/messenger/messenger.go +++ b/internal/sdk/messenger/messenger.go @@ -47,6 +47,7 @@ const ( ChannelPushMe = channels.ChannelPushMe ChannelNtfy = channels.ChannelNtfy ChannelGotify = channels.ChannelGotify + ChannelPushPlus = channels.ChannelPushPlus ) // 重导出辅助函数 @@ -78,6 +79,7 @@ func init() { RegisterChannel(ChannelCustom, func() Channel { return channels.NewCustomChannel() }) RegisterChannel(ChannelWeChatOFAccount, func() Channel { return channels.NewWeChatOFAccountChannel() }) RegisterChannel(ChannelAliyunSMS, func() Channel { return channels.NewAliyunSMSChannel() }) + RegisterChannel(ChannelPushPlus, func() Channel { return channels.NewPushPlusChannel() }) } // RegisterChannel 注册自定义渠道(可用于扩展) diff --git a/internal/services/notification_service.go b/internal/services/notification_service.go index 89c8a80..0417d98 100644 --- a/internal/services/notification_service.go +++ b/internal/services/notification_service.go @@ -50,6 +50,7 @@ var SupportedChannelTypes = []map[string]string{ {"type": messenger.ChannelPushMe, "label": "PushMe"}, // {"type": messenger.ChannelWeChatOFAccount, "label": "微信公众号"}, {"type": messenger.ChannelAliyunSMS, "label": "阿里云短信"}, + {"type": messenger.ChannelPushPlus, "label": "PushPlus"}, } // SupportedEvents 支持的事件类型 diff --git a/web/src/views/notify/Notify.vue b/web/src/views/notify/Notify.vue index a2351e4..2be6638 100644 --- a/web/src/views/notify/Notify.vue +++ b/web/src/views/notify/Notify.vue @@ -113,6 +113,15 @@ const channelConfigFields: Record