Skip to content

Instantly share code, notes, and snippets.

@percybolmer
Created August 10, 2021 21:02
Show Gist options
  • Save percybolmer/a3e2e7adbb439cffd1dd816bc502b83a to your computer and use it in GitHub Desktop.
Save percybolmer/a3e2e7adbb439cffd1dd816bc502b83a to your computer and use it in GitHub Desktop.
func main() {
// Load Env variables from .dot file
godotenv.Load(".env")
token := os.Getenv("SLACK_AUTH_TOKEN")
appToken := os.Getenv("SLACK_APP_TOKEN")
// Create a new client to slack by giving token
// Set debug to true while developing
// Also add a ApplicationToken option to the client
client := slack.New(token, slack.OptionDebug(true), slack.OptionAppLevelToken(appToken))
// go-slack comes with a SocketMode package that we need to use that accepts a Slack client and outputs a Socket mode client instead
socketClient := socketmode.New(
client,
socketmode.OptionDebug(true),
// Option to set a custom logger
socketmode.OptionLog(log.New(os.Stdout, "socketmode: ", log.Lshortfile|log.LstdFlags)),
)
// Create a context that can be used to cancel goroutine
ctx, cancel := context.WithCancel(context.Background())
// Make this cancel called properly in a real program , graceful shutdown etc
defer cancel()
go func(ctx context.Context, client *slack.Client, socketClient *socketmode.Client) {
// Create a for loop that selects either the context cancellation or the events incomming
for {
select {
// inscase context cancel is called exit the goroutine
case <-ctx.Done():
log.Println("Shutting down socketmode listener")
return
case event := <-socketClient.Events:
// We have a new Events, let's type switch the event
// Add more use cases here if you want to listen to other events.
switch event.Type {
// handle EventAPI events
case socketmode.EventTypeEventsAPI:
// The Event sent on the channel is not the same as the EventAPI events so we need to type cast it
eventsAPIEvent, ok := event.Data.(slackevents.EventsAPIEvent)
if !ok {
log.Printf("Could not type cast the event to the EventsAPIEvent: %v\n", event)
continue
}
// We need to send an Acknowledge to the slack server
socketClient.Ack(*event.Request)
// Now we have an Events API event, but this event type can in turn be many types, so we actually need another type switch
err := handleEventMessage(eventsAPIEvent, client)
if err != nil {
// Replace with actual err handeling
log.Fatal(err)
}
// Handle Slash Commands
case socketmode.EventTypeSlashCommand:
// Just like before, type cast to the correct event type, this time a SlashEvent
command, ok := event.Data.(slack.SlashCommand)
if !ok {
log.Printf("Could not type cast the message to a SlashCommand: %v\n", command)
continue
}
// Dont forget to acknowledge the request
socketClient.Ack(*event.Request)
// handleSlashCommand will take care of the command
err := handleSlashCommand(command, client)
if err != nil {
log.Fatal(err)
}
}
}
}
}(ctx, client, socketClient)
socketClient.Run()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment