From 927042dd2fd6c41c3947e59b7d8d4d6ca0d4f092 Mon Sep 17 00:00:00 2001 From: Yusuke Kuoka Date: Mon, 17 Feb 2020 08:54:55 +0900 Subject: [PATCH] fix(slackbot): Do not hang after a dialog is cancelled --- pkg/slack/README.md | 12 ++++++++++++ pkg/slack/slack.go | 9 ++++++--- slack.go | 15 +++++++++++---- 3 files changed, 29 insertions(+), 7 deletions(-) create mode 100644 pkg/slack/README.md diff --git a/pkg/slack/README.md b/pkg/slack/README.md new file mode 100644 index 0000000..b68844a --- /dev/null +++ b/pkg/slack/README.md @@ -0,0 +1,12 @@ +# Slackbot integration for Variant 2 + +This package provides a HTTP server that handles Slack interaction callbacks so that +it can run any variant command in response to a Slack slash command. + +## Acknowledgements + +I've learned how to code a Slack bot in Go by reading the following repositories and articles: + +- https://github.com/kpurdon/slappd +- https://github.com/shiimaxx/slack-coffeebot +- https://github.com/eure/cafe-bot/ diff --git a/pkg/slack/slack.go b/pkg/slack/slack.go index 5a0594b..365d47d 100644 --- a/pkg/slack/slack.go +++ b/pkg/slack/slack.go @@ -259,7 +259,10 @@ func (conn *Connection) Run() error { userInput := cmd.Command + " " + cmdText - c := "run " + cmdText + // This should be a full Variant command without the executable name. + // + // E.g. for what you would type `variant run foo bar --opt1`, this shuold be `run foo bar --opt1`, as without the executable name. + variantCmdWithArgs := "run " + cmdText response := slack.Message{} // You should always specify response type even when you're intended to use the default "ephemeral" @@ -278,7 +281,7 @@ func (conn *Connection) Run() error { _, _, _, err := conn.Client.SendMessage( cmd.ChannelID, slack.MsgOptionResponseURL(cmd.ResponseURL, slack.ResponseTypeEphemeral), - slack.MsgOptionText(fmt.Sprintf("Running `%s`... I'll soon post a message visible to everyone in this channel to share the progress and the result of it.", c), false), + slack.MsgOptionText(fmt.Sprintf("Running `%s`... I'll soon post a message visible to everyone in this channel to share the progress and the result of it.", variantCmdWithArgs), false), ) if err != nil { fmt.Printf("async response 1 error: %v", err) @@ -299,7 +302,7 @@ func (conn *Connection) Run() error { return } - res := conn.HandleSlashCommand(conn, c, cmd) + res := conn.HandleSlashCommand(conn, variantCmdWithArgs, cmd) fmt.Printf("async slash command run finished: %s\n", res) diff --git a/slack.go b/slack.go index 4478776..a333e9d 100644 --- a/slack.go +++ b/slack.go @@ -63,15 +63,22 @@ func (r *Runner) StartSlackbot(name string) error { callbackID := message.UserID + "_" + message.TriggerID dialog := slack.Dialog{ - Title: cmd, - SubmitLabel: "Run", - CallbackID: callbackID, - Elements: elems, + Title: cmd, + SubmitLabel: "Run", + CallbackID: callbackID, + Elements: elems, + NotifyOnCancel: true, } done := make(chan error, 1) bot.RegisterInteractionCallbackHandler(callbackID, func(callback slack.InteractionCallback) (interface{}, error) { + if callback.Type == slack.InteractionTypeDialogCancellation { + done <- nil + + return nil, nil + } + if callback.Type != slack.InteractionTypeDialogSubmission { return nil, fmt.Errorf("unexpected type of interaction callback: want %s, got %s", slack.InteractionTypeDialogSubmission, callback.Type) }