提交 04d61a2f 编写于 作者: Espoir__'s avatar Espoir__

feat(): notify dingding

上级 c82bb425
......@@ -34,6 +34,11 @@ email:
secret: 'xxx'
nickname: 'test'
dingding:
url: 'https://oapi.dingtalk.com/robot/send'
secret: 'SEC38425b7bd57c6bca9ce20611c41b437994ed65e0ddbd42e840ffa7a8c7da2106'
token: '77d18293e221b3b7bdae7330d19a213c3cbb20fa07de5f4c273c0363ae475c34'
# casbin configuration
casbin:
model-path: './resource/rbac_model.conf'
......@@ -55,15 +60,15 @@ captcha:
# mysql connect configuration
# 未初始化之前请勿手动修改数据库信息!!!如果一定要手动初始化请看(https://www.github.com/flipped-aurora/gin-vue-admin/server.com/docs/first)
mysql:
path: ''
config: ''
db-name: ''
username: ''
password: ''
max-idle-conns: 10
max-open-conns: 100
log-mode: false
log-zap: ""
path: 8.141.51.112:3306
config: charset=utf8mb4&parseTime=True&loc=Local
db-name: gva
username: root
password: 768f952daae626d9
max-idle-conns: 0
max-open-conns: 0
log-mode: ""
log-zap: false
# local configuration
local:
......
package config
type Server struct {
JWT JWT `mapstructure:"jwt" json:"jwt" yaml:"jwt"`
Zap Zap `mapstructure:"zap" json:"zap" yaml:"zap"`
Redis Redis `mapstructure:"redis" json:"redis" yaml:"redis"`
Email Email `mapstructure:"email" json:"email" yaml:"email"`
Casbin Casbin `mapstructure:"casbin" json:"casbin" yaml:"casbin"`
System System `mapstructure:"system" json:"system" yaml:"system"`
Captcha Captcha `mapstructure:"captcha" json:"captcha" yaml:"captcha"`
JWT JWT `mapstructure:"jwt" json:"jwt" yaml:"jwt"`
Zap Zap `mapstructure:"zap" json:"zap" yaml:"zap"`
Redis Redis `mapstructure:"redis" json:"redis" yaml:"redis"`
Email Email `mapstructure:"email" json:"email" yaml:"email"`
DingDing DingDing `mapstructure:"dingding" json:"dingding" yaml:"dingding"`
Casbin Casbin `mapstructure:"casbin" json:"casbin" yaml:"casbin"`
System System `mapstructure:"system" json:"system" yaml:"system"`
Captcha Captcha `mapstructure:"captcha" json:"captcha" yaml:"captcha"`
// auto
AutoCode Autocode `mapstructure:"autoCode" json:"autoCode" yaml:"autoCode"`
// gorm
......
package config
type DingDing struct {
Url string `mapstructure:"url" json:"url" yaml:"url"` // 发件人 你自己要发邮件的邮箱
Token string `mapstructure:"token" json:"token" yaml:"token"` // 服务器地址 例如 smtp.qq.com 请前往QQ或者你要发邮件的邮箱查看其smtp协议
Secret string `mapstructure:"secret" json:"secret" yaml:"secret"` // 密钥 用于登录的密钥 最好不要用邮箱密码 去邮箱smtp申请一个用于登录的密钥
}
......@@ -4,6 +4,7 @@ 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"
......@@ -65,6 +66,13 @@ func Routers() *gin.Engine {
// 添加开放权限的插件 示例
PluginInit(PublicGroup, example_plugin.ExamplePlugin)
// 钉钉通知,暂时开放权限
PluginInit(PublicGroup, notify.CreateDDPlug(
global.GVA_CONFIG.DingDing.Url,
global.GVA_CONFIG.DingDing.Secret,
global.GVA_CONFIG.DingDing.Token,
))
// 添加跟角色挂钩权限的插件 示例 本地示例模式于在线仓库模式注意上方的import 可以自行切换 效果相同
PluginInit(PrivateGroup, email.CreateEmailPlug(
global.GVA_CONFIG.Email.To,
......
## GVA 钉钉群通知插件
### 使用步骤
#### 1.
config.yaml 文件中配置钉钉通知的URL ,Token 等
#### 2. 配置说明
### 方法API
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.Send(); err != nil {
global.GVA_LOG.Error("发送失败!", zap.Any("err", err))
response.FailWithMessage("发送失败", c)
} else {
response.OkWithData("发送成功", c)
}
}
package api
type ApiGroup struct {
Api
}
var ApiGroupApp = new(ApiGroup)
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"` // 密钥
}
package global
import "github.com/flipped-aurora/gin-vue-admin/server/plugin/notify/config"
var GlobalConfig = new(config.DingDing)
package notify
import (
"github.com/flipped-aurora/gin-vue-admin/server/plugin/notify/global"
"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(Url string, Secret string, Token string) *ddPlugin {
global.GlobalConfig.Secret = Secret
global.GlobalConfig.Token = Token
global.GlobalConfig.Url = Url
return &ddPlugin{}
}
func (*ddPlugin) Register(group *gin.RouterGroup) {
router.RouterGroupApp.InitRouter(group)
}
func (*ddPlugin) RouterPath() string {
return "notify"
}
package router
type RouterGroup struct {
NotifyRouter
}
var RouterGroupApp = new(RouterGroup)
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) {
emailRouter := Router.Use(middleware.OperationRecord())
var Controller = api.ApiGroupApp.Api.NotifyController
{
emailRouter.POST("dingding", Controller)
}
}
package service
type ServiceGroup struct {
NotifyService
}
var ServiceGroupApp = new(ServiceGroup)
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 {
}
func SendTextMessage(content string) 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)
}
//@author: [Espoir](https://github.com/nightsimon)
//@function: NotifyController
//@description: 钉钉通知测试
//@return: err error
func (e *NotifyService) Send() (err error) {
err = SendTextMessage("test")
if err != nil {
return err
}
return err
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册