Skip to content

Instantly share code, notes, and snippets.

@seratch
Last active August 14, 2023 16:16
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save seratch/f10a868249c5503ac734d7fab6e63960 to your computer and use it in GitHub Desktop.
Save seratch/f10a868249c5503ac734d7fab6e63960 to your computer and use it in GitHub Desktop.
Slack Socket Mode in Go
module socket-mode-app
go 1.15
require github.com/slack-go/slack v0.8.0
go mod init socket-mode-app
go get github.com/slack-go/slack@v0.8.0
vi main.go
export SLACK_APP_TOKEN=xapp-{your own value}
export SLACK_BOT_TOKEN=xoxb-{your own value}
go run main.go
package main
import (
"fmt"
"github.com/slack-go/slack/socketmode"
"log"
"os"
"strings"
"github.com/slack-go/slack"
"github.com/slack-go/slack/slackevents"
)
func main() {
webApi := slack.New(
os.Getenv("SLACK_BOT_TOKEN"),
slack.OptionAppLevelToken(os.Getenv("SLACK_APP_TOKEN")),
slack.OptionDebug(true),
slack.OptionLog(log.New(os.Stdout, "api: ", log.Lshortfile|log.LstdFlags)),
)
socketMode := socketmode.New(
webApi,
socketmode.OptionDebug(true),
socketmode.OptionLog(log.New(os.Stdout, "sm: ", log.Lshortfile|log.LstdFlags)),
)
authTest, authTestErr := webApi.AuthTest()
if authTestErr != nil {
fmt.Fprintf(os.Stderr, "SLACK_BOT_TOKEN is invalid: %v\n", authTestErr)
os.Exit(1)
}
selfUserId := authTest.UserID
go func() {
for envelope := range socketMode.Events {
switch envelope.Type {
case socketmode.EventTypeEventsAPI:
// Events API:
// Acknowledge the eventPayload first
socketMode.Ack(*envelope.Request)
eventPayload, _ := envelope.Data.(slackevents.EventsAPIEvent)
switch eventPayload.Type {
case slackevents.CallbackEvent:
switch event := eventPayload.InnerEvent.Data.(type) {
case *slackevents.MessageEvent:
if event.User != selfUserId &&
strings.Contains(strings.ToLower(event.Text), "hello") {
_, _, err := webApi.PostMessage(
event.Channel,
slack.MsgOptionText(
fmt.Sprintf(":wave: Hi there, <@%v>!", event.User),
false,
),
)
if err != nil {
log.Printf("Failed to reply: %v", err)
}
}
default:
socketMode.Debugf("Skipped: %v", event)
}
default:
socketMode.Debugf("unsupported Events API eventPayload received")
}
case socketmode.EventTypeInteractive:
// Shortcuts:
payload, _ := envelope.Data.(slack.InteractionCallback)
switch payload.Type {
case slack.InteractionTypeShortcut:
if payload.CallbackID == "socket-mode-shortcut" {
socketMode.Ack(*envelope.Request)
modalView := slack.ModalViewRequest{
Type: "modal",
CallbackID: "modal-id",
Title: slack.NewTextBlockObject(
"plain_text",
"New Task",
false,
false,
),
Submit: slack.NewTextBlockObject(
"plain_text",
"Submit",
false,
false,
),
Close: slack.NewTextBlockObject(
"plain_text",
"Cancel",
false,
false,
),
Blocks: slack.Blocks{
BlockSet: []slack.Block{
slack.NewInputBlock(
"input-task",
slack.NewTextBlockObject(
"plain_text",
"Task Description",
false,
false,
),
// multiline is not yet supported
slack.NewPlainTextInputBlockElement(
slack.NewTextBlockObject(
"plain_text",
"Describe the task in detail with its timeline",
false,
false,
),
"input",
),
),
},
},
}
resp, err := webApi.OpenView(payload.TriggerID, modalView)
if err != nil {
log.Printf("Failed to opemn a modal: %v", err)
}
socketMode.Debugf("views.open response: %v", resp)
}
case slack.InteractionTypeViewSubmission:
// View Submission:
if payload.CallbackID == "modal-id" {
socketMode.Debugf("Submitted Data: %v", payload.View.State.Values)
socketMode.Ack(*envelope.Request)
}
default:
// Others
socketMode.Debugf("Skipped: %v", payload)
}
default:
socketMode.Debugf("Skipped: %v", envelope.Type)
}
}
}()
socketMode.Run()
}
@Shadrocks
Copy link

This is outstanding framework, can you provide any additional examples of how to use it? I have it running, but I don't know what to do with it after that?

@seratch
Copy link
Author

seratch commented Feb 4, 2021

Hey @Shadrocks, checking the examples in their repository should be helpful. https://github.com/slack-go/slack/tree/master/examples

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment