@@ -3,6 +3,7 @@ package telegram
3
3
import (
4
4
"encoding/json"
5
5
"net/http"
6
+ "strconv"
6
7
"strings"
7
8
"text/template"
8
9
@@ -21,6 +22,11 @@ type Client struct {
21
22
meta model.Meta
22
23
}
23
24
25
+ type chatID struct {
26
+ id int64
27
+ topics []int64
28
+ }
29
+
24
30
// New creates a new Telegram notification instance
25
31
func New (config * model.NotifTelegram , meta model.Meta ) notifier.Notifier {
26
32
return notifier.Notifier {
@@ -43,16 +49,27 @@ func (c *Client) Send(entry model.NotifEntry) error {
43
49
return errors .Wrap (err , "cannot retrieve token secret for Telegram notifier" )
44
50
}
45
51
46
- chatIDs := c .cfg .ChatIDs
47
- chatIDsRaw , err := utl .GetSecret ("" , c .cfg .ChatIDsFile )
52
+ var cids []interface {}
53
+ for _ , cid := range c .cfg .ChatIDs {
54
+ cids = append (cids , cid )
55
+ }
56
+ cidsRaw , err := utl .GetSecret ("" , c .cfg .ChatIDsFile )
48
57
if err != nil {
49
58
return errors .Wrap (err , "cannot retrieve chat IDs secret for Telegram notifier" )
50
59
}
51
- if len (chatIDsRaw ) > 0 {
52
- if err = json .Unmarshal ([]byte (chatIDsRaw ), & chatIDs ); err != nil {
60
+ if len (cidsRaw ) > 0 {
61
+ if err = json .Unmarshal ([]byte (cidsRaw ), & cids ); err != nil {
53
62
return errors .Wrap (err , "cannot unmarshal chat IDs secret for Telegram notifier" )
54
63
}
55
64
}
65
+ if len (cids ) == 0 {
66
+ return errors .New ("no chat IDs provided for Telegram notifier" )
67
+ }
68
+
69
+ parsedChatIDs , err := parseChatIDs (cids )
70
+ if err != nil {
71
+ return errors .Wrap (err , "cannot parse chat IDs for Telegram notifier" )
72
+ }
56
73
57
74
bot , err := gotgbot .NewBot (token , & gotgbot.BotOpts {
58
75
BotClient : & gotgbot.BaseBotClient {
@@ -90,15 +107,67 @@ func (c *Client) Send(entry model.NotifEntry) error {
90
107
return err
91
108
}
92
109
93
- for _ , chatID := range chatIDs {
94
- _ , err := bot .SendMessage (chatID , string (body ), & gotgbot.SendMessageOpts {
95
- ParseMode : gotgbot .ParseModeMarkdown ,
96
- LinkPreviewOptions : & gotgbot.LinkPreviewOptions {IsDisabled : true },
97
- })
98
- if err != nil {
99
- return err
110
+ for _ , cid := range parsedChatIDs {
111
+ if len (cid .topics ) > 0 {
112
+ for _ , topic := range cid .topics {
113
+ if err = sendTelegramMessage (bot , cid .id , topic , string (body )); err != nil {
114
+ return err
115
+ }
116
+ }
117
+ } else {
118
+ if err = sendTelegramMessage (bot , cid .id , 0 , string (body )); err != nil {
119
+ return err
120
+ }
100
121
}
101
122
}
102
123
103
124
return nil
104
125
}
126
+
127
+ func parseChatIDs (entries []interface {}) ([]chatID , error ) {
128
+ var chatIDs []chatID
129
+ for _ , entry := range entries {
130
+ switch v := entry .(type ) {
131
+ case int :
132
+ chatIDs = append (chatIDs , chatID {id : int64 (v )})
133
+ case int64 :
134
+ chatIDs = append (chatIDs , chatID {id : v })
135
+ case string :
136
+ parts := strings .Split (v , ":" )
137
+ if len (parts ) < 1 || len (parts ) > 2 {
138
+ return nil , errors .Errorf ("invalid chat ID %q" , v )
139
+ }
140
+ id , err := strconv .ParseInt (parts [0 ], 10 , 64 )
141
+ if err != nil {
142
+ return nil , errors .Wrap (err , "invalid chat ID" )
143
+ }
144
+ var topics []int64
145
+ if len (parts ) == 2 {
146
+ topicParts := strings .Split (parts [1 ], ";" )
147
+ for _ , topicPart := range topicParts {
148
+ topic , err := strconv .ParseInt (topicPart , 10 , 64 )
149
+ if err != nil {
150
+ return nil , errors .Wrapf (err , "invalid topic %q for chat ID %d" , topicPart , id )
151
+ }
152
+ topics = append (topics , topic )
153
+ }
154
+ }
155
+ chatIDs = append (chatIDs , chatID {
156
+ id : id ,
157
+ topics : topics ,
158
+ })
159
+ default :
160
+ return nil , errors .Errorf ("invalid chat ID %v (type=%T)" , entry , entry )
161
+ }
162
+ }
163
+ return chatIDs , nil
164
+ }
165
+
166
+ func sendTelegramMessage (bot * gotgbot.Bot , chatID int64 , threadID int64 , message string ) error {
167
+ _ , err := bot .SendMessage (chatID , message , & gotgbot.SendMessageOpts {
168
+ MessageThreadId : threadID ,
169
+ ParseMode : gotgbot .ParseModeMarkdown ,
170
+ LinkPreviewOptions : & gotgbot.LinkPreviewOptions {IsDisabled : true },
171
+ })
172
+ return err
173
+ }
0 commit comments