From d0180b1423b2b9fc83e68452009dc0ac65df9526 Mon Sep 17 00:00:00 2001 From: Gabriel Alejandro Soltz Date: Wed, 23 Jul 2025 12:12:25 +0200 Subject: [PATCH 1/2] support-slack-username --- pkg/providers/slack/slack.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pkg/providers/slack/slack.go b/pkg/providers/slack/slack.go index 85bf7cf..4b08f3f 100644 --- a/pkg/providers/slack/slack.go +++ b/pkg/providers/slack/slack.go @@ -76,6 +76,12 @@ func (p *Provider) Send(message, CliFormat string) error { Path: slackTokens, } + query := url.Query() + if pr.SlackUsername != "" { + query.Set("username", pr.SlackUsername) + } + url.RawQuery = query.Encode() + err := shoutrrr.Send(url.String(), msg) if err != nil { err = errors.Wrap(err, @@ -85,7 +91,6 @@ func (p *Provider) Send(message, CliFormat string) error { } } gologger.Verbose().Msgf("Slack notification sent for id: %s", pr.ID) - } return SlackErr } From 220a2e5744192c527ee6cd69312a3e0158c6f8fc Mon Sep 17 00:00:00 2001 From: Gabriel Alejandro Soltz Date: Wed, 23 Jul 2025 12:24:00 +0200 Subject: [PATCH 2/2] support-slack-icon-emoji --- README.md | 2 ++ pkg/providers/slack/slack.go | 42 +++++++++++++++++++++++++----------- 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 9260952..20ad0d0 100644 --- a/README.md +++ b/README.md @@ -88,12 +88,14 @@ slack: slack_channel: "recon" slack_username: "test" slack_format: "{{data}}" + slack_icon_emoji: ":ghost:" slack_webhook_url: "https://hooks.slack.com/services/XXXXXX" - id: "vulns" slack_channel: "vulns" slack_username: "test" slack_format: "{{data}}" + slack_icon_emoji: ":ghost:" slack_webhook_url: "https://hooks.slack.com/services/XXXXXX" discord: diff --git a/pkg/providers/slack/slack.go b/pkg/providers/slack/slack.go index 4b08f3f..e7e6185 100644 --- a/pkg/providers/slack/slack.go +++ b/pkg/providers/slack/slack.go @@ -1,11 +1,12 @@ package slack import ( + "bytes" + "encoding/json" "fmt" - "net/url" + "net/http" "strings" - "github.com/containrrr/shoutrrr" "github.com/pkg/errors" "go.uber.org/multierr" @@ -28,6 +29,7 @@ type Options struct { SlackThreadTS string `yaml:"slack_thread_ts,omitempty"` SlackToken string `yaml:"slack_token,omitempty"` SlackFormat string `yaml:"slack_format,omitempty"` + SlackIconEmoji string `yaml:"slack_icon_emoji,omitempty"` } func New(options []*Options, ids []string) (*Provider, error) { @@ -50,6 +52,7 @@ func (p *Provider) Send(message, CliFormat string) error { for _, pr := range p.Slack { msg := utils.FormatMessage(message, utils.SelectFormat(CliFormat, pr.SlackFormat), p.counter) + // Handle threaded messages separately if pr.SlackThreads { if pr.SlackToken == "" { err := errors.Wrap(fmt.Errorf("slack_token value is required to start a thread"), @@ -70,22 +73,37 @@ func (p *Provider) Send(message, CliFormat string) error { continue } } else { - slackTokens := strings.TrimPrefix(pr.SlackWebHookURL, "https://hooks.slack.com/services/") - url := &url.URL{ - Scheme: "slack", - Path: slackTokens, + // Send via webhook with emoji and username + if !strings.HasPrefix(pr.SlackWebHookURL, "https://hooks.slack.com/services/") { + err := errors.Wrap(fmt.Errorf("invalid slack webhook URL"), + fmt.Sprintf("failed to send slack notification for id: %s ", pr.ID)) + SlackErr = multierr.Append(SlackErr, err) + continue } - query := url.Query() + payload := map[string]interface{}{ + "text": msg, + } if pr.SlackUsername != "" { - query.Set("username", pr.SlackUsername) + payload["username"] = pr.SlackUsername + } + if pr.SlackIconEmoji != "" { + payload["icon_emoji"] = pr.SlackIconEmoji } - url.RawQuery = query.Encode() - err := shoutrrr.Send(url.String(), msg) + jsonPayload, err := json.Marshal(payload) if err != nil { - err = errors.Wrap(err, - fmt.Sprintf("failed to send slack notification for id: %s ", pr.ID)) + err = errors.Wrap(err, fmt.Sprintf("failed to marshal Slack payload for id: %s", pr.ID)) + SlackErr = multierr.Append(SlackErr, err) + continue + } + + resp, err := http.Post(pr.SlackWebHookURL, "application/json", bytes.NewBuffer(jsonPayload)) + if err != nil || resp.StatusCode >= 400 { + if err == nil { + err = fmt.Errorf("received non-success status: %s", resp.Status) + } + err = errors.Wrap(err, fmt.Sprintf("failed to send slack notification for id: %s", pr.ID)) SlackErr = multierr.Append(SlackErr, err) continue }