Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #904 from xNok/socketmode-handler
Socketmode Middleware Design Pattern
- Loading branch information
Showing
10 changed files
with
1,020 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,205 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
"os" | ||
"strings" | ||
|
||
"github.com/slack-go/slack/slackevents" | ||
"github.com/slack-go/slack/socketmode" | ||
|
||
"github.com/slack-go/slack" | ||
) | ||
|
||
func main() { | ||
appToken := os.Getenv("SLACK_APP_TOKEN") | ||
if appToken == "" { | ||
|
||
} | ||
|
||
if !strings.HasPrefix(appToken, "xapp-") { | ||
panic("SLACK_APP_TOKEN must have the prefix \"xapp-\".") | ||
} | ||
|
||
botToken := os.Getenv("SLACK_BOT_TOKEN") | ||
if botToken == "" { | ||
panic("SLACK_BOT_TOKEN must be set.\n") | ||
} | ||
|
||
if !strings.HasPrefix(botToken, "xoxb-") { | ||
panic("SLACK_BOT_TOKEN must have the prefix \"xoxb-\".") | ||
} | ||
|
||
api := slack.New( | ||
botToken, | ||
slack.OptionDebug(true), | ||
slack.OptionLog(log.New(os.Stdout, "api: ", log.Lshortfile|log.LstdFlags)), | ||
slack.OptionAppLevelToken(appToken), | ||
) | ||
|
||
client := socketmode.New( | ||
api, | ||
socketmode.OptionDebug(true), | ||
socketmode.OptionLog(log.New(os.Stdout, "socketmode: ", log.Lshortfile|log.LstdFlags)), | ||
) | ||
|
||
socketmodeHandler := socketmode.NewSocketmodeHandler(client) | ||
|
||
socketmodeHandler.Handle(socketmode.EventTypeConnecting, middlewareConnecting) | ||
socketmodeHandler.Handle(socketmode.EventTypeConnectionError, middlewareConnectionError) | ||
socketmodeHandler.Handle(socketmode.EventTypeConnected, middlewareConnected) | ||
|
||
//\\ EventTypeEventsAPI //\\ | ||
// Handle all EventsAPI | ||
socketmodeHandler.Handle(socketmode.EventTypeEventsAPI, middlewareEventsAPI) | ||
|
||
// Handle a specific event from EventsAPI | ||
socketmodeHandler.HandleEvents(slackevents.AppMention, middlewareAppMentionEvent) | ||
|
||
//\\ EventTypeInteractive //\\ | ||
// Handle all Interactive Events | ||
socketmodeHandler.Handle(socketmode.EventTypeInteractive, middlewareInteractive) | ||
|
||
// Handle a specific Interaction | ||
socketmodeHandler.HandleInteraction(slack.InteractionTypeBlockActions, middlewareInteractionTypeBlockActions) | ||
|
||
// Handle all SlashCommand | ||
socketmodeHandler.Handle(socketmode.EventTypeSlashCommand, middlewareSlashCommand) | ||
socketmodeHandler.HandleSlashCommand("/rocket", middlewareSlashCommand) | ||
|
||
// socketmodeHandler.HandleDefault(middlewareDefault) | ||
|
||
socketmodeHandler.RunEventLoop() | ||
} | ||
|
||
func middlewareConnecting(evt *socketmode.Event, client *socketmode.Client) { | ||
fmt.Println("Connecting to Slack with Socket Mode...") | ||
} | ||
|
||
func middlewareConnectionError(evt *socketmode.Event, client *socketmode.Client) { | ||
fmt.Println("Connection failed. Retrying later...") | ||
} | ||
|
||
func middlewareConnected(evt *socketmode.Event, client *socketmode.Client) { | ||
fmt.Println("Connected to Slack with Socket Mode.") | ||
} | ||
|
||
func middlewareEventsAPI(evt *socketmode.Event, client *socketmode.Client) { | ||
fmt.Println("middlewareEventsAPI") | ||
eventsAPIEvent, ok := evt.Data.(slackevents.EventsAPIEvent) | ||
if !ok { | ||
fmt.Printf("Ignored %+v\n", evt) | ||
return | ||
} | ||
|
||
fmt.Printf("Event received: %+v\n", eventsAPIEvent) | ||
|
||
client.Ack(*evt.Request) | ||
|
||
switch eventsAPIEvent.Type { | ||
case slackevents.CallbackEvent: | ||
innerEvent := eventsAPIEvent.InnerEvent | ||
switch ev := innerEvent.Data.(type) { | ||
case *slackevents.AppMentionEvent: | ||
fmt.Printf("We have been mentionned in %v", ev.Channel) | ||
_, _, err := client.Client.PostMessage(ev.Channel, slack.MsgOptionText("Yes, hello.", false)) | ||
if err != nil { | ||
fmt.Printf("failed posting message: %v", err) | ||
} | ||
case *slackevents.MemberJoinedChannelEvent: | ||
fmt.Printf("user %q joined to channel %q", ev.User, ev.Channel) | ||
} | ||
default: | ||
client.Debugf("unsupported Events API event received") | ||
} | ||
} | ||
|
||
func middlewareAppMentionEvent(evt *socketmode.Event, client *socketmode.Client) { | ||
|
||
eventsAPIEvent, ok := evt.Data.(slackevents.EventsAPIEvent) | ||
if !ok { | ||
fmt.Printf("Ignored %+v\n", evt) | ||
return | ||
} | ||
|
||
client.Ack(*evt.Request) | ||
|
||
ev, ok := eventsAPIEvent.InnerEvent.Data.(*slackevents.AppMentionEvent) | ||
if !ok { | ||
fmt.Printf("Ignored %+v\n", ev) | ||
return | ||
} | ||
|
||
fmt.Printf("We have been mentionned in %v\n", ev.Channel) | ||
_, _, err := client.Client.PostMessage(ev.Channel, slack.MsgOptionText("Yes, hello.", false)) | ||
if err != nil { | ||
fmt.Printf("failed posting message: %v", err) | ||
} | ||
} | ||
|
||
func middlewareInteractive(evt *socketmode.Event, client *socketmode.Client) { | ||
callback, ok := evt.Data.(slack.InteractionCallback) | ||
if !ok { | ||
fmt.Printf("Ignored %+v\n", evt) | ||
return | ||
} | ||
|
||
fmt.Printf("Interaction received: %+v\n", callback) | ||
|
||
var payload interface{} | ||
|
||
switch callback.Type { | ||
case slack.InteractionTypeBlockActions: | ||
// See https://api.slack.com/apis/connections/socket-implement#button | ||
client.Debugf("button clicked!") | ||
case slack.InteractionTypeShortcut: | ||
case slack.InteractionTypeViewSubmission: | ||
// See https://api.slack.com/apis/connections/socket-implement#modal | ||
case slack.InteractionTypeDialogSubmission: | ||
default: | ||
|
||
} | ||
|
||
client.Ack(*evt.Request, payload) | ||
} | ||
|
||
func middlewareInteractionTypeBlockActions(evt *socketmode.Event, client *socketmode.Client) { | ||
client.Debugf("button clicked!") | ||
} | ||
|
||
func middlewareSlashCommand(evt *socketmode.Event, client *socketmode.Client) { | ||
cmd, ok := evt.Data.(slack.SlashCommand) | ||
if !ok { | ||
fmt.Printf("Ignored %+v\n", evt) | ||
return | ||
} | ||
|
||
client.Debugf("Slash command received: %+v", cmd) | ||
|
||
payload := map[string]interface{}{ | ||
"blocks": []slack.Block{ | ||
slack.NewSectionBlock( | ||
&slack.TextBlockObject{ | ||
Type: slack.MarkdownType, | ||
Text: "foo", | ||
}, | ||
nil, | ||
slack.NewAccessory( | ||
slack.NewButtonBlockElement( | ||
"", | ||
"somevalue", | ||
&slack.TextBlockObject{ | ||
Type: slack.PlainTextType, | ||
Text: "bar", | ||
}, | ||
), | ||
), | ||
), | ||
}} | ||
client.Ack(*evt.Request, payload) | ||
} | ||
|
||
func middlewareDefault(evt *socketmode.Event, client *socketmode.Client) { | ||
// fmt.Fprintf(os.Stderr, "Unexpected event type received: %s\n", evt.Type) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.