Do-it-Yourself Templating for Slack API (Go)

Hey @username!This is a friendly reminder that you only have {{ .DaysLeft }} days left until the deadline!Make sure to *<https://link.to/some/form|submit your paper>*!
{
"blocks": [
{
"type": "section",
"text": {
"type": "plain_text",
"text": "Hey <@username>!"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "This is a friendly reminder that you only have {{ .DaysLeft }} days left until the deadline!\n\nMake sure to *<https://link.to/some/form|submit your paper>*!"
}
}
]
}
//go:embed templates/*
var content embed.FS
// error handling omitted for brevitydata, _ := content.ReadFile(filename)
tmpl, _ := template.New("tmpl").Parse(string(data))
var buf bytes.Buffer
_ := tmpl.Execute(&buf, arg) // pretend arg has everything required
// Note: as of this writing (Oct 2021), I couldn't unmarshal
// Block kit to slack.Blocks struct, so I had to devise a hack (*1)
var blocks slack.Blocks
_ := json.Unmarshal(buf.Bytes(), &blocks)
var options []slack.MsgOption
options = append(options, slack.MsgOptionBlocks(blocks.Blocks...))
_, _, _ := client.PostMessage(channel, options...)
blocks:
- type: section
text:
type: plain_text
text: "Hey <@username>!"
- type: section
text:
type: mrkdwn
text: |
This is a friendly reminder that you only have {{ .DaysLeft }} days left until the deadline!

Make sure to *<https://link.to/some/form|submit your paper>*!
type Blocks struct {
Blocks []slack.Block `json:"blocks"`
}
type blockhint struct {
Typ string `json:"type"`
}
func (b *Blocks) UnmarshalJSON(data []byte) error {
var proxy struct {
Blocks []json.RawMessage `json:"blocks"`
}
if err := json.Unmarshal(data, &proxy); err != nil {
return fmt.Errorf(`failed to unmarshal blocks array: %w`, err)
}
for _, rawBlock := range proxy.Blocks {
var hint blockhint
if err := json.Unmarshal(rawBlock, &hint); err != nil {
return fmt.Errorf(`failed to unmarshal next block for hint: %w`, err)
}
var block slack.Block
switch hint.Typ {
case "actions":
block = &slack.ActionBlock{}
case "context":
block = &slack.ContextBlock{}
case "divider":
block = &slack.DividerBlock{}
case "file":
block = &slack.FileBlock{}
case "header":
block = &slack.HeaderBlock{}
case "image":
block = &slack.ImageBlock{}
case "input":
block = &slack.InputBlock{}
case "section":
block = &slack.SectionBlock{}
default:
block = &slack.UnknownBlock{}
}
if err := json.Unmarshal(rawBlock, block); err != nil {
return fmt.Errorf(`failed to unmarshal next block: %w`, err)
}
b.Blocks = append(b.Blocks, block)
}
return nil
}
var blocks mypkg.Blocks

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store