129 lines
3.1 KiB
Go
129 lines
3.1 KiB
Go
![]() |
package notify
|
|||
|
|
|||
|
import (
|
|||
|
"crypto/hmac"
|
|||
|
"crypto/sha256"
|
|||
|
"encoding/base64"
|
|||
|
"encoding/json"
|
|||
|
"errors"
|
|||
|
"io/ioutil"
|
|||
|
"net/http"
|
|||
|
"net/url"
|
|||
|
"strconv"
|
|||
|
"strings"
|
|||
|
"time"
|
|||
|
|
|||
|
logrus "github.com/sirupsen/logrus"
|
|||
|
)
|
|||
|
|
|||
|
const DingdingMsgType_Markdown = "markdown"
|
|||
|
|
|||
|
type DingdingMsg struct {
|
|||
|
RobotName string
|
|||
|
Topic string
|
|||
|
Ctype string
|
|||
|
Content string
|
|||
|
AtAll bool
|
|||
|
UniqueCode string
|
|||
|
}
|
|||
|
|
|||
|
func (dd *DingdingMsg) AddItemListGrp(title string, level int, list []string) error {
|
|||
|
pre := ""
|
|||
|
if level < 1 {
|
|||
|
err := errors.New("level is not allow " + strconv.FormatInt(int64(level), 10))
|
|||
|
return err
|
|||
|
}
|
|||
|
for i := level; i > 0; i-- {
|
|||
|
pre = pre + "#"
|
|||
|
}
|
|||
|
title = pre + " " + title
|
|||
|
dd.Content += "\n"
|
|||
|
dd.Content += title
|
|||
|
dd.Content += "\n"
|
|||
|
for _, v := range list {
|
|||
|
dd.Content += v
|
|||
|
dd.Content += "\n"
|
|||
|
}
|
|||
|
return nil
|
|||
|
}
|
|||
|
|
|||
|
func MakeSign(baseUrl string, secure string, token string, tm time.Time) string {
|
|||
|
tsi := tm.UnixMilli()
|
|||
|
tsi = tsi - tsi%60000
|
|||
|
tss := strconv.FormatInt(tsi, 10)
|
|||
|
sign := tss + "\n" + secure
|
|||
|
sign = ComputeHmac256(secure, sign)
|
|||
|
sign = url.QueryEscape(sign)
|
|||
|
|
|||
|
url := baseUrl + "?access_token=" + token + "×tamp=" + tss + "&sign=" + sign
|
|||
|
return url
|
|||
|
}
|
|||
|
|
|||
|
func (dd *DingdingMsg) MakeContent() []byte {
|
|||
|
ctn := map[string]interface{}{}
|
|||
|
ctn["msgtype"] = dd.Ctype
|
|||
|
if dd.Ctype == DingdingMsgType_Markdown {
|
|||
|
md := map[string]interface{}{}
|
|||
|
md["title"] = dd.Topic
|
|||
|
md["text"] = dd.Content
|
|||
|
md["isAtAll"] = dd.AtAll
|
|||
|
ctn[DingdingMsgType_Markdown] = md
|
|||
|
}
|
|||
|
btn, _ := json.Marshal(ctn)
|
|||
|
return btn
|
|||
|
}
|
|||
|
|
|||
|
func ComputeHmac256(secret string, message string) string {
|
|||
|
h := hmac.New(sha256.New, []byte(secret))
|
|||
|
h.Write([]byte(message))
|
|||
|
return base64.StdEncoding.EncodeToString(h.Sum(nil))
|
|||
|
}
|
|||
|
|
|||
|
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 {
|
|||
|
logrus.Warn("postHeader err: ", err)
|
|||
|
return "", err
|
|||
|
}
|
|||
|
defer resp.Body.Close()
|
|||
|
body, err := ioutil.ReadAll(resp.Body)
|
|||
|
if err != nil {
|
|||
|
return "", err
|
|||
|
}
|
|||
|
return string(body), nil
|
|||
|
}
|
|||
|
func (dd *DingdingMsg) PostToRobot(rbt string, cr *Core) (string, error) {
|
|||
|
baseUrl, _ := cr.Cfg.Config.Get("dingding").Get("baseUrl").String()
|
|||
|
secret, _ := cr.Cfg.Config.Get("dingding").Get("robots").Get(rbt).Get("secret").String()
|
|||
|
token, _ := cr.Cfg.Config.Get("dingding").Get("robots").Get(rbt).Get("accessToken").String()
|
|||
|
cli := cr.RedisLocalCli
|
|||
|
|
|||
|
if len(dd.UniqueCode) > 0 {
|
|||
|
unique := "ddPostUnique|" + dd.UniqueCode
|
|||
|
exists, _ := cli.Exists(unique).Result()
|
|||
|
if exists == 1 {
|
|||
|
err := errors.New("20分钟内已经投递过了,不再重复")
|
|||
|
return "", err
|
|||
|
}
|
|||
|
cli.Set(unique, 1, 20*time.Minute).Result()
|
|||
|
}
|
|||
|
nw := time.Now()
|
|||
|
url := MakeSign(baseUrl, secret, token, nw)
|
|||
|
|
|||
|
ctn := dd.MakeContent()
|
|||
|
headers := make(map[string]string)
|
|||
|
headers["Content-Type"] = "application/json;charset=utf-8"
|
|||
|
res, err := PostHeader(url, ctn, headers)
|
|||
|
logrus.Warn("postToRobot res:", res, string(ctn))
|
|||
|
return res, err
|
|||
|
}
|