|
@ -0,0 +1,106 @@ |
|
|
|
|
|
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: NotifyController
|
|
|
|
|
|
//@description: 钉钉通知测试
|
|
|
|
|
|
//@return: err error
|
|
|
|
|
|
|
|
|
|
|
|
func (e *NotifyService) SendTextMessage(content string) (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) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
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) |
|
|
|
|
|
} |