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 }