123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- 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: SendTextMessage
- //@description: 发送钉钉文字信息
- //@params content string发送的文字内容
- //@params atMobiles []string 艾特的手机号
- //@params isAtAll bool 是否艾特全体
- //@return: err error
- func (e *NotifyService) SendTextMessage(content string, atMobiles []string, isAtAll bool) (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)
- }
- //@author: [Espoir](https://github.com/nightsimon)
- //@function: SendLinkMessage
- //@description: 发送钉钉图文链接信息
- //@params content string 发送的文字内容
- //@params title string 发送的标题
- //@params picUrl string 艾特的手机号
- //@params messageUrl string 是否艾特全体
- //@return: err error
- func (e *NotifyService) SendLinkMessage(content, title, picUrl, messageUrl string) (err error) {
- msg := map[string]interface{}{
- "msgtype": "link",
- "link": map[string]string{
- "text": content,
- "title": title,
- "picUrl": picUrl,
- "messageUrl": messageUrl,
- },
- }
- return SendMessage(msg)
- }
- //@author: [Espoir](https://github.com/nightsimon)
- //@function: SendMarkdownMessage
- //@description: 发送钉钉Markdown信息
- //@params content 发送的文字内容
- //@params title 发送的标题
- //@params atMobiles []string 艾特的手机号
- //@params isAtAll bool 是否艾特全体
- //@return: err error
- func (e *NotifyService) SendMarkdownMessage(content, title string, atMobiles []string, isAtAll bool) (err error) {
- msg := map[string]interface{}{
- "msgtype": "markdown",
- "markdown": map[string]string{
- "text": content,
- "title": title,
- },
- "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)
- }
- // 其余方法请参考 https://developers.dingtalk.com/document/robots/custom-robot-access?spm=ding_open_doc.document.0.0.7f8710afbfzduV#topic-2026027
|