Browse Source

Merge pull request #645 from nightsimon/feat/notify-dingding

Feat/notify dingding
main
奇淼(piexlmax 3 years ago
committed by GitHub
parent
commit
1ae17fb36a
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 25
      server/initialize/router.go
  2. 38
      server/plugin/notify/README.MD
  3. 21
      server/plugin/notify/api/api.go
  4. 7
      server/plugin/notify/api/enter.go
  5. 7
      server/plugin/notify/config/dingding.go
  6. 9
      server/plugin/notify/global/global.go
  7. 24
      server/plugin/notify/main.go
  8. 7
      server/plugin/notify/router/enter.go
  9. 18
      server/plugin/notify/router/router.go
  10. 7
      server/plugin/notify/service/enter.go
  11. 106
      server/plugin/notify/service/notify.go
  12. 1
      server/plugin/notify/utils/utils.go

25
server/initialize/router.go

@ -1,6 +1,12 @@
package initialize
import (
//email "github.com/flipped-aurora/gva-plug-email" // 在线仓库模式
"github.com/flipped-aurora/gin-vue-admin/server/plugin/email" // 本地插件仓库地址模式
"github.com/flipped-aurora/gin-vue-admin/server/plugin/example_plugin"
"github.com/flipped-aurora/gin-vue-admin/server/plugin/notify"
"net/http"
_ "github.com/flipped-aurora/gin-vue-admin/server/docs"
@ -58,8 +64,27 @@ func Routers() *gin.Engine {
// Code generated by github.com/flipped-aurora/gin-vue-admin/server End; DO NOT EDIT.
}
// 添加开放权限的插件 示例
PluginInit(PublicGroup, example_plugin.ExamplePlugin)
// 钉钉通知,暂时开放权限
PluginInit(PublicGroup, notify.CreateDDPlug())
// 添加跟角色挂钩权限的插件 示例 本地示例模式于在线仓库模式注意上方的import 可以自行切换 效果相同
PluginInit(PrivateGroup, email.CreateEmailPlug(
global.GVA_CONFIG.Email.To,
global.GVA_CONFIG.Email.From,
global.GVA_CONFIG.Email.Host,
global.GVA_CONFIG.Email.Secret,
global.GVA_CONFIG.Email.Nickname,
global.GVA_CONFIG.Email.Port,
global.GVA_CONFIG.Email.IsSSL,
))
InstallPlugin(PublicGroup, PrivateGroup) // 安装插件
global.GVA_LOG.Info("router register success")
return Router
}

38
server/plugin/notify/README.MD

@ -0,0 +1,38 @@
## GVA 钉钉群通知插件
本插件用于向钉钉群推送消息
### 1. 使用场景
- 当服务运行异常时,可以向钉钉推送异常信息,便于及时发现解决问题
- 推送一些关键业务的运行日志等
### 2. 配置说明
钉钉 token 等相关信息的获取,请参考 [钉钉官网](https://developers.dingtalk.com/document/robots/custom-robot-access?spm=ding_open_doc.document.0.0.7f8710afbfzduV#topic-2026027)
在`plugin/notify/global/global.go` 文件中配置钉钉通知的URL ,Token 等
```go
var GlobalConfig_ = &config.DingDing{
Url: "https://oapi.dingtalk.com/robot/send",
Token: "xxx",
Secret: "xxx",
}
```
### 3. 使用说明
在代码中调用 `SendTextMessage` 方法即可
```go
func NotifyController(c *gin.Context) {
if err := service.ServiceGroupApp.SendTextMessage("test"); err != nil {
global.GVA_LOG.Error("发送失败!", zap.Any("err", err))
response.FailWithMessage("发送失败", c)
} else {
response.OkWithData("发送成功", c)
}
}
```
### 方法API

21
server/plugin/notify/api/api.go

@ -0,0 +1,21 @@
package api
import (
"github.com/flipped-aurora/gin-vue-admin/server/global"
"github.com/flipped-aurora/gin-vue-admin/server/model/common/response"
"github.com/flipped-aurora/gin-vue-admin/server/plugin/notify/service"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
type Api struct {
}
func (s *Api) NotifyController(c *gin.Context) {
if err := service.ServiceGroupApp.SendTextMessage("test"); err != nil {
global.GVA_LOG.Error("发送失败!", zap.Any("err", err))
response.FailWithMessage("发送失败", c)
} else {
response.OkWithData("发送成功", c)
}
}

7
server/plugin/notify/api/enter.go

@ -0,0 +1,7 @@
package api
type ApiGroup struct {
Api
}
var ApiGroupApp = new(ApiGroup)

7
server/plugin/notify/config/dingding.go

@ -0,0 +1,7 @@
package config
type DingDing struct {
Url string `mapstructure:"url" json:"url" yaml:"url"` // Url
Token string `mapstructure:"token" json:"token" yaml:"token"` // Token
Secret string `mapstructure:"secret" json:"secret" yaml:"secret"` // 密钥
}

9
server/plugin/notify/global/global.go

@ -0,0 +1,9 @@
package global
import "github.com/flipped-aurora/gin-vue-admin/server/plugin/notify/config"
var GlobalConfig_ = &config.DingDing{
Url: "https://oapi.dingtalk.com/robot/send",
Token: "77d18293e221b3b7bdae7330d19a213c3cbb20fa07de5f4c273c0363ae475c34",
Secret: "SEC38425b7bd57c6bca9ce20611c41b437994ed65e0ddbd42e840ffa7a8c7da2106",
}

24
server/plugin/notify/main.go

@ -0,0 +1,24 @@
package notify
import (
"github.com/flipped-aurora/gin-vue-admin/server/plugin/notify/router"
"github.com/gin-gonic/gin"
)
type ddPlugin struct {
Secret string
Token string
Url string
}
func CreateDDPlug() *ddPlugin {
return &ddPlugin{}
}
func (*ddPlugin) Register(group *gin.RouterGroup) {
router.RouterGroupApp.InitRouter(group)
}
func (*ddPlugin) RouterPath() string {
return "notify"
}

7
server/plugin/notify/router/enter.go

@ -0,0 +1,7 @@
package router
type RouterGroup struct {
NotifyRouter
}
var RouterGroupApp = new(RouterGroup)

18
server/plugin/notify/router/router.go

@ -0,0 +1,18 @@
package router
import (
"github.com/flipped-aurora/gin-vue-admin/server/middleware"
"github.com/flipped-aurora/gin-vue-admin/server/plugin/notify/api"
"github.com/gin-gonic/gin"
)
type NotifyRouter struct {
}
func (s *NotifyRouter) InitRouter(Router *gin.RouterGroup) {
router := Router.Use(middleware.OperationRecord())
var Controller = api.ApiGroupApp.Api.NotifyController
{
router.POST("dingding", Controller)
}
}

7
server/plugin/notify/service/enter.go

@ -0,0 +1,7 @@
package service
type ServiceGroup struct {
NotifyService
}
var ServiceGroupApp = new(ServiceGroup)

106
server/plugin/notify/service/notify.go

@ -0,0 +1,106 @@
package service
import (
"bytes"
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
"encoding/json"
"fmt"
"github.com/flipped-aurora/gin-vue-admin/server/plugin/notify/global"
"io/ioutil"
"net/http"
"net/url"
"time"
)
type NotifyService struct {
}
//@author: [Espoir](https://github.com/nightsimon)
//@function: NotifyController
//@description: 钉钉通知测试
//@return: err error
func (e *NotifyService) SendTextMessage(content string) (err error) {
msg := map[string]interface{}{
"msgtype": "text",
"text": map[string]string{
"content": content,
},
//"at": map[string]interface{}{
// "atMobiles": atMobiles,
// "isAtAll": isAtAll,
//},
}
return SendMessage(msg)
}
func SendMessage(msg interface{}) error {
body := bytes.NewBuffer(nil)
err := json.NewEncoder(body).Encode(msg)
if err != nil {
return fmt.Errorf("msg json failed, msg: %v, err: %v", msg, err.Error())
}
value := url.Values{}
value.Set("access_token", global.GlobalConfig_.Token)
if global.GlobalConfig_.Secret != "" {
t := time.Now().UnixNano() / 1e6
value.Set("timestamp", fmt.Sprintf("%d", t))
value.Set("sign", sign(t, global.GlobalConfig_.Secret))
}
request, err := http.NewRequest(http.MethodPost, global.GlobalConfig_.Url, body)
if err != nil {
return fmt.Errorf("error request: %v", err.Error())
}
request.URL.RawQuery = value.Encode()
request.Header.Add("Content-Type", "application/json")
res, err := (&http.Client{}).Do(request)
if err != nil {
return fmt.Errorf("send dingTalk message failed, error: %v", err.Error())
}
defer func() { _ = res.Body.Close() }()
result, err := ioutil.ReadAll(res.Body)
if res.StatusCode != 200 {
return fmt.Errorf("send dingTalk message failed, %s", httpError(request, res, result, "http code is not 200"))
}
if err != nil {
return fmt.Errorf("send dingTalk message failed, %s", httpError(request, res, result, err.Error()))
}
type response struct {
ErrCode int `json:"errcode"`
}
var ret response
if err := json.Unmarshal(result, &ret); err != nil {
return fmt.Errorf("send dingTalk message failed, %s", httpError(request, res, result, err.Error()))
}
if ret.ErrCode != 0 {
return fmt.Errorf("send dingTalk message failed, %s", httpError(request, res, result, "errcode is not 0"))
}
return nil
}
func httpError(request *http.Request, response *http.Response, body []byte, error string) string {
return fmt.Sprintf(
"http request failure, error: %s, status code: %d, %s %s, body:\n%s",
error,
response.StatusCode,
request.Method,
request.URL.String(),
string(body),
)
}
func sign(t int64, secret string) string {
strToHash := fmt.Sprintf("%d\n%s", t, secret)
hmac256 := hmac.New(sha256.New, []byte(secret))
hmac256.Write([]byte(strToHash))
data := hmac256.Sum(nil)
return base64.StdEncoding.EncodeToString(data)
}

1
server/plugin/notify/utils/utils.go

@ -0,0 +1 @@
package utils
Loading…
Cancel
Save