WIP: 添加更多的占位符以支持基于服务器状态指标构造自定义的HTTP请求
This commit is contained in:
		
							parent
							
								
									5e400807e0
								
							
						
					
					
						commit
						f6a5362a97
					
				@ -412,7 +412,11 @@ func (ma *memberAPI) addOrEditNotification(c *gin.Context) {
 | 
			
		||||
		verifySSL := nf.VerifySSL == "on"
 | 
			
		||||
		n.VerifySSL = &verifySSL
 | 
			
		||||
		n.ID = nf.ID
 | 
			
		||||
		err = n.Send("这是测试消息")
 | 
			
		||||
		ns := model.NotificationServerBundle{
 | 
			
		||||
			Notification: &n,
 | 
			
		||||
			Server:       nil,
 | 
			
		||||
		}
 | 
			
		||||
		err = ns.Send("这是测试消息")
 | 
			
		||||
	}
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		// 保证Tag不为空
 | 
			
		||||
 | 
			
		||||
@ -25,6 +25,11 @@ const (
 | 
			
		||||
	NotificationRequestMethodPOST
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type NotificationServerBundle struct {
 | 
			
		||||
	Notification *Notification
 | 
			
		||||
	Server       *Server
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Notification struct {
 | 
			
		||||
	Common
 | 
			
		||||
	Name          string
 | 
			
		||||
@ -37,8 +42,9 @@ type Notification struct {
 | 
			
		||||
	VerifySSL     *bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (n *Notification) reqURL(message string) string {
 | 
			
		||||
	return replaceParamsInString(n.URL, message, func(msg string) string {
 | 
			
		||||
func (ns *NotificationServerBundle) reqURL(message string) string {
 | 
			
		||||
	n := ns.Notification
 | 
			
		||||
	return replaceParamsInString(ns.Server, n.URL, message, func(msg string) string {
 | 
			
		||||
		return url.QueryEscape(msg)
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
@ -53,13 +59,14 @@ func (n *Notification) reqMethod() (string, error) {
 | 
			
		||||
	return "", errors.New("不支持的请求方式")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (n *Notification) reqBody(message string) (string, error) {
 | 
			
		||||
func (ns *NotificationServerBundle) reqBody(message string) (string, error) {
 | 
			
		||||
	n := ns.Notification
 | 
			
		||||
	if n.RequestMethod == NotificationRequestMethodGET || message == "" {
 | 
			
		||||
		return "", nil
 | 
			
		||||
	}
 | 
			
		||||
	switch n.RequestType {
 | 
			
		||||
	case NotificationRequestTypeJSON:
 | 
			
		||||
		return replaceParamsInString(n.RequestBody, message, func(msg string) string {
 | 
			
		||||
		return replaceParamsInString(ns.Server, n.RequestBody, message, func(msg string) string {
 | 
			
		||||
			msgBytes, _ := utils.Json.Marshal(msg)
 | 
			
		||||
			return string(msgBytes)[1 : len(msgBytes)-1]
 | 
			
		||||
		}), nil
 | 
			
		||||
@ -70,7 +77,7 @@ func (n *Notification) reqBody(message string) (string, error) {
 | 
			
		||||
		}
 | 
			
		||||
		params := url.Values{}
 | 
			
		||||
		for k, v := range data {
 | 
			
		||||
			params.Add(k, replaceParamsInString(v, message, nil))
 | 
			
		||||
			params.Add(k, replaceParamsInString(ns.Server, v, message, nil))
 | 
			
		||||
		}
 | 
			
		||||
		return params.Encode(), nil
 | 
			
		||||
	}
 | 
			
		||||
@ -102,9 +109,9 @@ func (n *Notification) setRequestHeader(req *http.Request) error {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (n *Notification) Send(message string) error {
 | 
			
		||||
func (ns *NotificationServerBundle) Send(message string) error {
 | 
			
		||||
	var verifySSL bool
 | 
			
		||||
 | 
			
		||||
	n := ns.Notification
 | 
			
		||||
	if n.VerifySSL != nil && *n.VerifySSL {
 | 
			
		||||
		verifySSL = true
 | 
			
		||||
	}
 | 
			
		||||
@ -115,7 +122,7 @@ func (n *Notification) Send(message string) error {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	client := &http.Client{Transport: transCfg, Timeout: time.Minute * 10}
 | 
			
		||||
	reqBody, err := n.reqBody(message)
 | 
			
		||||
	reqBody, err := ns.reqBody(message)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
@ -125,7 +132,7 @@ func (n *Notification) Send(message string) error {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	req, err := http.NewRequest(reqMethod, n.reqURL(message), strings.NewReader(reqBody))
 | 
			
		||||
	req, err := http.NewRequest(reqMethod, ns.reqURL(message), strings.NewReader(reqBody))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
@ -150,11 +157,14 @@ func (n *Notification) Send(message string) error {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func replaceParamsInString(str string, message string, mod func(string) string) string {
 | 
			
		||||
func replaceParamsInString(s *Server, str string, message string, mod func(string) string) string {
 | 
			
		||||
	if mod != nil {
 | 
			
		||||
		str = strings.ReplaceAll(str, "#NEZHA#", mod(message))
 | 
			
		||||
	} else {
 | 
			
		||||
		str = strings.ReplaceAll(str, "#NEZHA#", message)
 | 
			
		||||
	}
 | 
			
		||||
	if s != nil {
 | 
			
		||||
		str = strings.ReplaceAll(str, "#SERVER#", s.Name)
 | 
			
		||||
	}
 | 
			
		||||
	return str
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -4,6 +4,7 @@ import (
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"testing"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/stretchr/testify/assert"
 | 
			
		||||
)
 | 
			
		||||
@ -35,8 +36,27 @@ func execCase(t *testing.T, item testSt) {
 | 
			
		||||
		RequestBody:   item.body,
 | 
			
		||||
		RequestHeader: item.header,
 | 
			
		||||
	}
 | 
			
		||||
	assert.Equal(t, item.expectURL, n.reqURL(msg))
 | 
			
		||||
	reqBody, err := n.reqBody(msg)
 | 
			
		||||
	server := Server{
 | 
			
		||||
		Common:                Common{},
 | 
			
		||||
		Name:                  "ServerName",
 | 
			
		||||
		Tag:                   "",
 | 
			
		||||
		Secret:                "",
 | 
			
		||||
		Note:                  "",
 | 
			
		||||
		DisplayIndex:          0,
 | 
			
		||||
		Host:                  nil,
 | 
			
		||||
		State:                 nil,
 | 
			
		||||
		LastActive:            time.Time{},
 | 
			
		||||
		TaskClose:             nil,
 | 
			
		||||
		TaskStream:            nil,
 | 
			
		||||
		PrevHourlyTransferIn:  0,
 | 
			
		||||
		PrevHourlyTransferOut: 0,
 | 
			
		||||
	}
 | 
			
		||||
	ns := NotificationServerBundle{
 | 
			
		||||
		Notification: &n,
 | 
			
		||||
		Server:       &server,
 | 
			
		||||
	}
 | 
			
		||||
	assert.Equal(t, item.expectURL, ns.reqURL(msg))
 | 
			
		||||
	reqBody, err := ns.reqBody(msg)
 | 
			
		||||
	assert.Nil(t, err)
 | 
			
		||||
	assert.Equal(t, item.expectBody, reqBody)
 | 
			
		||||
	reqMethod, err := n.reqMethod()
 | 
			
		||||
@ -117,6 +137,18 @@ func TestNotification(t *testing.T) {
 | 
			
		||||
			expectBody:        `{"msg":"msg"}`,
 | 
			
		||||
			expectHeader:      map[string]string{"asd": "dsa11"},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			url:               "https://example.com/?m=#NEZHA#",
 | 
			
		||||
			body:              `{"Server":"#SERVER#"}`,
 | 
			
		||||
			reqMethod:         NotificationRequestMethodPOST,
 | 
			
		||||
			header:            `{"asd":"dsa11"}`,
 | 
			
		||||
			reqType:           NotificationRequestTypeJSON,
 | 
			
		||||
			expectURL:         "https://example.com/?m=" + msg,
 | 
			
		||||
			expectMethod:      http.MethodPost,
 | 
			
		||||
			expectContentType: reqTypeJSON,
 | 
			
		||||
			expectBody:        `{"Server":"ServerName"}`,
 | 
			
		||||
			expectHeader:      map[string]string{"asd": "dsa11"},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, c := range cases {
 | 
			
		||||
 | 
			
		||||
@ -4,6 +4,8 @@ import (
 | 
			
		||||
	"crypto/md5" // #nosec
 | 
			
		||||
	"encoding/hex"
 | 
			
		||||
	"log"
 | 
			
		||||
	"regexp"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
@ -143,10 +145,24 @@ func SendNotification(notificationTag string, desc string, mutable bool) {
 | 
			
		||||
		log.Println("尝试通知", n.Name)
 | 
			
		||||
	}
 | 
			
		||||
	for _, n := range NotificationList[notificationTag] {
 | 
			
		||||
		if err := n.Send(desc); err != nil {
 | 
			
		||||
		server := findServerInMsg(desc)
 | 
			
		||||
		ns := model.NotificationServerBundle{
 | 
			
		||||
			Notification: n,
 | 
			
		||||
			Server:       server,
 | 
			
		||||
		}
 | 
			
		||||
		if err := ns.Send(desc); err != nil {
 | 
			
		||||
			log.Println("NEZHA>> 向 ", n.Name, " 发送通知失败:", err)
 | 
			
		||||
		} else {
 | 
			
		||||
			log.Println("NEZHA>> 向 ", n.Name, " 发送通知成功:")
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// findServerInMsg 通过msg字符串中的$ServerID$ 返回Server对象 未找到会返回nil
 | 
			
		||||
func findServerInMsg(msg string) *model.Server {
 | 
			
		||||
	reg1 := regexp.MustCompile(`^\$\d+`)
 | 
			
		||||
	reg2 := regexp.MustCompile(`[^$]+`)
 | 
			
		||||
	ServerIDStr := reg2.FindString(reg1.FindString(msg))
 | 
			
		||||
	ServerID, _ := strconv.ParseUint(ServerIDStr, 10, 64)
 | 
			
		||||
	return ServerList[ServerID]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user