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"
 | 
							verifySSL := nf.VerifySSL == "on"
 | 
				
			||||||
		n.VerifySSL = &verifySSL
 | 
							n.VerifySSL = &verifySSL
 | 
				
			||||||
		n.ID = nf.ID
 | 
							n.ID = nf.ID
 | 
				
			||||||
		err = n.Send("这是测试消息")
 | 
							ns := model.NotificationServerBundle{
 | 
				
			||||||
 | 
								Notification: &n,
 | 
				
			||||||
 | 
								Server:       nil,
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							err = ns.Send("这是测试消息")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if err == nil {
 | 
						if err == nil {
 | 
				
			||||||
		// 保证Tag不为空
 | 
							// 保证Tag不为空
 | 
				
			||||||
 | 
				
			|||||||
@ -25,6 +25,11 @@ const (
 | 
				
			|||||||
	NotificationRequestMethodPOST
 | 
						NotificationRequestMethodPOST
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type NotificationServerBundle struct {
 | 
				
			||||||
 | 
						Notification *Notification
 | 
				
			||||||
 | 
						Server       *Server
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Notification struct {
 | 
					type Notification struct {
 | 
				
			||||||
	Common
 | 
						Common
 | 
				
			||||||
	Name          string
 | 
						Name          string
 | 
				
			||||||
@ -37,8 +42,9 @@ type Notification struct {
 | 
				
			|||||||
	VerifySSL     *bool
 | 
						VerifySSL     *bool
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (n *Notification) reqURL(message string) string {
 | 
					func (ns *NotificationServerBundle) reqURL(message string) string {
 | 
				
			||||||
	return replaceParamsInString(n.URL, message, func(msg string) string {
 | 
						n := ns.Notification
 | 
				
			||||||
 | 
						return replaceParamsInString(ns.Server, n.URL, message, func(msg string) string {
 | 
				
			||||||
		return url.QueryEscape(msg)
 | 
							return url.QueryEscape(msg)
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -53,13 +59,14 @@ func (n *Notification) reqMethod() (string, error) {
 | 
				
			|||||||
	return "", errors.New("不支持的请求方式")
 | 
						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 == "" {
 | 
						if n.RequestMethod == NotificationRequestMethodGET || message == "" {
 | 
				
			||||||
		return "", nil
 | 
							return "", nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	switch n.RequestType {
 | 
						switch n.RequestType {
 | 
				
			||||||
	case NotificationRequestTypeJSON:
 | 
						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)
 | 
								msgBytes, _ := utils.Json.Marshal(msg)
 | 
				
			||||||
			return string(msgBytes)[1 : len(msgBytes)-1]
 | 
								return string(msgBytes)[1 : len(msgBytes)-1]
 | 
				
			||||||
		}), nil
 | 
							}), nil
 | 
				
			||||||
@ -70,7 +77,7 @@ func (n *Notification) reqBody(message string) (string, error) {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		params := url.Values{}
 | 
							params := url.Values{}
 | 
				
			||||||
		for k, v := range data {
 | 
							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
 | 
							return params.Encode(), nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -102,9 +109,9 @@ func (n *Notification) setRequestHeader(req *http.Request) error {
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (n *Notification) Send(message string) error {
 | 
					func (ns *NotificationServerBundle) Send(message string) error {
 | 
				
			||||||
	var verifySSL bool
 | 
						var verifySSL bool
 | 
				
			||||||
 | 
						n := ns.Notification
 | 
				
			||||||
	if n.VerifySSL != nil && *n.VerifySSL {
 | 
						if n.VerifySSL != nil && *n.VerifySSL {
 | 
				
			||||||
		verifySSL = true
 | 
							verifySSL = true
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -115,7 +122,7 @@ func (n *Notification) Send(message string) error {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	client := &http.Client{Transport: transCfg, Timeout: time.Minute * 10}
 | 
						client := &http.Client{Transport: transCfg, Timeout: time.Minute * 10}
 | 
				
			||||||
	reqBody, err := n.reqBody(message)
 | 
						reqBody, err := ns.reqBody(message)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -125,7 +132,7 @@ func (n *Notification) Send(message string) error {
 | 
				
			|||||||
		return err
 | 
							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 {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -150,11 +157,14 @@ func (n *Notification) Send(message string) error {
 | 
				
			|||||||
	return nil
 | 
						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 {
 | 
						if mod != nil {
 | 
				
			||||||
		str = strings.ReplaceAll(str, "#NEZHA#", mod(message))
 | 
							str = strings.ReplaceAll(str, "#NEZHA#", mod(message))
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		str = strings.ReplaceAll(str, "#NEZHA#", message)
 | 
							str = strings.ReplaceAll(str, "#NEZHA#", message)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if s != nil {
 | 
				
			||||||
 | 
							str = strings.ReplaceAll(str, "#SERVER#", s.Name)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return str
 | 
						return str
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -4,6 +4,7 @@ import (
 | 
				
			|||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
	"testing"
 | 
						"testing"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/stretchr/testify/assert"
 | 
						"github.com/stretchr/testify/assert"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@ -35,8 +36,27 @@ func execCase(t *testing.T, item testSt) {
 | 
				
			|||||||
		RequestBody:   item.body,
 | 
							RequestBody:   item.body,
 | 
				
			||||||
		RequestHeader: item.header,
 | 
							RequestHeader: item.header,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	assert.Equal(t, item.expectURL, n.reqURL(msg))
 | 
						server := Server{
 | 
				
			||||||
	reqBody, err := n.reqBody(msg)
 | 
							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.Nil(t, err)
 | 
				
			||||||
	assert.Equal(t, item.expectBody, reqBody)
 | 
						assert.Equal(t, item.expectBody, reqBody)
 | 
				
			||||||
	reqMethod, err := n.reqMethod()
 | 
						reqMethod, err := n.reqMethod()
 | 
				
			||||||
@ -117,6 +137,18 @@ func TestNotification(t *testing.T) {
 | 
				
			|||||||
			expectBody:        `{"msg":"msg"}`,
 | 
								expectBody:        `{"msg":"msg"}`,
 | 
				
			||||||
			expectHeader:      map[string]string{"asd": "dsa11"},
 | 
								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 {
 | 
						for _, c := range cases {
 | 
				
			||||||
 | 
				
			|||||||
@ -4,6 +4,8 @@ import (
 | 
				
			|||||||
	"crypto/md5" // #nosec
 | 
						"crypto/md5" // #nosec
 | 
				
			||||||
	"encoding/hex"
 | 
						"encoding/hex"
 | 
				
			||||||
	"log"
 | 
						"log"
 | 
				
			||||||
 | 
						"regexp"
 | 
				
			||||||
 | 
						"strconv"
 | 
				
			||||||
	"sync"
 | 
						"sync"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -143,10 +145,24 @@ func SendNotification(notificationTag string, desc string, mutable bool) {
 | 
				
			|||||||
		log.Println("尝试通知", n.Name)
 | 
							log.Println("尝试通知", n.Name)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for _, n := range NotificationList[notificationTag] {
 | 
						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)
 | 
								log.Println("NEZHA>> 向 ", n.Name, " 发送通知失败:", err)
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			log.Println("NEZHA>> 向 ", n.Name, " 发送通知成功:")
 | 
								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