argoproj / argoproj/notifications-engine

[slack] Support new Block Kit blocks in notification templates

Open Beginner friendly
#466 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Go
Stars
334
Forks
217
PR merge metrics
No merged PRs in 30d

Description

The Slack service pins `github.com/slack-go/slack` at `v0.16.0`. Block Kit types added since then (e.g. `table`, `markdown`) aren't in `Blocks.UnmarshalJSON`'s type switch, so they fall through to `UnknownBlock`, which only keeps `type`/`block_id` and drops everything else.

The block is then re-marshaled as a bare `{"type":"table"}` and Slack's API rejects the whole payload with `invalid_blocks`/`invalid_attachments`, whether the block was placed under `slack.blocks` or `slack.attachments`.

From a user perspective, this feels like a wrongly formatted template on its end when in reality it's the client that silently strips the block's content.

## Reproduction

Save the following file as `main.go` in a new folder. It unmarshals a `section` block alongside a `table` and a `markdown` block (similarly to how it's done in [`slack.go`](https://github.com/argoproj/notifications-engine/blob/master/pkg/services/slack.go#L155-L163)), then re-marshals them as is currently done by the Slack client (see [`chat.go`](https://github.com/slack-go/slack/blob/v0.27.0/chat.go#L397-L403)):

```go
// main.go
package main

import (
"encoding/json"
"fmt"

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

func main() {
input := `[
{"type": "section", "text": {"type": "mrkdwn", "text": "hello"}},
{"type": "table", "rows": [[{"type": "raw_text", "text": "a"}]]},
{"type": "markdown", "text": "**bold**"}
]`

var blocks slack.Blocks
json.Unmarshal([]byte(input), &blocks)
for i, b := range blocks.BlockSet {
fmt.Printf("block[%d]: %T (%s)\n", i, b, b.BlockType())
}
out, _ := json.Marshal(blocks)
fmt.Println(string(out))
}
```

Initialize this folder as a Go module, fetch the currently pinned `slack-go` version and run `main.go`:

```text
$ go mod init repo
$ go get github.com/slack-go/slack@v0.16.0
$ go run main.go
block[0]: *slack.SectionBlock (section)
block[1]: *slack.UnknownBlock (table)
block[2]: *slack.UnknownBlock (markdown)
[{"type":"section","text":{"type":"mrkdwn","text":"hello"}},{"type":"table"},{"type":"markdown"}]
```

Re-run the same test after updating `slack-go` to `v0.27.0`:

```text
$ go get github.com/slack-go/slack@v0.27.0
$ go run main.go
[{"type":"section","text":{"type":"mrkdwn","text":"hello"}},{"type":"table","rows":[[{"type":"raw_text","text":"a"}]]},{"type":"markdown","text":"**bold**"}]
```

## Proposed fix

Bump `github.com/slack-go/slack` in `go.mod` to a current release to support those newly added blocks.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with go.mod and the Slack integration in pkg/services/slack.go, then run the provided main.go reproduction using the pinned dependency. Verify that table and markdown blocks retain their fields when unmarshaled and re-marshaled, including when used in Slack blocks or attachments.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
backend
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
82/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.