zhangqian
2024-04-17 7bed630958e25d632903e19a57c1735b9dc9d8d8
增加钉钉机器人报警功能
3个文件已添加
4个文件已修改
155 ■■■■■ 已修改文件
conf/config.go 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
conf/config.yaml 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main.go 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/alarm.go 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
task/month_stats.go 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
utils/dingtalkrobot/message.go 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
utils/dingtalkrobot/robot.go 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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("......................................................")
}
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
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())
}
service/alarm.go
New file
@@ -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)
}
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))
            }
        }
    }
utils/dingtalkrobot/message.go
New file
@@ -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,
        },
    }
}
utils/dingtalkrobot/robot.go
New file
@@ -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
}