/
lark.go
125 lines (109 loc) · 2.76 KB
/
lark.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
package notifiers
import (
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
"fmt"
"strings"
"time"
"github.com/KevinGong2013/apkgo/cmd/shared"
"github.com/go-resty/resty/v2"
)
type LarkNotifier struct {
Key string `json:"key,omitempty"`
SecretToken string `json:"secret_token"`
}
// https://open.feishu.cn/document/ukTMukTMukTM/ucTM5YjL3ETO24yNxkjN
func (l *LarkNotifier) BuildAppPubishedMessage(req shared.PublishRequest, result map[string]string) string {
builder := new(strings.Builder)
builder.WriteString(fmt.Sprintf("**%s(%s)** %s\\n\\n", req.AppName, req.Version(), req.PackageName))
var failed []string
for k, v := range result {
if len(v) == 0 {
builder.WriteString(fmt.Sprintf("👌%s上传成功\\n", k))
} else {
builder.WriteString(fmt.Sprintf("❌%s err: %s\\n", k, v))
failed = append(failed, k)
}
}
if len(failed) == 0 {
builder.WriteString("\\n👏👏👏 所有平台上传成功")
} else if len(failed) == len(result) {
builder.WriteString("\\n😢😢😢 所有平台上传失败")
} else {
builder.WriteString(fmt.Sprintf("%s 上传失败,请检查", strings.Join(failed, ",")))
}
partialJSON := fmt.Sprintf(`
"msg_type": "interactive",
"card": {
"config": {
"wide_screen_mode": true
},
"elements": [
{
"tag": "markdown",
"content": "%s"
},
{
"tag": "note",
"elements": [
{
"tag": "plain_text",
"content": "%s"
}
]
}
],
"header": {
"template": "green",
"title": {
"content": "apkgo应用发布结束",
"tag": "plain_text"
}
}
}
`, builder.String(),
time.Now().Format(time.RFC3339),
)
return partialJSON
}
func (l *LarkNotifier) Notify(partialJsonStr string) error {
var jsonStr string
if l.SecretToken != "" {
timestamp := time.Now().Unix()
signature, err := GenSign(l.SecretToken, timestamp)
if err != nil {
return err
}
jsonStr = fmt.Sprintf(`{
"timestamp": %v,
"sign": "%s",
%s
}`, timestamp, signature, partialJsonStr)
} else {
jsonStr = fmt.Sprintf(`{
%s
} `, partialJsonStr)
}
url := fmt.Sprintf("https://open.feishu.cn/open-apis/bot/v2/hook/%s", l.Key)
resp, err := resty.New().R().SetBody(jsonStr).SetHeader("Content-Type", "application/json").Post(url)
if err != nil {
return err
}
if resp.StatusCode() >= 400 {
return fmt.Errorf("请求失败 %s, %s", resp.Status(), string(resp.Body()))
}
return nil
}
func GenSign(secret string, timestamp int64) (string, error) {
//Encode timestamp + key with SHA256, and then with Base64
stringToSign := fmt.Sprintf("%v", timestamp) + "\n" + secret
var data []byte
h := hmac.New(sha256.New, []byte(stringToSign))
_, err := h.Write(data)
if err != nil {
return "", err
}
signature := base64.StdEncoding.EncodeToString(h.Sum(nil))
return signature, nil
}