slack-go / slack

Slack API in Go, originally by @nlopes; Maintainers needed, contact @parsley42

Home Page:https://pkg.go.dev/github.com/slack-go/slack

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Webhook Sending Functions Seem to Use the Regular JSON Encoder Which Escapes HTML Characters Unnecessarily

zoominGiladSher opened this issue · comments

What happened

While working on a Github action to send a release note to a Slack channel I saw that using the PostWebhook function causes the message to have weird characters in Slack due to the HTML escaping. For example, an apostrophe is converted to '.

Expected behavior

JSON marshaller only encodes the relevant characters as defined in the Slack documentation

Steps to reproduce

Send a webhook with an apostrophe in the body of the request. See that the resulting message has an HTML escaped symbol.

reproducible code

package main

import (
	"github.com/slack-go/slack"
)

func main() {
    blocks = new(slack.Blocks)
    blocks.BlockSet = append(blocks.BlockSet, slack.NewSectionBlock(slack.NewTextBlockObject("mrkdwn", "'test' What's up", false, false), nil, nil))
    _ := slack.PostWebhook("<WebhookURL>", &slack.WebhookMessage{Blocks: blocks})
}

manifest.yaml

Not sure what this is?

Versions

  • Go: go version go1.21.5 darwin/arm64
  • slack-go/slack: v0.12.3

Extra context: I saw this in

slack/webhooks.go

Lines 41 to 63 in e715221

func PostWebhookCustomHTTPContext(ctx context.Context, url string, httpClient *http.Client, msg *WebhookMessage) error {
raw, err := json.Marshal(msg)
if err != nil {
return fmt.Errorf("marshal failed: %w", err)
}
req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewReader(raw))
if err != nil {
return fmt.Errorf("failed new request: %w", err)
}
req.Header.Set("Content-Type", "application/json")
resp, err := httpClient.Do(req)
if err != nil {
return fmt.Errorf("failed to post webhook: %w", err)
}
defer func() {
io.Copy(ioutil.Discard, resp.Body)
resp.Body.Close()
}()
return checkStatusCode(resp, discard{})
}
and see that there's no use of the EscapeMessage function mentioned in
// initialize replacer only once (if needed)
var escapeReplacer = strings.NewReplacer("&", "&amp;", "<", "&lt;", ">", "&gt;")
// EscapeMessage text
func EscapeMessage(message string) string {
return escapeReplacer.Replace(message)
}

Not sure if this is the solution, but this is what I saw from a very shallow look at things. Please let me know if I can help in any way or if you'd like me to try and tackle this myself!