package dingtalkrobot
|
|
import (
|
"bytes"
|
"crypto/hmac"
|
"crypto/sha256"
|
"encoding/base64"
|
"encoding/json"
|
"fmt"
|
"io"
|
"net/http"
|
"net/url"
|
"time"
|
"wms/pkg/logx"
|
)
|
|
type robot struct {
|
Key string
|
Url string
|
}
|
|
var Robot *robot
|
|
func Init(key, url string) {
|
Robot = &robot{Key: key, Url: url}
|
}
|
|
type response struct {
|
ErrMsg string `json:"errmsg"`
|
ErrCode int `json:"errcode"`
|
}
|
|
func (r *robot) Alarm(title, content string) {
|
nanoTimestamp := time.Now().UnixNano()
|
ts := nanoTimestamp / int64(time.Millisecond)
|
sign, err := r.sign(ts)
|
if err != nil {
|
logx.Errorf("send alarm message sign failed, err: %v", err)
|
return
|
}
|
|
fullUrl := fmt.Sprintf("%s×tamp=%v&sign=%s", r.Url, ts, sign)
|
msg := NewMarkdownMessage(title, content)
|
|
err = r.send(fullUrl, msg)
|
if err != nil {
|
logx.Errorf("send alarm message failed, err: %v, message: %s", err, msg)
|
return
|
}
|
|
logx.Infof("send alarm message ok, message: %s", msg)
|
}
|
|
func (r *robot) sign(ts int64) (string, error) {
|
text := fmt.Sprintf("%v\n%v", ts, r.Key)
|
h := hmac.New(sha256.New, []byte(r.Key))
|
_, err := h.Write([]byte(text))
|
if err != nil {
|
return "", err
|
}
|
|
value := h.Sum(nil)
|
sign := base64.StdEncoding.EncodeToString(value)
|
return url.QueryEscape(sign), nil
|
}
|
|
func (r *robot) send(url string, message interface{}) error {
|
msgBytes, _ := json.Marshal(message)
|
body := bytes.NewBuffer(msgBytes)
|
|
resp, err := http.Post(url, "application/json", body)
|
if err != nil {
|
return fmt.Errorf("error making POST request: %v", err)
|
}
|
defer resp.Body.Close()
|
|
var result response
|
bts, err := io.ReadAll(resp.Body)
|
if err != nil {
|
return fmt.Errorf("error reading response body: %v", err)
|
}
|
|
err = json.Unmarshal(bts, &result)
|
if err != nil {
|
return fmt.Errorf("error decoding JSON: %v", err)
|
}
|
|
if result.ErrCode != 0 {
|
return fmt.Errorf("error returned: ErrCode=%d, ErrMsg=%s", result.ErrCode, result.ErrMsg)
|
}
|
return nil
|
}
|