Skip to content

Commit

Permalink
INIT at 2021-12-09 09:30:34
Browse files Browse the repository at this point in the history
  • Loading branch information
AGou-ops committed Dec 9, 2021
0 parents commit d5d8622
Show file tree
Hide file tree
Showing 11 changed files with 527 additions and 0 deletions.
Binary file added .DS_Store
Binary file not shown.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.idea/
.vim/
Binary file added dingtalk_notify/.DS_Store
Binary file not shown.
140 changes: 140 additions & 0 deletions dingtalk_notify/notify.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
package dingtalk_notify

import (
"bytes"
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"time"
)

func NewRobot(token, secret string) *Robot {
return &Robot{
token: token,
secret: secret,
}
}

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)
}

type Robot struct {
token, secret string
}

func (robot *Robot) 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", robot.token)
if robot.secret != "" {
t := time.Now().UnixNano() / 1e6
value.Set("timestamp", fmt.Sprintf("%d", t))
value.Set("sign", sign(t, robot.secret))
}

request, err := http.NewRequest(http.MethodPost, "https://oapi.dingtalk.com/robot/send", body)
if err != nil {
return fmt.Errorf("error request: %v", err.Error())
}
request.URL.RawQuery = value.Encode()
request.Header.Add("Content-Type", "application/json;charset=utf-8")
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 (robot *Robot) SendTextMessage(content string, atUserIds []string, isAtAll bool) error {
msg := map[string]interface{}{
"msgtype": "text",
"text": map[string]string{
"content": content,
},
"at": map[string]interface{}{
"atUserIds": atUserIds,
"isAtAll": isAtAll,
},
}

return robot.SendMessage(msg)
}

func (robot *Robot) SendMarkdownMessage(title string, text string, atUserIds []string, isAtAll bool) error {
msg := map[string]interface{}{
"msgtype": "markdown",
"markdown": map[string]string{
"title": title,
"text": text,
},
"at": map[string]interface{}{
"atUserIds": atUserIds,
"isAtAll": isAtAll,
},
}

return robot.SendMessage(msg)
}

func (robot *Robot) SendActionCardMessage(title string, text string, singleTitle string, singleURL string) error {
msg := map[string]interface{}{
"msgtype": "actionCard",
"actionCard": map[string]string{
"title": title,
"text": text,
"singleTitle": singleTitle,
"singleURL": singleURL,
},
}

return robot.SendMessage(msg)
}
60 changes: 60 additions & 0 deletions dingtalk_notify/notify_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package dingtalk_notify

import (
"os"
"testing"
)

func TestRobot_SendMessage(t *testing.T) {
//t.SkipNow()

msg := map[string]interface{}{
"msgtype": "text",
"text": map[string]string{
"content": "这是一条golang钉钉消息测试.",
},
"at": map[string]interface{}{
"atMobiles": []string{},
"isAtAll": false,
},
}

robot := NewRobot("37849051cc270053f33a0d683bff85d58712e38790dfe1ddfcf86a17ad9df895", "x")
if err := robot.SendMessage(msg); err != nil {
t.Error(err)
}
}

func TestRobot_SendTextMessage(t *testing.T) {
robot := NewRobot(os.Getenv("ROBOT_TOKEN"), os.Getenv("ROBOT_SECRET"))
if err := robot.SendTextMessage("普通文本消息", []string{}, false); err != nil {
t.Error(err)
}
}

func TestRobot_SendMarkdownMessage(t *testing.T) {
robot := NewRobot(os.Getenv("ROBOT_TOKEN"), os.Getenv("ROBOT_SECRET"))
err := robot.SendMarkdownMessage(
"Markdown Test Title",
"### Markdown 测试消息\n* 谷歌: [Google](https://www.google.com/)\n* 一张图片\n ![](https://avatars0.githubusercontent.com/u/40748346)",
[]string{},
false,
)
if err != nil {
t.Error(err)
}
}

func TestRobot_SendLinkMessage(t *testing.T) {
robot := NewRobot(os.Getenv("ROBOT_TOKEN"), os.Getenv("ROBOT_SECRET"))
err := robot.SendLinkMessage(
"Link Test Title",
"这是一条链接测试消息",
"https://github.com/JetBlink",
"https://avatars0.githubusercontent.com/u/40748346",
)

if err != nil {
t.Error(err)
}
}
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module github.com/AGou-ops/dingtalk

go 1.17
Empty file added go.sum
Empty file.
8 changes: 8 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package main

func main() {

// run a simple http server
HTTPServer()

}
Loading

0 comments on commit d5d8622

Please sign in to comment.