@@ -2,6 +2,8 @@ package notification
22
33import (
44 "bytes"
5+ "context"
6+ "fmt"
57 "html/template"
68 "os"
79
@@ -10,9 +12,6 @@ import (
1012)
1113
1214const (
13- START = "start"
14- SUCCESS = "success"
15- FAILED = "failed"
1615 SlackMessageTemplate = `
1716{{if .CronJobName}} *CronJobName*: {{.CronJobName}}{{end}}
1817 *JobName*: {{.JobName}}
@@ -39,33 +38,44 @@ var slackColors = map[string]string{
3938
4039type slackClient interface {
4140 PostMessage (channelID string , options ... slackapi.MsgOption ) (string , string , error )
42- UploadFile (params slackapi.FileUploadParameters ) (file * slackapi.File , err error )
41+ UploadFileV2Context (ctx context.Context , params slackapi.UploadFileV2Parameters ) (file * slackapi.FileSummary , err error )
42+ GetFileInfoContext (ctx context.Context , fileID string , count , page int ) (* slackapi.File , []slackapi.Comment , * slackapi.Paging , error )
43+ GetConversationsContext (ctx context.Context , params * slackapi.GetConversationsParameters ) (channels []slackapi.Channel , nextCursor string , err error )
4344}
4445
4546type slack struct {
46- client slackClient
47- channel string
48- username string
47+ client slackClient
48+ channel string
49+ channelID string
50+ username string
4951}
5052
5153func newSlack () slack {
54+ ctx := context .Background ()
5255 token := os .Getenv ("SLACK_TOKEN" )
5356 if token == "" {
5457 panic ("please set slack client" )
5558 }
5659
57- client := slackapi .New (token )
60+ newSlack := slackapi .New (token )
5861
62+ client := slack {
63+ client : newSlack ,
64+ }
5965 channel := os .Getenv ("SLACK_CHANNEL" )
6066
67+ channelID := client .getChannelID (ctx , channel )
68+ if channelID == "" {
69+ channelID = channel
70+ }
71+ client .channelID = channelID
72+
6173 username := os .Getenv ("SLACK_USERNAME" )
6274
63- return slack {
64- client : client ,
65- channel : channel ,
66- username : username ,
67- }
75+ client .username = username
76+ client .channel = channel
6877
78+ return client
6979}
7080
7181func (s slack ) NotifyStart (messageParam MessageTemplateParam ) (err error ) {
@@ -252,23 +262,103 @@ func (s slack) notify(attachment slackapi.Attachment) (err error) {
252262}
253263
254264func (s slack ) uploadLog (param MessageTemplateParam ) (file * slackapi.File , err error ) {
255- file , err = s .client .UploadFile (
256- slackapi.FileUploadParameters {
257- Title : param .Namespace + "_" + param .JobName ,
258- Content : param .Log ,
259- Filetype : "txt" ,
260- Channels : []string {s .channel },
261- })
265+ ctx := context .Background ()
266+ content := param .Log
267+ filename := param .Namespace + "_" + param .JobName + ".txt"
268+
269+ fileSize := len ([]byte (content ))
270+ if fileSize == 0 {
271+ return nil , fmt .Errorf ("file size cannot be 0" )
272+ }
273+
274+ if filename == "" {
275+ return nil , fmt .Errorf ("filename cannot be empty" )
276+ }
277+
278+ if s .channel == "" {
279+ return nil , fmt .Errorf ("channel cannot be empty" )
280+ }
281+
282+ // Use filename if title is empty
283+ title := param .Namespace + "_" + param .JobName
284+ if title == "" || title == "_" {
285+ title = filename
286+ }
287+
288+ params := slackapi.UploadFileV2Parameters {
289+ Title : title ,
290+ Content : content ,
291+ FileSize : fileSize ,
292+ Filename : filename ,
293+ Channel : s .channelID ,
294+ }
295+
296+ klog .V (4 ).Infof ("Uploading file: title=%s, filename=%s, fileSize=%d, channel=%s, channelID=%s)" , title , filename , fileSize , s .channel , s .channelID )
297+
298+ fileSummary , err := s .client .UploadFileV2Context (ctx , params )
299+ if err != nil {
300+ klog .Errorf ("File uploadLog failed: %v (title=%s, filename=%s, fileSize=%d, channel=%s, channelID=%s, contentLength=%d)\n " ,
301+ err , title , filename , fileSize , s .channel , s .channelID , len (content ))
302+ return
303+ }
304+
305+ // Get complete File information from FileSummary to get Permalink
306+ fileInfo , _ , _ , err := s .client .GetFileInfoContext (ctx , fileSummary .ID , 0 , 0 )
262307 if err != nil {
263- klog .Errorf ("File uploadLog failed %s\n " , err )
308+ klog .Errorf ("Get file info failed %s\n " , err )
264309 return
265310 }
266311
267- klog .Infof ("File uploadLog successfully %s" , file .Name )
268- return
312+ klog .Infof ("File uploadLog successfully %s" , fileInfo .Name )
313+ return fileInfo , nil
269314}
270315
271316func isNotifyFromEnv (key string ) bool {
272317 value := os .Getenv (key )
273318 return value != "false"
274319}
320+
321+ // getChannelID converts a channel name (e.g., "#channel-name") to a channel ID (e.g., "C1234567890")
322+ // If the input is already a channel ID or lookup fails, it returns the original value
323+ func (s slack ) getChannelID (ctx context.Context , channel string ) string {
324+ // If channel starts with 'C', 'G', or 'D', it's likely already a channel ID
325+ if len (channel ) > 0 && (channel [0 ] == 'C' || channel [0 ] == 'G' || channel [0 ] == 'D' ) {
326+ return channel
327+ }
328+
329+ // Remove '#' prefix if present
330+ channelName := channel
331+ if len (channelName ) > 0 && channelName [0 ] == '#' {
332+ channelName = channelName [1 :]
333+ }
334+
335+ // Try to find the channel by name
336+ params := & slackapi.GetConversationsParameters {
337+ Types : []string {"public_channel" , "private_channel" },
338+ Limit : 1000 ,
339+ Cursor : "" ,
340+ }
341+
342+ for {
343+ channels , nextCursor , err := s .client .GetConversationsContext (ctx , params )
344+ if err != nil {
345+ klog .V (4 ).Infof ("Failed to get conversations: %v" , err )
346+ return ""
347+ }
348+
349+ for _ , ch := range channels {
350+ if ch .Name == channelName {
351+ klog .V (4 ).Infof ("Found channel ID %s for channel name %s" , ch .ID , channelName )
352+ return ch .ID
353+ }
354+ }
355+
356+ if nextCursor == "" {
357+ break
358+ }
359+ params .Cursor = nextCursor
360+ }
361+
362+ klog .V (4 ).Infof ("Channel ID not found for channel name %s" , channelName )
363+ return ""
364+ }
0 commit comments