From 7bed630958e25d632903e19a57c1735b9dc9d8d8 Mon Sep 17 00:00:00 2001
From: zhangqian <zhangqian@123.com>
Date: 星期三, 17 四月 2024 13:38:34 +0800
Subject: [PATCH] 增加钉钉机器人报警功能

---
 utils/dingtalkrobot/robot.go   |   92 ++++++++++++++++++++++++++++++
 task/month_stats.go            |    4 +
 service/alarm.go               |   12 ++++
 conf/config.go                 |    8 ++
 main.go                        |    5 +
 conf/config.yaml               |    3 +
 utils/dingtalkrobot/message.go |   31 ++++++++++
 7 files changed, 155 insertions(+), 0 deletions(-)

diff --git a/conf/config.go b/conf/config.go
index c521566..c9887c0 100644
--- a/conf/config.go
+++ b/conf/config.go
@@ -47,6 +47,11 @@
 	fileTemplateConf struct {
 		InputSelfmadeAddr string //鍏ュ簱鑷埗鍗曟ā鐗堝湴鍧�
 	}
+
+	dingTalkConf struct {
+		AlarmKey string
+		AlarmUrl string
+	}
 )
 
 var (
@@ -56,6 +61,7 @@
 	LocalConf      = &localConf{}
 	Viper          *viper.Viper
 	GrpcServerConf = &grpcServerConf{}
+	DingTalkConf   = &dingTalkConf{}
 )
 
 func Init() error {
@@ -117,6 +123,7 @@
 	_ = v.UnmarshalKey("db", DbConf)
 	_ = v.UnmarshalKey("local", LocalConf)
 	_ = v.UnmarshalKey("grpcServer", GrpcServerConf)
+	_ = v.UnmarshalKey("dingTalk", DingTalkConf)
 	showConfig()
 }
 
@@ -127,5 +134,6 @@
 	log.Printf("   DbConf:                 %+v", DbConf)
 	log.Printf("   LocalConf:               %+v", LocalConf)
 	log.Printf("   GrpcServerConf:               %+v", GrpcServerConf)
+	log.Printf("   DingTalkConf:               %+v", DingTalkConf)
 	log.Println("......................................................")
 }
diff --git a/conf/config.yaml b/conf/config.yaml
index 3ae36d8..4664ec9 100644
--- a/conf/config.yaml
+++ b/conf/config.yaml
@@ -29,3 +29,6 @@
   apsAddr: 192.168.20.119:9091
   crmAddr: 192.168.20.119:9092
   srmAddr: 192.168.20.119:9093
+dingTalk:
+  alarmKey: SEC31ccce95daf26763ab54575bd4cac156f22ed0a42f3e27d3edd06edb77b3d221
+  alarmUrl: https://oapi.dingtalk.com/robot/send?access_token=c6023d2c55058b86d59290ad205eff86a8c681a7807f76c569f91434663081fa
diff --git a/main.go b/main.go
index cbc62e9..99e764c 100644
--- a/main.go
+++ b/main.go
@@ -20,6 +20,7 @@
 	"wms/router"
 	"wms/service"
 	"wms/task"
+	"wms/utils/dingtalkrobot"
 )
 
 func main() {
@@ -76,8 +77,12 @@
 	go service.InitLocationReportData()
 	go service.InitHistoryReportData()
 
+	//瀹氭椂浠诲姟鍒濆鍖�
 	task.Init()
 
+	//閽夐拤鏈哄櫒浜哄垵濮嬪寲
+	dingtalkrobot.Init(conf.DingTalkConf.AlarmKey, conf.DingTalkConf.AlarmUrl)
+
 	logx.Error(server.ListenAndServe().Error())
 }
 
diff --git a/service/alarm.go b/service/alarm.go
new file mode 100644
index 0000000..9a4bff6
--- /dev/null
+++ b/service/alarm.go
@@ -0,0 +1,12 @@
+package service
+
+import (
+	"wms/conf"
+	"wms/utils/dingtalkrobot"
+)
+
+func SendAlarm(title, content string) {
+	title = "WMS鎶ヨ"
+	content = "-鏍囬锛�" + title + "\n- 鍏徃锛�" + conf.WebConf.CompanyName + "\n - 鎶ヨ鍐呭锛�" + content
+	dingtalkrobot.Robot.Alarm(title, content)
+}
diff --git a/task/month_stats.go b/task/month_stats.go
index 2b33ef6..6947b73 100644
--- a/task/month_stats.go
+++ b/task/month_stats.go
@@ -2,11 +2,13 @@
 
 import (
 	"encoding/json"
+	"fmt"
 	"github.com/shopspring/decimal"
 	"time"
 	"wms/constvar"
 	"wms/models"
 	"wms/pkg/logx"
+	"wms/service"
 )
 
 func MonthStats() {
@@ -127,6 +129,7 @@
 		err = models.NewMonthStatsSearch().Create(&record)
 		if err != nil {
 			logx.Errorf("NewMonthStatsSearch Create err:%v, record: %+v", err, record)
+			service.SendAlarm("鏈堝害缁熻鍒涘缓鏈湀澶辫触", fmt.Sprintf("NewMonthStatsSearch Create err:%v, record: %+v", err, record))
 		}
 
 		if oldRecordsMap[productId] != nil && (!inputMap[productId].IsZero() || !outputMap[productId].IsZero()) {
@@ -145,6 +148,7 @@
 			err = models.NewMonthStatsSearch().SetID(oldRecordsMap[productId].Id).UpdateByMap(m)
 			if err != nil {
 				logx.Errorf("NewMonthStatsSearch UpdateByMap err:%v, id:%v, m:%+v", err, oldRecordsMap[productId].ID, m)
+				service.SendAlarm("鏈堝害缁熻鏇存敼涓婃湀澶辫触", fmt.Sprintf("NewMonthStatsSearch Create err:%v, record: %+v", err, record))
 			}
 		}
 	}
diff --git a/utils/dingtalkrobot/message.go b/utils/dingtalkrobot/message.go
new file mode 100644
index 0000000..2a3ae7a
--- /dev/null
+++ b/utils/dingtalkrobot/message.go
@@ -0,0 +1,31 @@
+package dingtalkrobot
+
+import "fmt"
+
+type message interface {
+	String() string
+}
+
+type MarkdownMessage struct {
+	MsgType  string   `json:"msgtype"`
+	Markdown markdown `json:"markdown"`
+}
+
+type markdown struct {
+	Title string `json:"title"`
+	Text  string `json:"text"`
+}
+
+func (m *MarkdownMessage) String() string {
+	return fmt.Sprintf("markdown message, title: %v, content: %v", m.Markdown.Title, m.Markdown.Text)
+}
+
+func NewMarkdownMessage(title string, content string) *MarkdownMessage {
+	return &MarkdownMessage{
+		MsgType: "markdown",
+		Markdown: markdown{
+			Title: title,
+			Text:  content,
+		},
+	}
+}
diff --git a/utils/dingtalkrobot/robot.go b/utils/dingtalkrobot/robot.go
new file mode 100644
index 0000000..04b2474
--- /dev/null
+++ b/utils/dingtalkrobot/robot.go
@@ -0,0 +1,92 @@
+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&timestamp=%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
+}

--
Gitblit v1.8.0