mirror of
https://gitee.com/mirrors/AllinSSL.git
synced 2026-03-13 01:50:53 +08:00
新增企业微信通道
新增申请证书buypass 新增版本更新提醒 webhook、企业微信支持动态参数 监控支持域名加端口 ssh部署支持域名
This commit is contained in:
@@ -130,6 +130,8 @@ func NotifyTest(id string) error {
|
||||
err = NotifyFeishu(params)
|
||||
case "dingtalk":
|
||||
err = NotifyDingtalk(params)
|
||||
case "workwx":
|
||||
err = NotifyWorkWx(params)
|
||||
}
|
||||
return err
|
||||
}
|
||||
@@ -153,6 +155,8 @@ func Notify(params map[string]any) error {
|
||||
return NotifyFeishu(params)
|
||||
case "dingtalk":
|
||||
return NotifyDingtalk(params)
|
||||
case "workwx":
|
||||
return NotifyWorkWx(params)
|
||||
default:
|
||||
return fmt.Errorf("不支持的通知类型")
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"fmt"
|
||||
"github.com/go-resty/resty/v2"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
@@ -29,15 +30,15 @@ type WebHookReporter struct {
|
||||
func NewWebHookReporter(config *ReportConfig, logger *public.Logger) *WebHookReporter {
|
||||
client := resty.New()
|
||||
client.SetTimeout(30 * time.Second)
|
||||
|
||||
|
||||
if config.IgnoreSSL {
|
||||
client.SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true})
|
||||
}
|
||||
|
||||
|
||||
if config.Data == "" {
|
||||
config.Data = "{}" // 默认数据为空JSON对象
|
||||
}
|
||||
|
||||
|
||||
return &WebHookReporter{
|
||||
config: config,
|
||||
logger: logger,
|
||||
@@ -51,11 +52,11 @@ func (w *WebHookReporter) Send(ctx context.Context) error {
|
||||
if method == "" {
|
||||
method = http.MethodPost // 默认使用POST方法
|
||||
}
|
||||
|
||||
|
||||
// 创建基础请求
|
||||
req := w.httpClient.R().
|
||||
SetContext(ctx)
|
||||
|
||||
|
||||
// 设置请求头
|
||||
if w.config.Headers != "" {
|
||||
reqHeader, err := w.ParseHeaders(w.config.Headers)
|
||||
@@ -64,7 +65,7 @@ func (w *WebHookReporter) Send(ctx context.Context) error {
|
||||
}
|
||||
req.Header = reqHeader
|
||||
}
|
||||
|
||||
|
||||
switch method {
|
||||
case http.MethodPost:
|
||||
{
|
||||
@@ -111,17 +112,17 @@ func (w *WebHookReporter) Send(ctx context.Context) error {
|
||||
default:
|
||||
return fmt.Errorf("暂不支持的HTTP方法: %s", method)
|
||||
}
|
||||
|
||||
|
||||
// 发送请求
|
||||
resp, err := req.Execute(method, w.config.Url)
|
||||
if err != nil {
|
||||
if w.logger != nil {
|
||||
w.logger.Error(fmt.Sprintf("Webhook请求失败%s %v", w.config.Url, err))
|
||||
}
|
||||
|
||||
|
||||
return fmt.Errorf("webhook请求失败: %w", err)
|
||||
}
|
||||
|
||||
|
||||
// 处理响应
|
||||
if resp.IsError() {
|
||||
if w.logger != nil {
|
||||
@@ -129,7 +130,7 @@ func (w *WebHookReporter) Send(ctx context.Context) error {
|
||||
}
|
||||
return fmt.Errorf("webhook返回错误状态码: %d", resp.StatusCode())
|
||||
}
|
||||
|
||||
|
||||
if w.logger != nil {
|
||||
w.logger.Debug(fmt.Sprintf("Webhook请求成功 %s", w.config.Url))
|
||||
}
|
||||
@@ -139,7 +140,7 @@ func (w *WebHookReporter) Send(ctx context.Context) error {
|
||||
func (w *WebHookReporter) ParseHeaders(headerStr string) (http.Header, error) {
|
||||
headers := make(http.Header)
|
||||
lines := strings.Split(headerStr, "\n")
|
||||
|
||||
|
||||
for i, line := range lines {
|
||||
line = strings.TrimSpace(line)
|
||||
if line == "" {
|
||||
@@ -157,7 +158,7 @@ func (w *WebHookReporter) ParseHeaders(headerStr string) (http.Header, error) {
|
||||
canonicalKey := http.CanonicalHeaderKey(key)
|
||||
headers.Add(canonicalKey, value)
|
||||
}
|
||||
|
||||
|
||||
return headers, nil
|
||||
}
|
||||
|
||||
@@ -166,13 +167,13 @@ func NotifyWebHook(params map[string]any) error {
|
||||
return fmt.Errorf("缺少参数")
|
||||
}
|
||||
providerID := params["provider_id"].(string)
|
||||
|
||||
|
||||
var logger *public.Logger
|
||||
|
||||
|
||||
if params["logger"] != nil {
|
||||
logger = params["logger"].(*public.Logger)
|
||||
}
|
||||
|
||||
|
||||
providerData, err := GetReport(providerID)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -183,7 +184,11 @@ func NotifyWebHook(params map[string]any) error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("解析配置失败: %v", err)
|
||||
}
|
||||
|
||||
config.Data, err = ReplaceJSONPlaceholders(config.Data, params)
|
||||
if err != nil {
|
||||
return fmt.Errorf("替换JSON占位符失败: %w", err)
|
||||
}
|
||||
|
||||
reporter := NewWebHookReporter(&config, logger)
|
||||
httpctx := context.Background()
|
||||
err = reporter.Send(httpctx)
|
||||
@@ -192,3 +197,16 @@ func NotifyWebHook(params map[string]any) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func ReplaceJSONPlaceholders(jsonStr string, vars map[string]any) (string, error) {
|
||||
re := regexp.MustCompile(`__([a-zA-Z0-9_]+)__`)
|
||||
result := re.ReplaceAllStringFunc(jsonStr, func(match string) string {
|
||||
key := re.FindStringSubmatch(match)[1]
|
||||
if val, ok := vars[key]; ok {
|
||||
return fmt.Sprintf("%v", val) // 将 any 类型转换为字符串
|
||||
}
|
||||
return match // 未匹配到变量则保留原样
|
||||
})
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
87
backend/internal/report/workwx.go
Normal file
87
backend/internal/report/workwx.go
Normal file
@@ -0,0 +1,87 @@
|
||||
package report
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func PostHeader(url string, msg []byte, headers map[string]string) (string, error) {
|
||||
client := &http.Client{}
|
||||
|
||||
req, err := http.NewRequest("POST", url, strings.NewReader(string(msg)))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
for key, header := range headers {
|
||||
req.Header.Set(key, header)
|
||||
}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(body), nil
|
||||
}
|
||||
|
||||
func PostJson(url string, msg []byte) (string, error) {
|
||||
headers := make(map[string]string)
|
||||
headers["Content-Type"] = "application/json;charset=utf-8"
|
||||
res, err := PostHeader(url, msg, headers)
|
||||
return res, err
|
||||
}
|
||||
|
||||
func NotifyWorkWx(params map[string]any) error {
|
||||
if params == nil {
|
||||
return fmt.Errorf("缺少参数")
|
||||
}
|
||||
providerID := params["provider_id"].(string)
|
||||
// fmt.Println(providerID)
|
||||
providerData, err := GetReport(providerID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
configStr := providerData["config"].(string)
|
||||
fmt.Println(configStr)
|
||||
var config map[string]string
|
||||
err = json.Unmarshal([]byte(configStr), &config)
|
||||
if err != nil {
|
||||
return fmt.Errorf("解析配置失败: %v", err)
|
||||
}
|
||||
url := config["url"]
|
||||
if url == "" {
|
||||
return fmt.Errorf("缺少企业微信URL配置")
|
||||
}
|
||||
if config["data"] == "" {
|
||||
config["data"] = `
|
||||
{
|
||||
"msgtype": "news",
|
||||
"news": {
|
||||
"articles" : [
|
||||
{
|
||||
"title" : "__subject__",
|
||||
"description" : "__body__。",
|
||||
"url" : "https://allinssl.com/",
|
||||
"picurl" : "https://allinssl.com/logo.svg"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
`
|
||||
}
|
||||
msg, err := ReplaceJSONPlaceholders(config["data"], params)
|
||||
if err != nil {
|
||||
return fmt.Errorf("替换JSON占位符失败: %v", err)
|
||||
}
|
||||
_, err = PostJson(url, []byte(msg))
|
||||
if err != nil {
|
||||
return fmt.Errorf("发送企业微信消息失败: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user