forked from nikoksr/notify
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcustom_app.go
119 lines (103 loc) · 3.06 KB
/
custom_app.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
package lark
import (
"context"
"fmt"
"net/http"
"time"
"github.com/go-lark/lark"
"github.com/nikoksr/notify"
)
const defaultTimeout = 10 * time.Second
// CustomAppService is a Lark notify service using a Lark custom app.
type CustomAppService struct {
receiveIDs []*ReceiverID
cli sendToer
}
// Compile time check that larkCustomAppService implements notify.Notifer.
var _ notify.Notifier = &CustomAppService{}
// NewCustomAppService returns a new instance of a Lark notify service using a
// Lark custom app.
func NewCustomAppService(appID, appSecret string) *CustomAppService {
bot := lark.NewChatBot(appID, appSecret)
// We need to set the bot to use Lark's open.larksuite.com domain instead of
// the default open.feishu.cn domain.
bot.SetDomain(lark.DomainLark)
// Let the bot use a HTTP client with a longer timeout than the default 5
// seconds.
bot.SetClient(&http.Client{
Timeout: defaultTimeout,
})
_ = bot.StartHeartbeat()
return &CustomAppService{
receiveIDs: make([]*ReceiverID, 0),
cli: &larkClientGoLarkChatBot{
bot: bot,
},
}
}
// AddReceivers adds recipients to future notifications. There are five different
// types of receiver IDs available in Lark and they must be specified here. For
// example:
//
// larkService.AddReceivers(
// lark.OpenID("ou_c99c5f35d542efc7ee492afe11af19ef"),
// lark.UserID("8335aga2"),
// lark.UnionID("on_cad4860e7af114fb4ff6c5d496d1dd76"),
// lark.Email("[email protected]"),
// lark.ChatID("oc_a0553eda9014c201e6969b478895c230"),
// )
func (c *CustomAppService) AddReceivers(ids ...*ReceiverID) {
c.receiveIDs = append(c.receiveIDs, ids...)
}
// Send takes a message subject and a message body and sends them to all
// previously registered recipient IDs.
func (c *CustomAppService) Send(ctx context.Context, subject, message string) error {
for _, id := range c.receiveIDs {
select {
case <-ctx.Done():
return ctx.Err()
default:
if err := c.cli.SendTo(subject, message, id.id, string(id.typ)); err != nil {
return err
}
}
}
return nil
}
// larkClientGoLarkChatBot is a wrapper around go-lark/lark's Bot, to be used
// for sending messages with custom apps.
type larkClientGoLarkChatBot struct {
bot *lark.Bot
}
// SendTo implements the sendToer interface using a go-lark/lark chat bot.
func (l *larkClientGoLarkChatBot) SendTo(subject, message, receiverID, idType string) error {
content := lark.NewPostBuilder().
Title(subject).
TextTag(message, 1, false).
Render()
msg := lark.NewMsgBuffer(lark.MsgPost).Post(content)
switch receiverIDType(idType) {
case openID:
msg.BindOpenID(receiverID)
case userID:
msg.BindUserID(receiverID)
case unionID:
msg.BindUnionID(receiverID)
case email:
msg.BindEmail(receiverID)
case chatID:
msg.BindChatID(receiverID)
}
res, err := l.bot.PostMessage(msg.Build())
if err != nil {
return fmt.Errorf("send message: %w", err)
}
if res.Code != 0 {
return fmt.Errorf(
"send failed with error code %d, please see "+
"https://open.larksuite.com/document/ukTMukTMukTM/ugjM14COyUjL4ITN for details",
res.Code,
)
}
return nil
}