New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Socketmode Middleware Design Pattern #904
Merged
+1,020
−32
Merged
Changes from all commits
Commits
Show all changes
38 commits
Select commit
Hold shift + click to select a range
54bd12b
feat(slacktest): add handler for reaction.Add
xNok 3178aab
feat: basic stucture
xNok 65335cf
feat: socketmode Event Handling
xNok 1dbd284
feat: handle all type of EventTypeInteractive
xNok 6d8be03
feat: handler EventAPI inner events
xNok 03e47e9
test: write unit tests
xNok 2c8000f
feat: added type for SocketmodeMiddlewareFunc
xNok 357e374
fix: typos
xNok e976c8a
fix: typos
xNok b1318d9
feat: Handle interaction block action by action ID
xNok 28ed51b
fix: tests for socketmode
xNok 5ceeab8
Merge branch 'master' into socketmode-handler
xNok 2710f4e
Merge branch 'master' into socketmode-handler
xNok 16e7557
fix: linting issue
xNok 6410dfe
feat: dedicated handler for Slash commands
xNok e8ecf5e
fix: exemple
xNok 9bc8016
fix: initialization controller
xNok 9163026
fix: typo in example file
xNok dd086ec
refact: use client logger
xNok 02281d1
refact: panic instead of os.Exit(1)
xNok cf9dd14
refact: rename HandleEventsAPI to HandleEvents
xNok fb69306
fix: rename action_id to actionID
xNok 430c14a
refact: rename EventAPIType to EventsAPIType
xNok 670527f
refact: update godoc
xNok 296bd7e
refact: change the type of socketmode.apiClient from a non-pointer to…
xNok 9bd9782
refact: RunEventLoop return errors that occured
xNok 20e09d5
refact: rename file to socketmode_handler
xNok 01e7385
refact: use socketmode client's logger.
xNok c965498
refact: rename block_actions to blockActions
xNok 0273c6d
fix: side effect
xNok 7a1949e
refact: use client logger
xNok 38427ff
refact: must register unique action_id or slash commands
xNok c062aee
fix: typo
xNok 6609fd5
Merge branch 'master' into socketmode-handler
xNok 2135a67
fix: compatibility with access to Slack client in socketmode
xNok d06a99b
doc: socketmode handler
xNok b11c9d1
fix: trailing whitespace
xNok 2a3c452
Merge branch 'master' into socketmode-handler
kanata2 File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missed EventsAPIType^^