更新钉钉服务

master
李光春 2 years ago
parent ad86421cb8
commit dbcb0ee85b

@ -0,0 +1,50 @@
package dingtalk
import (
"encoding/json"
"errors"
"fmt"
"github.com/go-redis/redis/v8"
"go.mongodb.org/mongo-driver/mongo"
"go.uber.org/zap"
"gopkg.in/dtapps/go-library.v3/utils/gohttp"
"gorm.io/gorm"
"net/http"
)
type App struct {
Secret string
AccessToken string
ZapLog *zap.Logger // 日志服务
Db *gorm.DB // 关系数据库服务
RDb *redis.Client // 缓存数据库服务
MDb *mongo.Client // 非关系数据库服务
}
func (app *App) request(url string, params map[string]interface{}, method string) ([]byte, error) {
switch method {
case http.MethodGet:
// 请求
get, err := gohttp.Get(url, params)
// 日志
if app.ZapLog != nil {
app.ZapLog.Sugar().Info(fmt.Sprintf("%s %s", url, get.Body))
}
return get.Body, err
case http.MethodPost:
// 请求参数
paramsMarshal, err := json.Marshal(params)
if err != nil {
return nil, err
}
// 请求
postJson, err := gohttp.PostJson(url, paramsMarshal)
// 日志
if app.ZapLog != nil {
app.ZapLog.Sugar().Info(fmt.Sprintf("%s %s", url, postJson.Body))
}
return postJson.Body, err
default:
return nil, errors.New("请求类型不支持")
}
}

@ -1,3 +0,0 @@
package config
const Api = "https://oapi.dingtalk.com/robot/send"

@ -1,57 +0,0 @@
package dingtalk
import (
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
"encoding/json"
"fmt"
"gopkg.in/dtapps/go-library.v3/service/dingtalk/config"
"gopkg.in/dtapps/go-library.v3/service/dingtalk/message"
"gopkg.in/dtapps/go-library.v3/utils/gojson"
"io/ioutil"
"net/http"
"strings"
"time"
)
type DingBot struct {
Secret string
AccessToken string
}
type Response struct {
Errcode int64 `json:"errcode"`
Errmsg string `json:"errmsg"`
}
func (bot *DingBot) Send(msg message.Message) (Response, error) {
timestamp := time.Now().UnixNano() / 1e6
var response Response
signStr := sign(timestamp, bot.Secret)
dingUrl := fmt.Sprintf("%s?access_token=%s&timestamp=%d&sign=%s", config.Api, bot.AccessToken, timestamp, signStr)
toString, err := gojson.MarshalToString(msg)
if err != nil {
return response, err
}
resp, e := http.Post(dingUrl, "application/json", strings.NewReader(toString))
if e != nil {
return response, e
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
e = json.Unmarshal(body, &response)
if e != nil {
return response, e
}
return response, nil
}
func sign(t int64, secret string) string {
secStr := fmt.Sprintf("%d\n%s", t, secret)
hmac256 := hmac.New(sha256.New, []byte(secret))
hmac256.Write([]byte(secStr))
result := hmac256.Sum(nil)
return base64.StdEncoding.EncodeToString(result)
}

@ -1,26 +0,0 @@
package dingtalk
import (
"fmt"
"gopkg.in/dtapps/go-library.v3/service/dingtalk/message"
"testing"
)
func TestName(t *testing.T) {
bot := DingBot{
Secret: "gSEC05342ba24a7eb2e1dbeae61b3df997eb1a97b7cda414566876e983f1db0fec0b",
AccessToken: "caad81de7f6b218bb7d085264d4885714c805cc80a460690a0d19db91a05dd174",
}
msg := message.Message{
MsgType: message.TextStr,
Text: message.Text_{
Content: "测试",
},
}
send, err := bot.Send(msg)
fmt.Printf("send%v\n", send)
if err != nil {
t.Errorf("err%v\n", err)
return
}
}

@ -1,59 +0,0 @@
package message
type Message struct {
MsgType MsgType_ `json:"msgtype"`
Text Text_ `json:"text"`
Link Link_ `json:"link"`
Markdown Markdown_ `json:"markdown"`
ActionCard ActionCard_ `json:"actionCard"`
FeedCard FeedCard_ `json:"feedCard"`
}
// Text_ text类型
type Text_ struct {
Content string `json:"content"`
At At_ `json:"at"`
}
// At_ At类型
type At_ struct {
AtMobiles []string `json:"atMobiles"`
IsAtAll bool `json:"isAtAll"`
}
// Link_ link类型
type Link_ struct {
Text string `json:"text"`
Title string `json:"title"`
PicUrl string `json:"picUrl"`
MessageUrl string `json:"messageUrl"`
}
// Markdown_ markdown类型
type Markdown_ struct {
Title string `json:"title"`
Text string `json:"text"`
At At_ `json:"at"`
}
// ActionCard_ 整体跳转actionCard
type ActionCard_ struct {
Title string `json:"title"`
Text string `json:"text"`
BtnOrientation string `json:"btnOrientation"`
SingleTitle string `json:"singleTitle"`
SingleURL string `json:"singleUrl"`
HideAvatar string `json:"hideAvatar"`
BtnS []Btn_ `json:"btns"`
}
// Btn_ Btn类型
type Btn_ struct {
Title string `json:"title"`
ActionURL string `json:"actionURL"`
}
// FeedCard_ FeedCard类型
type FeedCard_ struct {
Links []Link_ `json:"links"`
}

@ -1,11 +0,0 @@
package message
type MsgType_ string
const (
TextStr MsgType_ = "text"
LinkStr MsgType_ = "link"
MarkdownStr MsgType_ = "markdown"
ActionCardStr MsgType_ = "actionCard"
FeedCardStr MsgType_ = "feedCard"
)

@ -0,0 +1,27 @@
package dingtalk
// Params 请求参数
type Params map[string]interface{}
func NewParams() Params {
p := make(Params)
return p
}
func (app *App) NewParamsWith(params ...Params) Params {
p := make(Params)
for _, v := range params {
p.SetParams(v)
}
return p
}
func (p Params) Set(key string, value interface{}) {
p[key] = value
}
func (p Params) SetParams(params Params) {
for key, value := range params {
p[key] = value
}
}

@ -0,0 +1,24 @@
package dingtalk
import (
"fmt"
"net/http"
"time"
)
type RobotSendResult struct {
Errcode int64 `json:"errcode"`
Errmsg string `json:"errmsg"`
}
// RobotSend 自定义机器人
// https://open.dingtalk.com/document/group/custom-robot-access
func (app *App) RobotSend(notMustParams ...Params) (body []byte, err error) {
// 参数
params := app.NewParamsWith(notMustParams...)
// 时间
timestamp := time.Now().UnixNano() / 1e6
// 请求
body, err = app.request(fmt.Sprintf("https://oapi.dingtalk.com/robot/send?access_token=%s&timestamp=%d&sign=%s", app.AccessToken, timestamp, app.sign(timestamp)), params, http.MethodPost)
return body, err
}

@ -0,0 +1,16 @@
package dingtalk
import (
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
"fmt"
)
func (app *App) sign(t int64) string {
secStr := fmt.Sprintf("%d\n%s", t, app.Secret)
hmac256 := hmac.New(sha256.New, []byte(app.Secret))
hmac256.Write([]byte(secStr))
result := hmac256.Sum(nil)
return base64.StdEncoding.EncodeToString(result)
}
Loading…
Cancel
Save