generated from dronestock/template
-
Notifications
You must be signed in to change notification settings - Fork 0
/
notify.go
131 lines (111 loc) · 3.72 KB
/
notify.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
126
127
128
129
130
131
package step
import (
"context"
_ "embed"
"strings"
"time"
"github.com/dronestock/drone"
"github.com/dronestock/feishu/internal/config"
"github.com/dronestock/feishu/internal/step/internal/constant"
"github.com/dronestock/feishu/internal/step/internal/feishu/message"
"github.com/dronestock/feishu/internal/step/internal/notify"
"github.com/go-resty/resty/v2"
"github.com/goexl/exception"
"github.com/goexl/gox"
"github.com/goexl/gox/field"
"github.com/goexl/gox/tpl"
"github.com/rs/xid"
)
//go:embed internal/notify/template.gohtml
var defaultNotifyTemplate []byte
type Notify struct {
base *drone.Base
card *config.Card
user *config.User
notfound *config.Notfound
}
func NewNotify(base *drone.Base, card *config.Card, user *config.User, notfound *config.Notfound) *Notify {
return &Notify{
base: base,
card: card,
user: user,
notfound: notfound,
}
}
func (n *Notify) Runnable() bool {
return true
}
func (n *Notify) Run(ctx *context.Context) (err error) {
if token, ok := (*ctx).Value(constant.ContextKeyToken).(string); !ok {
err = exception.New().Message("没有正确的授权码").Build()
} else if request, mre := n.makeRequest(); nil != mre {
err = mre
} else {
err = n.send(ctx, request, token)
}
return
}
func (n *Notify) makeRequest() (req *message.Request, err error) {
req = new(message.Request)
req.Id = xid.New().String()
req.Receive = n.user.Id
req.Type = constant.MessageTypeInteractive
request := new(notify.Request)
build := new(notify.Build)
build.Status = n.base.Value("BUILD_STATUS").String()
build.Url = n.base.Value("BUILD_LINK").String()
build.Name = n.base.Value("REPO").String()
build.Created = n.base.Value("BUILD_CREATED").Time()
build.Finished = n.base.Value("BUILD_STARTED").Time()
build.Elapsed = n.base.Elapsed().Truncate(time.Second)
build.Steps = n.base.Value("FAILED_STEPS").Slices()
request.Build = build
code := new(notify.Code)
code.Pr = n.base.Value("COMMIT_LINK").String()
code.Repository = n.base.Value("REPO_LINK").String()
code.Commit = n.base.Value("COMMIT_LINK").String()
code.Message = n.base.Value("COMMIT_MESSAGE").String()
request.Code = code
// 加载模板
req.Content, err = n.load(request)
return
}
func (n *Notify) send(ctx *context.Context, req *message.Request, token string) (err error) {
rsp := new(message.Response)
idType := gox.StringBuilder(n.user.Type, constant.ReceiveTypeStaff).String()
http := n.base.Http().R().SetContext(*ctx).SetAuthToken(token).SetBody(req).SetResult(rsp)
if response, pe := http.SetQueryParam(constant.ReceiveType, idType).Post(constant.MessageUrl); nil != pe {
err = pe
} else if response.IsError() {
err = n.onError(ctx, token, response, req, rsp)
} else {
n.base.Debug("发送消息成功", field.New("response", rsp))
}
return
}
func (n *Notify) load(req *notify.Request) (content string, err error) {
if "" != n.card.Template {
content, err = tpl.New(n.card.Template).File().Data(req).Build().ToString()
} else {
content, err = tpl.New(string(defaultNotifyTemplate)).Data(req).Build().ToString()
}
if nil == err { // ! 去掉所有空白字符,不然会报格式错误
content = strings.ReplaceAll(content, "\n", "")
}
return
}
func (n *Notify) onError(
ctx *context.Context, token string,
response *resty.Response,
req *message.Request, rsp *message.Response,
) (err error) {
if constant.CodeUserNotfound == rsp.Code {
req.Receive = n.notfound.Id
req.Type = n.notfound.Type
n.base.Warn("未找到用户,发送消息给默认用户", field.New("user", n.user), field.New("notfound", n.notfound))
err = n.send(ctx, req, token)
} else {
err = exception.New().Message("飞书返回错误").Field(field.New("response", string(response.Body()))).Build()
}
return
}