The widely used Go SDK github.com/slack-go/slack ) Now supports socket mode: tada: @ mumoshu and @ kanata2's great work: clap:
https://github.com/slack-go/slack
In this article, I'll show you how to use this Go SDK to run the same sample app that you used in Easy Getting Started with Slack Socket Mode.
The sample presented here works with v0.8.0 and above.
go mod init socket-mode-app
go get github.com/slack-go/[email protected]
For the time being, please copy and paste the following source code as it is.
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:
//Event API handling
//Ack for the time being within 3 seconds
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(event.Text, "Hello") {
_, _, err := webApi.PostMessage(
event.Channel,
slack.MsgOptionText(
fmt.Sprintf(":wave:Hello<@%v>San!", 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:
//Shortcut handling and modal activation
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",
"Task registration",
false,
false,
),
Submit: slack.NewTextBlockObject(
"plain_text",
"Send",
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",
false,
false,
),
// multiline is not yet supported
slack.NewPlainTextInputBlockElement(
slack.NewTextBlockObject(
"plain_text",
"Please write the details and deadline of the task",
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:
//Handling transmissions from modals
if payload.CallbackID == "modal-id" {
socketMode.Debugf("Submitted Data: %v", payload.View.State.Values)
socketMode.Ack(*envelope.Request)
}
default:
socketMode.Debugf("Skipped: %v", payload)
}
default:
socketMode.Debugf("Skipped: %v", envelope.Type)
}
}
}()
socketMode.Run()
}
As in the previous article, let's set the environment variables and start it.
export SLACK_APP_TOKEN=xapp-<Value of my token>
export SLACK_BOT_TOKEN=xoxb-<Value of my token>
go run main.go
If you see a message like the one below, you are connected!
$ go run main.go
api: 2021/01/19 15:41:48 slack.go:125: Challenging auth...
sm: 2021/01/19 15:41:48 socket_mode_managed_conn.go:241: Starting SocketMode
sm: 2021/01/19 15:41:48 main.go:133: Skipped: connecting
api: 2021/01/19 15:41:48 socket_mode.go:30: Using URL: wss://wss-primary.slack.com/link/?ticket=xxx&app_id=yyy
sm: 2021/01/19 15:41:48 socket_mode_managed_conn.go:249: Dialing to websocket on url wss://wss-primary.slack.com/link/?ticket=xxx&app_id=yyy
sm: 2021/01/19 15:41:49 socket_mode_managed_conn.go:78: WebSocket connection succeeded on try 0
sm: 2021/01/19 15:41:49 socket_mode_managed_conn.go:422: Starting to receive message
sm: 2021/01/19 15:41:49 main.go:133: Skipped: connected
sm: 2021/01/19 15:41:49 socket_mode_managed_conn.go:464: Incoming WebSocket message: {
"type": "hello",
"num_connections": 1,
"debug_info": {
"host": "applink-xxx-yyy",
"build_number": 10,
"approximate_connection_time": 18060
},
"connection_info": {
"app_id": "A111"
}
}
sm: 2021/01/19 15:41:49 socket_mode_managed_conn.go:476: Finished to receive message
sm: 2021/01/19 15:41:49 socket_mode_managed_conn.go:422: Starting to receive message
sm: 2021/01/19 15:41:49 socket_mode_managed_conn.go:319: Received WebSocket message: {"type":"hello","num_connections":1,"debug_info":{"host":"applink-xxx-yyy","build_number":10,"approximate_connection_time":18060},"connection_info":{"app_id":"A111"}}
sm: 2021/01/19 15:41:49 main.go:133: Skipped: hello
sm: 2021/01/19 15:41:51 socket_mode_managed_conn.go:544: WebSocket ping message received: Ping from applink-xxx-yyy
The official sample code can be found at the following location, so please check it out.
https://github.com/slack-go/slack/tree/master/examples/socketmode
Recommended Posts