Table of Contents

Introduction

Want to learn to build a slack bot using Golang? Not sure where you can start? Here we are to lessen your frustration and ease your struggles. With the help of the go-slack package, we will see how to set up a slack workspace and connect the slack bot with Golang.

In this tutorial, we will mainly focus on setting up and creating a bot that can interact with Slack channels and workspace. The guide is mainly divided into two sections:

  • Slack Set Up: Workspace setup and add a bot app to it
  • Golang Set Up and Installation: Coding part setup in which the bot app will be sending requests to a Go backend via Web Socket, termed Socket Mode in the slack world.

Without further ado, let’s get started with our tutorial: How to develop Slack Bot using Golang.

Create Slack Workspace

Go to slack and click Create a Workspace.

Click Create a Workspace Create Slack Workspace

Add required details, a team or company name, a channel name, and invite other teammates who can interact with the bot.

Want the best? Demand the best! Get the best!
Contact Bacancy and hire Golang developer from us today to meet your product requirements. All you need is our highly skilled Golang experts. Period.

Create Slack Application

Create a Slack application, visit the slack website and select From scratch option.

Create Slack Application from Scratch

Add an application name that will be allowed by Workspace for further use. Create a bot with the application.

Create a bot with the application

Click on Bots; this will redirect to the Help Page, select Add Scopes, and add permissions to the application.

Select Add Scopes

Click on Review Scopes to Add and add four main scopes, which make the bot work with the application.

add four main scopes

Now install the application; if you’re not the owner, then you have to request permission from an Admin.

Install the application

The next step is to select a channel the bot can use to post on as an application.

Select a channel

Click Allow and get the OAuth token and Webhook URL required for the authentication process.

Invite the app to a channel. In my case, I used a channel name slack-bot-golang.

Now, type a command message starting with this /.; now we can invite the bot by typing /invite @NameOfYourbot.

Invite the app to a channel Invite the bot

Basic Golang Set-Up and Installation

Create a new directory where we attach all code further, set up communication with the Slack channel, and write a code with the authentication token.

We use the go-slack package that supports the regular REST API, WebSockets, RTM, and Events, and we use the godotenv package to read environment variables.

go slack package

Develop Slack Bot using Golang

First, create a .env file used to store slack credentials, including channel ID. Find the Token in the web UI where the application is created; channel ID can be found in the UI; go to Get channel details by clicking on the dropdown arrow of the channel.

Slack Bot using Golang Slack auth token

Let’s start coding. Create main.go. Start with connecting to the workspace and post a simple message to check if everything is working.

Next, create a slack attachment, which includes a message that we send to the channel and add some fields to send extra contextual data; it’s totally on us if we want to add this data or not.

// main.go

Copy Text
package main
 
import (
    "fmt"
    "os"
    "time"
 
    "github.com/joho/godotenv"
    "github.com/slack-go/slack"
)
 
func main() {
 
    godotenv.Load(".env")
 
    token := os.Getenv("SLACK_AUTH_TOKEN")
    channelID := os.Getenv("SLACK_CHANNEL_ID")
 
    client := slack.New(token, slack.OptionDebug(true))
    attachment := slack.Attachment{
        Pretext: "Super Bot Message",
        Text:    "some text",
        Color: "4af030",
        Fields: []slack.AttachmentField{
            {
                Title: "Date",
                Value: time.Now().String(),
            },
        },
    }
 
    _, timestamp, err := client.PostMessage(
        channelID,
 
        slack.MsgOptionAttachments(attachment),
    )
 
    if err != nil {
        panic(err)
    }
    fmt.Printf("Message sent at %s", timestamp)
}

Run the below command to execute the program. You can see a new message in the slack channel.

Copy Text
go run main.go
New message in the slack channel

Slack Events API Call

Now, use slack events API and handle events in the Slack channels. Our bot listen to only mentioned events; if anyone mentions the bot, it will receive a triggered event. These events are delivered via WebSocket.

First, we need to activate the section Socket Mode; this allows the bot to connect via WebSocket.

Activate Socket Mode

Now, add Event Subscriptions. Find it in the Features tab, and toggle the button to activate it. Then add the app_mention scope to event subscriptions. This will trigger mentioned new event in the application.

Add Event Subscriptions Subscribe to bot events

The final thing is to generate an application token. Currently, we have a bot token only, but for events, we need an application token.

Go to Settings->Basic Information and scroll down to section App-Level Tokens and click on Generate Tokens and Scope and give a name for your Token.

Basic Information Section Section App Level Tokens

On the app side, we need to add connections:write scope to that token, make sure to save the token by adding it to the .env file as SLACK_APP_TOKEN.

SLACK_APP_TOKEN

To use Socket Mode, add a sub package of slack-go called socketmode.

socketmode

Next, create a new client for the socket mode; with this, we have two clients, one for regular API and one for WebSocket events.

Now connect the WebSocket client by calling socketmode.New and forward the regular client as input and add OptionAppLevelToken to the regular client as is now required to connect to the Socket.

At last, we call socketClient.Run() , which will block and process new WebSocket messages on a channel at socketClient.Events. We Put a for loop that will continuously check for new events and add a type switch to handle different events. We attach a go-routine that will handle incoming messages in the background to listen to new events. And with this, we trigger an event on the EventAPI in Slack.

Copy Text
package main
 
import (
    "context"
    "fmt"
    "log"
    "os"
    "time"
 
    "github.com/joho/godotenv"
    "github.com/slack-go/slack"
    "github.com/slack-go/slack/slackevents"
    "github.com/slack-go/slack/socketmode"
)
 
func main() {
 
    godotenv.Load(".env")
 
    token := os.Getenv("SLACK_AUTH_TOKEN")
    appToken := os.Getenv("SLACK_APP_TOKEN")
 
    client := slack.New(token, slack.OptionDebug(true), slack.OptionAppLevelToken(appToken))
 
    socketClient := socketmode.New(
        client,
        socketmode.OptionDebug(true),
        socketmode.OptionLog(log.New(os.Stdout, "socketmode: ", log.Lshortfile|log.LstdFlags)),
    )
 
    ctx, cancel := context.WithCancel(context.Background())
 
    defer cancel()
 
    go func(ctx context.Context, client *slack.Client, socketClient *socketmode.Client) {
        for {
            select {
            case <-ctx.Done():
                log.Println("Shutting down socketmode listener")
                return
            case event := <-socketClient.Events:
 
                switch event.Type {
        
                case socketmode.EventTypeEventsAPI:
 
                    eventsAPI, ok := event.Data.(slackevents.EventsAPIEvent)
                    if !ok {
                        log.Printf("Could not type cast the event to the EventsAPI: %v\n", event)
                        continue
                    }
 
                    socketClient.Ack(*event.Request)
                    log.Println(eventsAPI)
                }
            }
        }
    }(ctx, client, socketClient)
 
    socketClient.Run()
}

To test, run the program and enter the Slack app or web, and mention by bot by using @yourbotname.

go run main.go

You should be able to see the event being logged in the command line running the bot. The event we get is of the type event_callback, and that contains a payload with the actual event that was performed.

Next, start to implement the HandleEventMessage , which will continue the type switching. We can use the type field to know how to handle the Event. Then we can reach the payload event by using the InnerEvent field.

Copy Text
func HandleEventMessage(event slackevents.EventsAPIEvent, client *slack.Client) error {
    switch event.Type {
 
    case slackevents.CallbackEvent:
 
        innerEvent := event.InnerEvent
 
        switch evnt := innerEvent.Data.(type) {
            err := HandleAppMentionEventToBot(evnt, client)
            if err != nil {
                return err
            }
        }
    default:
        return errors.New("unsupported event type")
    }
    return nil
}

Replace the previous log in the main function that prints the event with the new HandleEventMessage function.

Copy Text
log.Println(eventsAPI)
 
replace with
 
err := HandleEventMessage(eventsAPI, client)
if err != nil {
    log.Fatal(err)
}

We need to make the bot respond to the user who mentioned it.

Next start with logging into the application and adding the users:read scope to the bot token, as we did earlier. After adding the scope to the token, we will create the HandleAppMentionEventToBot function. This function will take a *slackevents.AppMentionEvent and a slack.Client as input so it can respond.

The event contains the user ID in the event.User with which we can fetch user details. The channel response is also available during the event.Channel. The data we need is the actual message the user sent while mentioning, which we can fetch from the event.Text.

Copy Text
func HandleAppMentionEventToBot(event *slackevents.AppMentionEvent, client *slack.Client) error {
 
    user, err := client.GetUserInfo(event.User)
    if err != nil {
        return err
    }
 
    text := strings.ToLower(event.Text)
 
    attachment := slack.Attachment{}
 
    if strings.Contains(text, "hello") || strings.Contains(text, "hi") {
        attachment.Text = fmt.Sprintf("Hello %s", user.Name)
        attachment.Color = "#4af030"
    } else if strings.Contains(text, "weather") {
        attachment.Text = fmt.Sprintf("Weather is sunny today. %s", user.Name)
        attachment.Color = "#4af030"
    } else {
        attachment.Text = fmt.Sprintf("I am good. How are you %s?", user.Name)
        attachment.Color = "#4af030"
    }
    _, _, err = client.PostMessage(event.Channel, slack.MsgOptionAttachments(attachment))
    if err != nil {
        return fmt.Errorf("failed to post message: %w", err)
    }
    return nil
}

Now restart the program and say hello or hi and say something else to see whether it works as expected. You have missed some scope if you get a “missing_scope” error.

Bot Token Scopes

Run the Application

Here is the output of my currently running a bot

Run the Application

Github Repository: Slack Bot Using Golang Example

If you want to visit the source code, please clone the repository and set up the project on your system. You can try playing around with the demo application and explore more.

Here’s the github repository: slack-bot-using-golang-example

Conclusion

I hope the purpose of this tutorial: How to Develop Slack Bot using Golang is served as expected. This is a basic step-by-step guide to get you started with implementing slack bot with the go-slack package. Write us back if you have any questions, suggestions, or feedback. Feel free to clone the repository and play around with the code.

Best Go Programming Tutorials

Explore the fundamentals of Golang

LEARN NOW

Build Your Agile Team

Hire Skilled Developer From Us

solutions@bacancy.com

Your Success Is Guaranteed !

We accelerate the release of digital product and guaranteed their success

We Use Slack, Jira & GitHub for Accurate Deployment and Effective Communication.

How Can We Help You?