mirror of https://github.com/allinssl/allinssl
【新增】【通知】钉钉群机器人通知类型
parent
5e874e65f8
commit
c7e8dee436
|
@ -0,0 +1,105 @@
|
||||||
|
package report
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto/hmac"
|
||||||
|
"crypto/sha256"
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DingtalkReport struct {
|
||||||
|
webHookUrl string
|
||||||
|
secret string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDingtalkReport(webHookUrl, secret string) *DingtalkReport {
|
||||||
|
return &DingtalkReport{webHookUrl: webHookUrl, secret: secret}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DingtalkReport) sign() (string, error) {
|
||||||
|
timestamp := time.Now().UnixNano() / 1000000
|
||||||
|
stringToSign := fmt.Sprintf("%d\n%s", timestamp, d.secret)
|
||||||
|
hash := hmac.New(sha256.New, []byte(d.secret))
|
||||||
|
hash.Write([]byte(stringToSign))
|
||||||
|
sum := hash.Sum(nil)
|
||||||
|
signature := base64.StdEncoding.EncodeToString(sum)
|
||||||
|
|
||||||
|
webhookurl, _ := url.Parse(d.webHookUrl)
|
||||||
|
query := webhookurl.Query()
|
||||||
|
query.Set("timestamp", fmt.Sprint(timestamp))
|
||||||
|
query.Set("sign", signature)
|
||||||
|
webhookurl.RawQuery = query.Encode()
|
||||||
|
|
||||||
|
return webhookurl.String(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DingtalkReport) SendText(msg string) error {
|
||||||
|
data := map[string]any{
|
||||||
|
"text": map[string]any{
|
||||||
|
"content": msg,
|
||||||
|
},
|
||||||
|
"msgtype": "text",
|
||||||
|
}
|
||||||
|
jsonData, err := json.Marshal(data)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
signUrl, err := d.sign()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
req, _ := http.NewRequest("POST", signUrl, bytes.NewReader(jsonData))
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
|
client := &http.Client{}
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("请求钉钉失败: %v", err)
|
||||||
|
}
|
||||||
|
body, _ := io.ReadAll(resp.Body)
|
||||||
|
defer resp.Body.Close()
|
||||||
|
var res map[string]interface{}
|
||||||
|
err = json.Unmarshal(body, &res)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("返回值解析失败: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if res["errcode"].(float64) != 0 {
|
||||||
|
return fmt.Errorf("发送失败: %s", res["errmsg"].(string))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func NotifyDingtalk(params map[string]any) error {
|
||||||
|
if params == nil {
|
||||||
|
return fmt.Errorf("缺少参数")
|
||||||
|
}
|
||||||
|
providerID := params["provider_id"].(string)
|
||||||
|
|
||||||
|
providerData, err := GetReport(providerID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
configStr := providerData["config"].(string)
|
||||||
|
var config map[string]string
|
||||||
|
err = json.Unmarshal([]byte(configStr), &config)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("解析配置失败: %v", err)
|
||||||
|
}
|
||||||
|
notifyMsg := fmt.Sprintf("%s : %s", params["subject"].(string), params["body"].(string))
|
||||||
|
|
||||||
|
report := NewDingtalkReport(config["webhook"], config["secret"])
|
||||||
|
err = report.SendText(notifyMsg)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Dingtalk发送失败: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package report
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestDingdingSend(test *testing.T) {
|
||||||
|
report := NewDingtalkReport("", "")
|
||||||
|
err := report.SendText("test msg")
|
||||||
|
if err != nil {
|
||||||
|
test.Errorf("Dingding failed: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNotifyDingding(test *testing.T) {
|
||||||
|
params := map[string]any{
|
||||||
|
"provider_id": "4",
|
||||||
|
"body": "测试消息通道",
|
||||||
|
"subject": "测试消息通道",
|
||||||
|
}
|
||||||
|
|
||||||
|
err := NotifyDingtalk(params)
|
||||||
|
if err != nil {
|
||||||
|
test.Error("NotifyDingtalk failed", "error", err)
|
||||||
|
} else {
|
||||||
|
test.Log("NotifyDingtalk success")
|
||||||
|
}
|
||||||
|
}
|
|
@ -128,6 +128,8 @@ func NotifyTest(id string) error {
|
||||||
err = NotifyWebHook(params)
|
err = NotifyWebHook(params)
|
||||||
case "feishu":
|
case "feishu":
|
||||||
err = NotifyFeishu(params)
|
err = NotifyFeishu(params)
|
||||||
|
case "dingtalk":
|
||||||
|
err = NotifyDingtalk(params)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -149,6 +151,8 @@ func Notify(params map[string]any) error {
|
||||||
return NotifyWebHook(params)
|
return NotifyWebHook(params)
|
||||||
case "feishu":
|
case "feishu":
|
||||||
return NotifyFeishu(params)
|
return NotifyFeishu(params)
|
||||||
|
case "dingtalk":
|
||||||
|
return NotifyDingtalk(params)
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("不支持的通知类型")
|
return fmt.Errorf("不支持的通知类型")
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue