mirror of
https://github.com/lddsb/drone-dingtalk-message.git
synced 2026-06-04 18:33:48 +08:00
242 lines
5.4 KiB
Go
242 lines
5.4 KiB
Go
package main
|
||
|
||
import (
|
||
"bytes"
|
||
"encoding/json"
|
||
"errors"
|
||
"fmt"
|
||
"io/ioutil"
|
||
"net/http"
|
||
"regexp"
|
||
)
|
||
|
||
// link message struct
|
||
type LinkMsg struct {
|
||
Title string `json:"title"`
|
||
MessageURL string `json:"messageURL"`
|
||
PicURL string `json:"picURL"`
|
||
}
|
||
|
||
// action card message struct
|
||
type ActionCard struct {
|
||
Text string `json:"text"`
|
||
Title string `json:"title"`
|
||
SingleTitle string `json:"singleTitle"`
|
||
SingleURL string `json:"singleURL"`
|
||
BtnOrientation string `json:"btnOrientation"`
|
||
HideAvatar string `json:"hideAvatar"` // robot message avatar
|
||
Buttons []struct {
|
||
Title string `json:"title"`
|
||
ActionURL string `json:"actionURL"`
|
||
} `json:"btns"`
|
||
}
|
||
|
||
// payload
|
||
type PayLoad struct {
|
||
MsgType string `json:"msgtype"`
|
||
Text struct {
|
||
Content string `json:"content"`
|
||
} `json:"text"`
|
||
Link struct {
|
||
Title string `json:"title"`
|
||
Text string `json:"text"`
|
||
PicUrl string `json:"picUrl"`
|
||
MessageUrl string `json:"messageUrl"`
|
||
} `json:"link"`
|
||
Markdown struct {
|
||
Title string `json:"title"`
|
||
Text string `json:"text"`
|
||
} `json:"markdown"`
|
||
ActionCard ActionCard `json:"actionCard"`
|
||
FeedCard struct {
|
||
Links []LinkMsg `json:"links"`
|
||
} `json:"feedCard"`
|
||
At struct {
|
||
AtMobiles []string `json:"atMobiles"`
|
||
IsAtAll bool `json:"isAtAll"`
|
||
} `json:"at"`
|
||
}
|
||
|
||
// web hook base config
|
||
type WebHook struct {
|
||
AccessToken string `json:"accessToken"`
|
||
}
|
||
|
||
func NewWebHook(accessToken string) *WebHook {
|
||
return &WebHook{AccessToken: accessToken}
|
||
}
|
||
|
||
type Response struct {
|
||
ErrorCode int `json:"errcode"`
|
||
ErrorMessage string `json:"errmsg"`
|
||
}
|
||
|
||
var baseApi = "https://oapi.dingtalk.com/robot/send?access_token="
|
||
var reg = `^1([38][0-9]|14[57]|5[^4])\d{8}$`
|
||
var regx = regexp.MustCompile(reg)
|
||
|
||
// real send request to api
|
||
func (w *WebHook) sendPayload(payload *PayLoad) error {
|
||
// get config
|
||
bs, err := json.Marshal(payload)
|
||
if nil != err {
|
||
return err
|
||
}
|
||
// request api
|
||
resp, err := http.Post(baseApi+w.AccessToken, "application/json", bytes.NewReader(bs))
|
||
if nil != err {
|
||
return err
|
||
}
|
||
// read response body
|
||
body, err := ioutil.ReadAll(resp.Body)
|
||
if nil != err {
|
||
return err
|
||
}
|
||
// api unusual
|
||
if 200 != resp.StatusCode {
|
||
return fmt.Errorf("%d: %s", resp.StatusCode, string(body))
|
||
}
|
||
|
||
var result Response
|
||
// json decode
|
||
err = json.Unmarshal(body, &result)
|
||
if nil != err {
|
||
return err
|
||
}
|
||
if 0 != result.ErrorCode {
|
||
return fmt.Errorf("%d: %s", result.ErrorCode, result.ErrorMessage)
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
// text message
|
||
func (w *WebHook) SendTextMsg(content string, isAtAll bool, mobiles ...string) error {
|
||
// send request
|
||
return w.sendPayload(&PayLoad{
|
||
MsgType: "text",
|
||
Text: struct {
|
||
Content string `json:"content"`
|
||
}{
|
||
Content: content,
|
||
},
|
||
At: struct {
|
||
AtMobiles []string `json:"atMobiles"`
|
||
IsAtAll bool `json:"isAtAll"`
|
||
}{
|
||
AtMobiles: mobiles,
|
||
IsAtAll: isAtAll,
|
||
},
|
||
})
|
||
}
|
||
|
||
// with link message
|
||
func (w *WebHook) SendLinkMsg(title, content, picURL, msgURL string) error {
|
||
return w.sendPayload(&PayLoad{
|
||
MsgType: "link",
|
||
Link: struct {
|
||
Title string `json:"title"`
|
||
Text string `json:"text"`
|
||
PicUrl string `json:"picUrl"`
|
||
MessageUrl string `json:"messageUrl"`
|
||
}{
|
||
Title: title,
|
||
Text: content,
|
||
PicUrl: picURL,
|
||
MessageUrl: msgURL,
|
||
},
|
||
})
|
||
}
|
||
|
||
// send markdown msg
|
||
func (w *WebHook) SendMarkdownMsg(title, content string, isAtAll bool, mobiles ...string) error {
|
||
firstLine := false
|
||
for _, mobile := range mobiles {
|
||
if regx.MatchString(mobile) {
|
||
if false == firstLine {
|
||
content += "#####"
|
||
}
|
||
content += " @" + mobile
|
||
firstLine = true
|
||
}
|
||
}
|
||
// send request
|
||
return w.sendPayload(&PayLoad{
|
||
MsgType: "markdown",
|
||
Markdown: struct {
|
||
Title string `json:"title"`
|
||
Text string `json:"text"`
|
||
}{
|
||
Title: title,
|
||
Text: content,
|
||
},
|
||
At: struct {
|
||
AtMobiles []string `json:"atMobiles"`
|
||
IsAtAll bool `json:"isAtAll"`
|
||
}{
|
||
AtMobiles: mobiles,
|
||
IsAtAll: isAtAll,
|
||
},
|
||
})
|
||
}
|
||
|
||
// send single action card
|
||
func (w *WebHook) SendActionCardMsg(title, content string, linkTitles, linkUrls []string, hideAvatar, btnOrientation bool) error {
|
||
// validation is empty
|
||
if 0 == len(linkTitles) || 0 == len(linkUrls) {
|
||
return errors.New("links or titles is empty!")
|
||
}
|
||
// validation is equal
|
||
if len(linkUrls) != len(linkTitles) {
|
||
return errors.New("links length and titles length is not equal!")
|
||
}
|
||
// hide robot avatar
|
||
var strHideAvatar = "0"
|
||
if hideAvatar {
|
||
strHideAvatar = "1"
|
||
}
|
||
// button sort
|
||
var strBtnOrientation = "0"
|
||
if btnOrientation {
|
||
strBtnOrientation = "1"
|
||
}
|
||
// button struct
|
||
var buttons []struct {
|
||
Title string `json:"title"`
|
||
ActionURL string `json:"actionURL"`
|
||
}
|
||
// inject to button
|
||
for i := 0; i < len(linkTitles); i++ {
|
||
buttons = append(buttons, struct {
|
||
Title string `json:"title"`
|
||
ActionURL string `json:"actionURL"`
|
||
}{
|
||
Title: linkTitles[i],
|
||
ActionURL: linkUrls[i],
|
||
})
|
||
}
|
||
// send request
|
||
return w.sendPayload(&PayLoad{
|
||
MsgType: "actionCard",
|
||
ActionCard: ActionCard{
|
||
Title: title,
|
||
Text: content,
|
||
HideAvatar: strHideAvatar,
|
||
BtnOrientation: strBtnOrientation,
|
||
Buttons: buttons,
|
||
},
|
||
})
|
||
}
|
||
|
||
// send link card message
|
||
func (w *WebHook) SendLinkCardMsg(messages []LinkMsg) error {
|
||
return w.sendPayload(&PayLoad{
|
||
MsgType: "feedCard",
|
||
FeedCard: struct {
|
||
Links []LinkMsg `json:"links"`
|
||
}{
|
||
Links: messages,
|
||
},
|
||
})
|
||
}
|