Skip to content

Commit

Permalink
add 模板支持
Browse files Browse the repository at this point in the history
  • Loading branch information
sdvdxl committed Jul 19, 2019
1 parent 7d4a67e commit b023970
Show file tree
Hide file tree
Showing 7 changed files with 246 additions and 168 deletions.
24 changes: 13 additions & 11 deletions cfg.example.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
{
"addr": "localhost:23329",
"dingTalk": {
"enable": true
},
"wexin": {
"enable": false,
"corpID": "",
"agentId": "",
"secret": "",
"encodingAESKey": ""
}
"addr": "localhost:23329",
"dingTalk": {
"enable": true,
"templateFile": "message-template.md",
"messageType": "markdown"
},
"wexin": {
"enable": false,
"corpID": "",
"agentId": "",
"secret": "",
"encodingAESKey": ""
}
}
60 changes: 36 additions & 24 deletions config/config.go
Original file line number Diff line number Diff line change
@@ -1,46 +1,58 @@
package config

import (
"encoding/json"
"io/ioutil"
"log"
"encoding/json"
"io/ioutil"
"log"
)

// Config 配置
type Config struct {
Addr string `json:"addr"`
DingTalk DingTalk `json:"dingTalk"`
Addr string `json:"addr"`
DingTalk DingTalk `json:"dingTalk"`

Weixin Weixin `json:"weixin"`
Weixin Weixin `json:"weixin"`
}

// Weixin 微信配置
type Weixin struct {
Enable bool
CorpID string `json:"corpID"`
AgentID string `json:"agentId"`
Secret string `json:"secret"`
EncodingAESKey string `json:"encodingAESKey"`
Enable bool
CorpID string `json:"corpID"`
AgentID string `json:"agentId"`
Secret string `json:"secret"`
EncodingAESKey string `json:"encodingAESKey"`
}

type AlarmMessage struct {
Level string // 告警等级 P1
Type string // 类型 PROBLEM,OK
Endpoint string // 主机host或者ip
Desc string // 告警描述
Condition string // 告警条件
Count string // 当前告警次数
Time string // 告警时间
}

// DingTalk 钉钉配置
type DingTalk struct {
Enable bool `json:"enable"`
// Level 等级, 只发送level 及其以下的消息
Enable bool `json:"enable"`
// Level 等级, 只发送level 及其以下 的消息

Level uint `json:"level"`
Level uint `json:"level"`
TemplateFile string
MessageType string // markdown ,text
}

// Read 读取配置
func Read() Config {
bytes, err := ioutil.ReadFile("cfg.json")
if err != nil {
log.Fatalln("need file: cfg.json")
}
var cfg Config
if err = json.Unmarshal(bytes, &cfg); err != nil {
log.Fatalln("config file error", err.Error())
}

return cfg
bytes, err := ioutil.ReadFile("cfg.json")
if err != nil {
log.Fatalln("need file: cfg.json")
}
var cfg Config
if err = json.Unmarshal(bytes, &cfg); err != nil {
log.Fatalln("config file error", err.Error())
}

return cfg
}
191 changes: 106 additions & 85 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
package main

import (
"errors"
"log"
"net/http"
"strings"
"time"

"github.com/labstack/echo"
"github.com/labstack/echo/middleware"
"github.com/sdvdxl/falcon-message/config"
"github.com/sdvdxl/falcon-message/sender"
"github.com/sdvdxl/falcon-message/util"
"github.com/tylerb/graceful"
"bytes"
"errors"
"html/template"
"log"
"net/http"
"strings"
"time"

"github.com/labstack/echo"
"github.com/labstack/echo/middleware"
"github.com/sdvdxl/falcon-message/config"
"github.com/sdvdxl/falcon-message/sender"
"github.com/sdvdxl/falcon-message/util"
"github.com/tylerb/graceful"
)

// OK
Expand All @@ -27,87 +29,106 @@ import (
// http://127.0.0.1:8081/portal/template/view/37

const (
// IMDingPrefix 钉钉 前缀
IMDingPrefix = "[ding]:"
// IMWexinPrefix 微信前缀
// IMWexinPrefix = "[wexin]:"
// IMDingPrefix 钉钉 前缀
IMDingPrefix = "[ding]:"
// IMWexinPrefix 微信前缀
// IMWexinPrefix = "[wexin]:"
)

var (
cfg config.Config
ding *sender.DingTalk
wx *sender.Weixin
cfg config.Config
ding *sender.DingTalk
wx *sender.Weixin
)

func main() {
cfg = config.Read()

if cfg.DingTalk.Enable {
ding = sender.NewDingTalk()
}

if cfg.Weixin.Enable {
wx = sender.NewWeixin(cfg.Weixin.CorpID, cfg.Weixin.Secret)
go wx.GetAccessToken()
}

engine := echo.New()
engine.Server.Addr = cfg.Addr
server := &graceful.Server{Timeout: time.Second * 10, Server: engine.Server, Logger: graceful.DefaultLogger()}
engine.Use(middleware.Recover())
// engine.Use(middleware.Logger())
api := engine.Group("/api/v1")
api.GET("/wechat/auth", wxAuth)
api.POST("/message", func(c echo.Context) error {
log.Println("message comming")
tos := c.FormValue("tos")
content := c.FormValue("content")
log.Println("tos:", tos, " content:", content)
if content == "" {
return echo.NewHTTPError(http.StatusBadRequest, "content is requied")
}

content = util.HandleContent(content)
if strings.HasPrefix(tos, IMDingPrefix) { //是钉钉
tokens := tos[len(IMDingPrefix):]

if cfg.DingTalk.Enable {
for _, v := range strings.Split(tokens, ";") {
go ding.Send(v, content)
}
}
} else { //微信
if cfg.Weixin.Enable {
if err := wx.Send(tos, content); err != nil {
return echo.NewHTTPError(500, err.Error())
}
}
}

return nil
})

log.Println("listening on ", cfg.Addr)
if err := server.ListenAndServe(); err != nil {
log.Fatal(err)
}
cfg = config.Read()

if cfg.DingTalk.Enable {
ding = sender.NewDingTalk()
}

if cfg.Weixin.Enable {
wx = sender.NewWeixin(cfg.Weixin.CorpID, cfg.Weixin.Secret)
go wx.GetAccessToken()
}

engine := echo.New()
engine.Server.Addr = cfg.Addr
server := &graceful.Server{Timeout: time.Second * 10, Server: engine.Server, Logger: graceful.DefaultLogger()}
engine.Use(middleware.Recover())
// engine.Use(middleware.Logger())
api := engine.Group("/api/v1")
api.GET("/wechat/auth", wxAuth)
api.POST("/message", func(c echo.Context) error {
log.Println("message comming")
tos := c.FormValue("tos")
content := c.FormValue("content")
log.Println("tos:", tos, " content:", content)
if content == "" {
return echo.NewHTTPError(http.StatusBadRequest, "content is requied")
}

msg, err := util.HandleContent(content)
if err != nil {
return err
}

t, err := template.New("alarm").ParseFiles(cfg.DingTalk.TemplateFile)
if err != nil {
return err
}

var buffer bytes.Buffer
if err := t.Execute(&buffer, msg); err != nil {
return err
}
content = buffer.String()

if strings.HasPrefix(tos, IMDingPrefix) { //是钉钉
tokens := tos[len(IMDingPrefix):]

if cfg.DingTalk.Enable {
for _, v := range strings.Split(tokens, ";") {
go func() {
if err := ding.Send(v, content, cfg.DingTalk.MessageType); err != nil {
log.Println("ERR:", err)
}
}()
}
}
} else { //微信
if cfg.Weixin.Enable {
if err := wx.Send(tos, content); err != nil {
return echo.NewHTTPError(500, err.Error())
}
}
}

return nil
})

log.Println("listening on ", cfg.Addr)
if err := server.ListenAndServe(); err != nil {
log.Fatal(err)
}
}

// WxAuth 开启回调模式验证
func wxAuth(context echo.Context) error {
if cfg.Weixin.Enable {
echostr := context.FormValue("echostr")
if echostr == "" {
return errors.New("无法获取请求参数, echostr 为空")
}
var buf []byte
var err error
if buf, err = wx.Auth(echostr); err != nil {
return err
}

return context.JSONBlob(200, buf)
}

return context.String(200, "微信没有启用")
if cfg.Weixin.Enable {
echostr := context.FormValue("echostr")
if echostr == "" {
return errors.New("无法获取请求参数, echostr 为空")
}
var buf []byte
var err error
if buf, err = wx.Auth(echostr); err != nil {
return err
}

return context.JSONBlob(200, buf)
}

return context.String(200, "微信没有启用")
}
8 changes: 8 additions & 0 deletions message-template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
## 告警

- 告警等级: {{.Level}}
- 告警类型: {{.Type}}
- 告警指标: {{.Condition}}
- 告警主机: {{.Host}}
- 告警时间: {{.Time}}
- 告警说明: {{.Desc}},已持续{{.Count}}分钟
44 changes: 24 additions & 20 deletions sender/dingtalk.go
Original file line number Diff line number Diff line change
@@ -1,34 +1,38 @@
package sender

import (
"errors"
"log"
"net/http"

"github.com/labstack/echo"
"github.com/sdvdxl/dinghook"
"errors"
"github.com/labstack/echo"
"github.com/sdvdxl/dinghook"
"log"
"net/http"
)

type DingTalk struct {
}

func (d *DingTalk) Send(token string, content string) error {
if token == "" {
return errors.New("need dingding token")
}
func (d *DingTalk) Send(token string, content, msgType string) error {
if token == "" {
return errors.New("need dingding token")
}

// 发送钉钉
ding := dinghook.NewDing(token)
result := ding.SendMessage(dinghook.Message{Content: content})
log.Println(result)
if !result.Success {
log.Println("token:", token)
return echo.NewHTTPError(http.StatusBadRequest, result.ErrMsg)
}
// 发送钉钉
ding := dinghook.NewDing(token)
var result dinghook.Result
if msgType == dinghook.MsgTypeMarkdown {
result = ding.SendMarkdown(dinghook.Markdown{Title: "告警", Content: content})
} else {
result = ding.SendMessage(dinghook.Message{Content: content})
}
log.Println(result)
if !result.Success {
log.Println("token:", token, " send result:", result)
return echo.NewHTTPError(http.StatusBadRequest, result.ErrMsg)
}

return nil
return nil
}

func NewDingTalk() *DingTalk {
return &DingTalk{}
return &DingTalk{}
}
Loading

0 comments on commit b023970

Please sign in to comment.