Skip to content

Commit d514057

Browse files
committed
初始化
1 parent e8d1716 commit d514057

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

89 files changed

+17489
-0
lines changed

biz/bot/dingtalk/action_card.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package dingtalk
2+
3+
type ActionCardMessage struct {
4+
MsgType MsgType `json:"msgtype"`
5+
ActionCard *ActionCard `json:"actionCard"`
6+
}
7+
8+
type ActionCard struct {
9+
Title string `json:"title"`
10+
Text string `json:"text"`
11+
HideAvatar string `json:"hideAvatar"`
12+
BtnOrientation string `json:"btnOrientation"`
13+
SingleTitle string `json:"singleTitle"`
14+
SingleURL string `json:"singleURL"`
15+
Btns []*Btn `json:"btns"`
16+
}
17+
18+
/*** ActionCard ***/
19+
func NewActionCard() *ActionCardMessage {
20+
return &ActionCardMessage{ACTIONCARD, &ActionCard{}}
21+
}
22+
23+
func (a *ActionCardMessage) SetContent(title, text string) *ActionCardMessage {
24+
a.ActionCard.Title = title
25+
a.ActionCard.Text = text
26+
return a
27+
}
28+
29+
func (a *ActionCardMessage) AddBtn(singleTitle, singleURL string) *ActionCardMessage {
30+
a.ActionCard.SingleTitle = singleTitle
31+
a.ActionCard.SingleURL = singleURL
32+
return a
33+
}
34+
35+
func (a *ActionCardMessage) AddBtns(btns [][]string) *ActionCardMessage {
36+
for _, item := range btns {
37+
a.ActionCard.Btns = append(a.ActionCard.Btns, &Btn{item[0], item[1]})
38+
}
39+
return a
40+
}
41+
42+
func (a *ActionCardMessage) HideAvatar() *ActionCardMessage {
43+
a.ActionCard.HideAvatar = "1"
44+
return a
45+
}
46+
47+
func (a *ActionCardMessage) BtnOrientation() *ActionCardMessage {
48+
a.ActionCard.BtnOrientation = "0"
49+
return a
50+
}

biz/bot/dingtalk/bot.go

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
package dingtalk
2+
3+
import (
4+
"bytes"
5+
"crypto/hmac"
6+
"crypto/sha256"
7+
"encoding/base64"
8+
"encoding/json"
9+
"errors"
10+
"fmt"
11+
"github.com/yi-nology/common/utils/xjson"
12+
"io"
13+
"io/ioutil"
14+
"net/http"
15+
"net/url"
16+
"strconv"
17+
"time"
18+
)
19+
20+
type Robot struct {
21+
Key string
22+
RequestUrl string
23+
Client *http.Client
24+
}
25+
26+
type Resp struct {
27+
ErrCode int `json:"errcode"`
28+
ErrMsg string `json:"errmsg"`
29+
}
30+
31+
const (
32+
WEBHOOK_URL = "https://oapi.dingtalk.com/robot/send?access_token=%s"
33+
)
34+
35+
// New 获取一个 Robot instance
36+
func New(botKey string) *Robot {
37+
return &Robot{
38+
Key: botKey,
39+
RequestUrl: fmt.Sprintf(WEBHOOK_URL, botKey),
40+
Client: &http.Client{Timeout: 5 * time.Second},
41+
}
42+
}
43+
44+
// AddSign 更新SDK 支持Sign模式
45+
func (r *Robot) AddSign(secret string) *Robot {
46+
if len(secret) == 0 {
47+
return r
48+
}
49+
microTimestamp := time.Now().UnixNano() / 1e6
50+
h := hmac.New(sha256.New, []byte(secret))
51+
io.WriteString(h, fmt.Sprintf("%d\n%s", microTimestamp, secret))
52+
if r.RequestUrl != "" {
53+
r.RequestUrl = r.RequestUrl + "&timestamp=" + strconv.Itoa(int(microTimestamp)) + "&sign=" + url.QueryEscape(base64.StdEncoding.EncodeToString(h.Sum(nil)))
54+
}
55+
return r
56+
}
57+
58+
// Send 发送notification
59+
func (r *Robot) Send(message interface{}) (bool, error) {
60+
b, err := json.Marshal(message)
61+
if err != nil {
62+
return false, err
63+
}
64+
// log.Println(string(b))
65+
return r.SendRaw(b)
66+
}
67+
68+
func (r *Robot) SendRaw(msgBytes []byte) (bool, error) {
69+
resp, err := r.Client.Post(r.RequestUrl, "application/json", bytes.NewReader(msgBytes))
70+
if err != nil {
71+
return false, err
72+
}
73+
74+
defer resp.Body.Close()
75+
body, err := ioutil.ReadAll(resp.Body)
76+
if err != nil {
77+
return false, err
78+
}
79+
80+
ret := &Resp{}
81+
82+
if err := json.Unmarshal(body, &ret); err != nil {
83+
return false, err
84+
}
85+
86+
if ret.ErrCode == 0 {
87+
return true, nil
88+
} else {
89+
return false, errors.New(ret.ErrMsg)
90+
}
91+
}
92+
93+
func (r *Robot) CheckMessage(msg string) bool {
94+
95+
if len(msg) == 0 {
96+
return false
97+
}
98+
text := TextMessage{}
99+
markdown := MarkDownMessage{}
100+
link := LinkMessage{}
101+
feedcard := FeedCardMessage{}
102+
actionCard := ActionCardMessage{}
103+
if xjson.UnmarshalFromString(msg, &text) == nil {
104+
return true
105+
}
106+
if xjson.UnmarshalFromString(msg, &markdown) == nil {
107+
return true
108+
}
109+
if xjson.UnmarshalFromString(msg, &link) == nil {
110+
return true
111+
}
112+
if xjson.UnmarshalFromString(msg, &feedcard) == nil {
113+
return true
114+
}
115+
if xjson.UnmarshalFromString(msg, &actionCard) == nil {
116+
return true
117+
}
118+
return false
119+
}

biz/bot/dingtalk/dingtalk.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package dingtalk
2+
3+
type MsgType string
4+
5+
const TEXT MsgType = "text"
6+
const LINK MsgType = "link"
7+
const MARKDOWN MsgType = "markdown"
8+
const ACTIONCARD MsgType = "actionCard"
9+
const FEEDCARD MsgType = "feedCard"
10+
11+
type At struct {
12+
AtMobiles []string `json:"atMobiles"`
13+
IsAtAll bool `json:"isAtAll"`
14+
}
15+
16+
type Btn struct {
17+
Title string `json:"title"`
18+
ActionURL string `json:"actionURL"`
19+
}

biz/bot/dingtalk/feed_card.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package dingtalk
2+
3+
type FeedCardMessage struct {
4+
MsgType MsgType `json:"msgtype"`
5+
FeedCard *FeedCard `json:"feedCard"`
6+
}
7+
8+
type FeedCard struct {
9+
Links []*FeedCardLink `json:"links"`
10+
}
11+
12+
type FeedCardLink struct {
13+
Title string `json:"title"`
14+
MessageURL string `json:"messageURL"`
15+
PicURL string `json:"picURL"`
16+
}
17+
18+
/*** FeedCard ***/
19+
func NewFeedCard() *FeedCardMessage {
20+
return &FeedCardMessage{FEEDCARD, &FeedCard{}}
21+
}
22+
23+
func (f *FeedCardMessage) AddCard(title, messageURL, picURL string) *FeedCardMessage {
24+
f.FeedCard.Links = append(f.FeedCard.Links, &FeedCardLink{title, messageURL, picURL})
25+
return f
26+
}
27+
28+
func (f *FeedCardMessage) AddCards(cards [][]string) *FeedCardMessage {
29+
for _, item := range cards {
30+
f.FeedCard.Links = append(f.FeedCard.Links, &FeedCardLink{item[0], item[1], item[2]})
31+
}
32+
return f
33+
}

biz/bot/dingtalk/link.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package dingtalk
2+
3+
type LinkMessage struct {
4+
MsgType MsgType `json:"msgtype"`
5+
Link *Link `json:"link"`
6+
}
7+
8+
type Link struct {
9+
Title string `json:"title"`
10+
Text string `json:"text"`
11+
MessageUrl string `json:"messageUrl"`
12+
PicUrl string `json:"picUrl"`
13+
}
14+
15+
/*** Link ***/
16+
func NewLink() *LinkMessage {
17+
return &LinkMessage{LINK, &Link{}}
18+
}
19+
20+
func (l *LinkMessage) SetContent(title, text, messageUrl, picUrl string) *LinkMessage {
21+
l.Link.Title = title
22+
l.Link.Text = text
23+
l.Link.MessageUrl = messageUrl
24+
l.Link.PicUrl = picUrl
25+
return l
26+
}

biz/bot/dingtalk/markdown.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package dingtalk
2+
3+
type MarkDownMessage struct {
4+
MsgType MsgType `json:"msgtype"`
5+
At *At `json:"at"`
6+
MarkDown *MarkDown `json:"markdown"`
7+
}
8+
9+
type MarkDown struct {
10+
Title string `json:"title"`
11+
Text string `json:"text"`
12+
}
13+
14+
/*** markdown ***/
15+
func NewMarkDown() *MarkDownMessage {
16+
return &MarkDownMessage{MARKDOWN, &At{}, &MarkDown{}}
17+
}
18+
19+
func (m *MarkDownMessage) SetContent(title, text string) *MarkDownMessage {
20+
m.MarkDown.Title = title
21+
m.MarkDown.Text = text
22+
return m
23+
}
24+
25+
func (m *MarkDownMessage) AtMobiles(mobiles []string) *MarkDownMessage {
26+
m.At.AtMobiles = mobiles
27+
return m
28+
}
29+
30+
func (m *MarkDownMessage) AtAll() *MarkDownMessage {
31+
m.At.IsAtAll = true
32+
return m
33+
}

biz/bot/dingtalk/text.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package dingtalk
2+
3+
type TextMessage struct {
4+
MsgType MsgType `json:"msgtype"`
5+
At *At `json:"at"`
6+
Text *Text `json:"text"`
7+
}
8+
9+
type Text struct {
10+
Content string `json:"content"`
11+
}
12+
13+
/*** Text ***/
14+
func NewText() *TextMessage {
15+
return &TextMessage{TEXT, &At{}, &Text{}}
16+
}
17+
18+
func (t *TextMessage) SetContent(content string) *TextMessage {
19+
t.Text.Content = content
20+
return t
21+
}
22+
23+
func (t *TextMessage) AtMobiles(mobiles []string) *TextMessage {
24+
t.At.AtMobiles = mobiles
25+
return t
26+
}
27+
28+
func (t *TextMessage) AtAll() *TextMessage {
29+
t.At.IsAtAll = true
30+
return t
31+
}

biz/bot/interface.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package bot
2+
3+
import (
4+
"github.com/yi-nology/common/biz/bot/dingtalk"
5+
"github.com/yi-nology/common/biz/bot/wxwork"
6+
)
7+
8+
type BotOne interface {
9+
Send(interface{}) (bool, error) // 发送
10+
SendRaw(msgBytes []byte) (bool, error) // 发送原始消息
11+
CheckMessage(msg string) bool // 检查消息是否合法
12+
}
13+
14+
type BotType string
15+
16+
const (
17+
WXWork BotType = "wx"
18+
Dingtalk BotType = "dd"
19+
)
20+
21+
func SwitchOne(botType BotType, botKey string, secret string) BotOne {
22+
switch botType {
23+
case WXWork:
24+
return wxwork.New(botKey)
25+
case Dingtalk:
26+
return dingtalk.New(botKey).AddSign(secret)
27+
default:
28+
return wxwork.New(botKey)
29+
}
30+
}

0 commit comments

Comments
 (0)