feat: add push message - wxpusher #98
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
package message
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type WxPusher struct {
|
||||
AppToken string `json:"appToken"`
|
||||
Content string `json:"content"`
|
||||
ContentType int `json:"contentType"`
|
||||
TopicIds []int `json:"topicIds,omitempty"`
|
||||
Uids []string `json:"uids,omitempty"`
|
||||
Url string `json:"url,omitempty"`
|
||||
VerifyPayType int `json:"verifyPayType,omitempty"`
|
||||
}
|
||||
|
||||
type wxPusherResponse struct {
|
||||
Code int `json:"code"`
|
||||
Msg string `json:"msg"`
|
||||
Data []struct {
|
||||
Uid string `json:"uid"`
|
||||
TopicId int `json:"topicId"`
|
||||
MessageId int `json:"messageId"`
|
||||
Code int `json:"code"`
|
||||
Status string `json:"status"`
|
||||
} `json:"data"`
|
||||
}
|
||||
|
||||
func (w *WxPusher) Send() (string, error) {
|
||||
apiUrl := "https://wxpusher.zjiecode.com/api/send/message"
|
||||
|
||||
body, err := json.Marshal(w)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
resp, err := http.Post(apiUrl, "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 wxPusherResponse
|
||||
if err := json.Unmarshal(respBody, &res); err != nil {
|
||||
return string(respBody), err
|
||||
}
|
||||
|
||||
if res.Code == 1000 {
|
||||
return string(respBody), nil
|
||||
}
|
||||
|
||||
return string(respBody), fmt.Errorf("WxPusher error: %s (code: %d)", res.Msg, res.Code)
|
||||
}
|
||||
@@ -74,4 +74,5 @@ const (
|
||||
ChannelGotify = "Gotify"
|
||||
ChannelPushPlus = "PushPlus"
|
||||
ChannelVoceChat = "VoceChat"
|
||||
ChannelWxPusher = "WxPusher"
|
||||
)
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
package channels
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/engigu/baihu-panel/internal/sdk/message"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type WxPusherChannel struct{ *BaseChannel }
|
||||
|
||||
func NewWxPusherChannel() Channel {
|
||||
return &WxPusherChannel{NewBaseChannel(ChannelWxPusher, []string{FormatTypeText})}
|
||||
}
|
||||
|
||||
func (c *WxPusherChannel) Send(config ChannelConfig, msg *Message) (*Result, error) {
|
||||
appToken := config.GetString("app_token")
|
||||
if appToken == "" {
|
||||
return SendError("wxpusher config missing: app_token is required"), nil
|
||||
}
|
||||
|
||||
uidsStr := config.GetString("uids")
|
||||
topicIdsStr := config.GetString("topic_ids")
|
||||
verifyPayTypeStr := config.GetString("verify_pay_type")
|
||||
|
||||
if uidsStr == "" && topicIdsStr == "" {
|
||||
return SendError("wxpusher config missing: uids or topic_ids is required"), nil
|
||||
}
|
||||
|
||||
var uids []string
|
||||
if uidsStr != "" {
|
||||
uids = strings.Split(uidsStr, ",")
|
||||
for i := range uids {
|
||||
uids[i] = strings.TrimSpace(uids[i])
|
||||
}
|
||||
}
|
||||
|
||||
var topicIds []int
|
||||
if topicIdsStr != "" {
|
||||
ids := strings.Split(topicIdsStr, ",")
|
||||
for _, idStr := range ids {
|
||||
idStr = strings.TrimSpace(idStr)
|
||||
if id, err := strconv.Atoi(idStr); err == nil {
|
||||
topicIds = append(topicIds, id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
verifyPayType := 0
|
||||
if verifyPayTypeStr != "" {
|
||||
if v, err := strconv.Atoi(verifyPayTypeStr); err == nil {
|
||||
verifyPayType = v
|
||||
}
|
||||
}
|
||||
|
||||
_, formattedContent := c.FormatContent(msg)
|
||||
|
||||
// 如果有标题,将标题和内容合并
|
||||
content := formattedContent
|
||||
if msg.Title != "" {
|
||||
content = fmt.Sprintf("%s\n\n%s", msg.Title, formattedContent)
|
||||
}
|
||||
|
||||
cli := message.WxPusher{
|
||||
AppToken: appToken,
|
||||
Content: content,
|
||||
ContentType: 1, // 仅支持文字
|
||||
Uids: uids,
|
||||
TopicIds: topicIds,
|
||||
VerifyPayType: verifyPayType,
|
||||
}
|
||||
|
||||
res, err := cli.Send()
|
||||
if err != nil {
|
||||
return ErrorResult(res, err), nil
|
||||
}
|
||||
return SuccessResult(res), nil
|
||||
}
|
||||
@@ -49,6 +49,7 @@ const (
|
||||
ChannelGotify = channels.ChannelGotify
|
||||
ChannelPushPlus = channels.ChannelPushPlus
|
||||
ChannelVoceChat = channels.ChannelVoceChat
|
||||
ChannelWxPusher = channels.ChannelWxPusher
|
||||
)
|
||||
|
||||
// 重导出辅助函数
|
||||
@@ -82,6 +83,7 @@ func init() {
|
||||
RegisterChannel(ChannelAliyunSMS, func() Channel { return channels.NewAliyunSMSChannel() })
|
||||
RegisterChannel(ChannelPushPlus, func() Channel { return channels.NewPushPlusChannel() })
|
||||
RegisterChannel(ChannelVoceChat, func() Channel { return channels.NewVoceChatChannel() })
|
||||
RegisterChannel(ChannelWxPusher, func() Channel { return channels.NewWxPusherChannel() })
|
||||
}
|
||||
|
||||
// RegisterChannel 注册自定义渠道(可用于扩展)
|
||||
|
||||
@@ -56,6 +56,7 @@ var SupportedChannelTypes = []map[string]string{
|
||||
{"type": messenger.ChannelAliyunSMS, "label": "阿里云短信"},
|
||||
{"type": messenger.ChannelPushPlus, "label": "PushPlus"},
|
||||
{"type": messenger.ChannelVoceChat, "label": "VoceChat"},
|
||||
{"type": messenger.ChannelWxPusher, "label": "WxPusher"},
|
||||
}
|
||||
|
||||
// SupportedEvents 支持的事件类型
|
||||
|
||||
@@ -128,6 +128,12 @@ const channelConfigFields: Record<string, { key: string; label: string; required
|
||||
{ key: 'target_type', label: '目标类型', required: false, placeholder: 'user (默认) / group' },
|
||||
{ key: 'note', label: '说明', required: false, placeholder: '当前仅支持 text/plain', type: 'note' },
|
||||
],
|
||||
WxPusher: [
|
||||
{ key: 'app_token', label: 'AppToken', required: true, placeholder: 'AT_...' },
|
||||
{ key: 'uids', label: 'UIDs', required: false, placeholder: '用户 UID,多个用逗号分隔' },
|
||||
{ key: 'topic_ids', label: 'TopicIDs', required: false, placeholder: '主题 ID,多个用逗号分隔' },
|
||||
{ key: 'verify_pay_type', label: '付费验证', required: false, placeholder: '0:不验证, 1:仅付费, 2:仅未订阅/过期' },
|
||||
],
|
||||
}
|
||||
|
||||
// 加载数据
|
||||
|
||||
Reference in New Issue
Block a user