mirror of
https://github.com/warmbly/warmbly.git
synced 2026-10-19 16:03:14 +00:00
113 lines
3.1 KiB
Go
113 lines
3.1 KiB
Go
package slackapp
|
|
|
|
// Block Kit limits the builders respect.
|
|
const (
|
|
maxSectionText = 3000
|
|
maxButtonText = 75
|
|
maxFallbackText = 3000
|
|
// maxAnswerRunes keeps one markdown block under Slack's 12,000 limit.
|
|
maxAnswerRunes = 11000
|
|
)
|
|
|
|
func plainText(s string) Block {
|
|
return Block{"type": "plain_text", "text": s, "emoji": true}
|
|
}
|
|
|
|
func mrkdwnText(s string) Block {
|
|
return Block{"type": "mrkdwn", "text": truncateRunes(s, maxSectionText)}
|
|
}
|
|
|
|
func sectionBlock(mrkdwn string) Block {
|
|
return Block{"type": "section", "text": mrkdwnText(mrkdwn)}
|
|
}
|
|
|
|
func contextBlock(mrkdwn string) Block {
|
|
return Block{"type": "context", "elements": []any{mrkdwnText(mrkdwn)}}
|
|
}
|
|
|
|
func markdownBlock(md string) Block {
|
|
return Block{"type": "markdown", "text": md}
|
|
}
|
|
|
|
func headerBlock(s string) Block {
|
|
return Block{"type": "header", "text": plainText(truncateRunes(s, 150))}
|
|
}
|
|
|
|
func actionsBlock(elements ...Block) Block {
|
|
els := make([]any, 0, len(elements))
|
|
for _, e := range elements {
|
|
if e != nil {
|
|
els = append(els, e)
|
|
}
|
|
}
|
|
return Block{"type": "actions", "elements": els}
|
|
}
|
|
|
|
// urlButton opens a link; Slack still posts a block_action, which is acked.
|
|
func urlButton(text, url string) Block {
|
|
if url == "" {
|
|
return nil
|
|
}
|
|
return Block{"type": "button", "text": plainText(truncateRunes(text, maxButtonText)), "url": url, "action_id": ActionOpenURL + ":" + text}
|
|
}
|
|
|
|
func actionButton(text, actionID, value, style string) Block {
|
|
b := Block{"type": "button", "text": plainText(truncateRunes(text, maxButtonText)), "action_id": actionID, "value": value}
|
|
if style != "" {
|
|
b["style"] = style
|
|
}
|
|
return b
|
|
}
|
|
|
|
// buttonsBlock returns an actions block, or nil when no button survived.
|
|
func buttonsBlock(elements ...Block) Block {
|
|
b := actionsBlock(elements...)
|
|
if len(b["elements"].([]any)) == 0 {
|
|
return nil
|
|
}
|
|
return b
|
|
}
|
|
|
|
// blocks drops nil entries.
|
|
func blocks(in ...Block) []Block {
|
|
out := make([]Block, 0, len(in))
|
|
for _, b := range in {
|
|
if b != nil {
|
|
out = append(out, b)
|
|
}
|
|
}
|
|
return out
|
|
}
|
|
|
|
// linkPrompt asks an unlinked Slack member to connect their Warmbly account.
|
|
func linkPrompt(linkURL, lead string) Message {
|
|
return linkPromptFor(linkURL, lead, false)
|
|
}
|
|
|
|
// linkPromptFor is linkPrompt; held says a question waits for the link.
|
|
func linkPromptFor(linkURL, lead string, held bool) Message {
|
|
if lead == "" {
|
|
lead = "Link your Warmbly account so I can answer as you, with your workspace permissions."
|
|
}
|
|
if linkURL == "" {
|
|
return Message{Text: lead, Blocks: blocks(sectionBlock(lead + " Ask your Warmbly admin to set the dashboard address (APP_URL) for this instance."))}
|
|
}
|
|
expiry := "The link works once and expires in 15 minutes."
|
|
if held {
|
|
expiry += " I'll answer your question as soon as you've linked."
|
|
}
|
|
return Message{
|
|
Text: lead,
|
|
Blocks: blocks(
|
|
sectionBlock(lead),
|
|
buttonsBlock(urlButton("Link your Warmbly account", linkURL)),
|
|
contextBlock(expiry),
|
|
),
|
|
}
|
|
}
|
|
|
|
// plainMessage is a one-section message with a matching fallback.
|
|
func plainMessage(mrkdwn string) Message {
|
|
return Message{Text: truncateRunes(mrkdwn, maxFallbackText), Blocks: blocks(sectionBlock(mrkdwn))}
|
|
}
|