diff --git a/slack/slack.go b/slack/slack.go index 6419fbf..c051f1b 100644 --- a/slack/slack.go +++ b/slack/slack.go @@ -3,6 +3,7 @@ package slack import ( "fmt" "log" + "os" "strings" "github.com/dustin/go-humanize" @@ -25,16 +26,49 @@ func New(token, channel string, logger *log.Logger) *Notifier { } func (n *Notifier) Notify(r usage.Report) error { + host, err := os.Hostname() + if err != nil { + log.Printf("Failed to get hostname %v", err) + } + + msg := n.Message(r, host) + + // TODO should we use a context? What is the default behavior, does posting + // the message ever time out? + _, _, err = n.client.PostMessage(n.channel, msg) + log.Printf("Posted slack message on channel") + + return err +} + +func (n *Notifier) Message(r usage.Report, host string) slack.MsgOption { + // TODO clean up code + header := "Disk usage report" + if host != "" { + header = header + fmt.Sprintf(" for host %q", host) + } + headerText := slack.NewTextBlockObject("plain_text", header, false, false) + headerSection := slack.NewSectionBlock(headerText, nil, nil) + + limitImage := slack.NewImageBlockElement("https://api.slack.com/img/blocks/bkb_template_images/notificationsWarningIcon.png", "notifications warning icon") + limitHeader := slack.NewTextBlockObject("mrkdwn", fmt.Sprintf("*Following disks have reached the usage limit of %d%%*", r.Limits[0].Limit), false, false) + var sb strings.Builder for _, l := range r.Limits { - fmt.Fprintf(&sb, "Free/Total %s/%s %q - reached limit of %d%%\n", humanize.Bytes(l.Free), humanize.Bytes(l.Total), l.Path, l.Limit) + fmt.Fprintf(&sb, "• %q - %s/%s (free/total)\n", l.Path, humanize.Bytes(l.Free), humanize.Bytes(l.Total)) } + // TODO split errors into own section? for _, e := range r.Errors { sb.WriteString(e.Error()) } - _, _, err := n.client.PostMessage( - n.channel, slack.MsgOptionText(sb.String(), false), + rest := slack.NewTextBlockObject("mrkdwn", sb.String(), false, false) + restSection := slack.NewSectionBlock(rest, nil, nil) + + limitSection := slack.NewContextBlock( + "", + []slack.MixedElement{limitImage, limitHeader}..., ) - log.Printf("Posted slack message on channel") - return err + divSection := slack.NewDividerBlock() + + return slack.MsgOptionBlocks(headerSection, divSection, limitSection, restSection) }