Waylon  Bruen

Waylon Bruen

1646908560

Go-chat-bot: IRC, Slack & Telegram Bot Written in Go

go-bot

IRC, Slack & Telegram bot written in Go using go-ircevent for IRC connectivity, nlopes/slack for Slack and Syfaro/telegram-bot-api for Telegram.

2016-01-17 11 21 38 036

Plugins

Please see the plugins repository for a complete list of plugins.

You can also write your own, it's really simple.

Compiling and testing the bot and plugins (Debug)

This project uses the new Go 1.11 modules if you have Go 1.11 installed, just clone the project and follow the instructions bellow, when you build Go will automatically download all dependencies.

To test the bot, use the debug console app.

  • Clone this repository or use go get github.com/go-chat-bot/bot
  • Build everything: go build ./...
  • Build and execute the debug app:
    • cd debug
    • go build
    • ./debug
  • This will open a console where you can type commands
  • Type !help to see the list of available commands

Testing your plugin

  • Add your plugin to debug/main.go import list
  • Build the debug app
  • Execute it and test with the interactive console

Protocols

Slack

To deploy your go-bot to Slack, you need to:

  • Create a new bot user integration on Slack and get your token
  • Import the package github.com/go-chat-bot/bot/slack
  • Import the commands you would like to use
  • Call slack.Run(token)

Here is a full example reading the Slack token from the SLACK_TOKEN env var:

package main

import (
    "os"

    "github.com/go-chat-bot/bot/slack"
    _ "github.com/go-chat-bot/plugins/catfacts"
    _ "github.com/go-chat-bot/plugins/catgif"
    _ "github.com/go-chat-bot/plugins/chucknorris"
    // Import all the commands you wish to use
)

func main() {
    slack.Run(os.Getenv("SLACK_TOKEN"))
}

IRC

To deploy your own go-bot to IRC, you need to:

  • Import the package github.com/go-chat-bot/bot/irc
  • Import the commands you would like to use
  • Fill the Config struct
  • Call irc.Run(config)

Here is a full example:

package main

import (
    "github.com/go-chat-bot/bot/irc"
    _ "github.com/go-chat-bot/plugins/catfacts"
    _ "github.com/go-chat-bot/plugins/catgif"
    _ "github.com/go-chat-bot/plugins/chucknorris"
    // Import all the commands you wish to use
    "os"
    "strings"
)

func main() {
    irc.Run(&irc.Config{
        Server:   os.Getenv("IRC_SERVER"),
        Channels: strings.Split(os.Getenv("IRC_CHANNELS"), ","),
        User:     os.Getenv("IRC_USER"),
        Nick:     os.Getenv("IRC_NICK"),
        Password: os.Getenv("IRC_PASSWORD"),
        UseTLS:   true,
        Debug:    os.Getenv("DEBUG") != "",})
}

To join channels with passwords just put the password after the channel name separated by a space:

Channels: []string{"#mychannel mypassword", "#go-bot"}

Telegram

To deploy your go-bot to Telegram, you need to:

  • Follow Telegram instructions to create a new bot user and get your token
  • Import the package github.com/go-chat-bot/bot/telegram
  • Import the commands you would like to use
  • Call telegram.Run(token, debug)

Here is a full example reading the telegram token from the TELEGRAM_TOKEN env var:

package main

import (
    "os"

    "github.com/go-chat-bot/bot/telegram"
    _ "github.com/go-chat-bot/plugins/catfacts"
    _ "github.com/go-chat-bot/plugins/catgif"
    _ "github.com/go-chat-bot/plugins/chucknorris"
    // Import all the commands you wish to use
)

func main() {
    telegram.Run(os.Getenv("TELEGRAM_TOKEN"), os.Getenv("DEBUG") != "")
}

Rocket.chat

To deploy your go-bot to Rocket.chat, you need to:

  • Import the package github.com/go-chat-bot/bot/rocket
  • Import the commands you would like to use
  • Call rocket.Run(config)

Here is a full example:

package main

import (
    "os"

    "github.com/go-chat-bot/bot/rocket"
    _ "github.com/go-chat-bot/plugins/godoc"
    _ "github.com/go-chat-bot/plugins/catfacts"
    _ "github.com/go-chat-bot/plugins/catgif"
    _ "github.com/go-chat-bot/plugins/chucknorris"
)

func main() {
    config := &rocket.Config{
        Server:   os.Getenv("ROCKET_SERVER"),
        Port:     os.Getenv("ROCKET_PORT"),
        User:     os.Getenv("ROCKET_USER"),
        Email:    os.Getenv("ROCKET_EMAIL"),
        Password: os.Getenv("ROCKET_PASSWORD"),
        UseTLS:   false,
        Debug:    os.Getenv("DEBUG") != "",
    }
    rocket.Run(config)
}

Google Chat

To deploy your go-bot to Google Chat (also known as Hangouts Chat, not plain Hangouts) you will first need to follow documentation to setup pub/sub project in Google Cloud. This will enable your bot to receive messages even when it is behind a firewall.

Condensed, the steps you will need to take are as follows:

  • Create new project in google cloud console
    • ID of the project will be used in Config.PubSubProject
  • Create service credentials for this project
    • Path to downloaded credentials file should be in env variable GOOGLE_APPLICATION_CREDENTIALS
    • Choose "Pub/Sub Editor" role for the credential
  • Enable Pub/Sub API in cloud console
  • Create new topic in the Pub/Sub (say "google-chat")
    • Use the value of "Topic Name" (not "Topic ID") for Config.TopicName (e.g. /project//topics/)
  • Modify permissions on created topic so that "chat-api-push@system.gserviceaccount.com" has Pub/Sub Publisher permissions
  • Enable hangouts chat api in Cloud Console
  • Go to hangouts chat API config in the Cloud Console and fill in info
    • Connection settings - use Pub/Sub and fill in topic string you created above

Config.SubscriptionName should be unique for each environment or you'll not process messages correctly. If you encounter issues make sure your credentials are correct and permissions for topics/queues are set up correctly.

Config.WelcomeMessage is sent each time the bot joins a new room or private chat.

Full example is here:

package main

import (
    "os"

    "github.com/go-chat-bot/bot/google-chat"
    _ "github.com/go-chat-bot/plugins/godoc"
    _ "github.com/go-chat-bot/plugins/catfacts"
    _ "github.com/go-chat-bot/plugins/catgif"
    _ "github.com/go-chat-bot/plugins/chucknorris"
)

func main() {
    googlechat.Run(&googlechat.Config{
        PubSubProject:    os.Getenv("HANGOUTS_PROJECT"),
        TopicName:        os.Getenv("HANGOUTS_TOPIC"),
        SubscriptionName: os.Getenv("HANGOUTS_SUB"),
        WelcomeMessage:   os.Getenv("HANGOUTS_WELCOME"),
}

Deploying your own bot

To see an example project on how to deploy your bot, please see my own configuration:

Author: Go-chat-bot
Source Code: https://github.com/go-chat-bot/bot 
License: MIT License

#go #golang #bot 

What is GEEK

Buddha Community

Go-chat-bot: IRC, Slack & Telegram Bot Written in Go
Zachary Palmer

Zachary Palmer

1555901576

CSS Flexbox Tutorial | Build a Chat Application

Creating the conversation sidebar and main chat section

In this article we are going to focus on building a basic sidebar, and the main chat window inside our chat shell. See below.

Chat shell with a fixed width sidebar and expanded chat window

This is the second article in this series. You can check out the previous article for setting up the shell OR you can just check out the chat-shell branch from the following repository.

https://github.com/lyraddigital/flexbox-chat-app.git

Open up the chat.html file. You should have the following HTML.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Chat App</title>
    <link rel="stylesheet" type="text/css" media="screen" href="css/chat.css" />
</head>
<body>
    <div id="chat-container">
    </div>
</body>
</html>

Now inside of the chat-container div add the following HTML.

<div id="side-bar">
</div>
<div id="chat-window">
</div>

Now let’s also add the following CSS under the #chat-container selector in the chat.css file.

#side-bar {
    background: #0048AA;
    border-radius: 10px 0 0 10px;
}
#chat-window {
    background: #999;
    border-radius: 0 10px 10px 0;
}

Now reload the page. You should see the following:-

So what happened? Where is our sidebar and where is our chat window? I expected to see a blue side bar and a grey chat window, but it’s no where to be found. Well it’s all good. This is because we have no content inside of either element, so it can be 0 pixels wide.

Sizing Flex Items

So now that we know that our items are 0 pixels wide, let’s attempt to size them. We’ll attempt to try this first using explicit widths.

Add the following width property to the #side-bar rule, then reload the page.

width: 275px;

Hmm. Same result. It’s still a blank shell. Oh wait I have to make sure the height is 100% too. So we better do that too. Once again add the following property to the #side-bar rule, then reload the page.

height: 100%;

So now we have our sidebar that has grown to be exactly 275 pixels wide, and is 100% high. So that’s it. We’re done right? Wrong. Let me ask you a question. How big is the chat window? Let’s test that by adding some text to it. Try this yourself just add some text. You should see something similar to this.

So as you can see the chat window is only as big as the text that’s inside of it, and it is not next to the side bar. And this makes sense because up until now the chat shell is not a flex container, and just a regular block level element.

So let’s make our chat shell a flex container. Set the following display property for the #chat-window selector. Then reload the page.

display: flex;

So as you can see by the above illustration, we can see it’s now next to the side bar, and not below it. But as you can see currently it’s only as wide as the text that’s inside of it.

But we want it to take up the remaining space of the chat shell. Well we know how to do this, as we did it in the previous article. Set the flex-grow property to 1 on the #chat-window selector. Basically copy and paste the property below and reload the page.

flex-grow: 1;

So now we have the chat window taking up the remaining space of the chat shell. Next, let’s remove the background property, and also remove all text inside the chat-window div if any still exists. You should now see the result below.

But are we done? Technically yes, but before we move on, let’s improve things a little bit.

Understanding the default alignment

If you remember, before we had defined our chat shell to be a flex container, we had to make sure we set the height of the side bar to be 100%. Otherwise it was 0 pixels high, and as a result nothing was displayed. With that said, try removing the height property from the #side-bar selector and see what happens when you reload the page. Yes that’s right, it still works. The height of the sidebar is still 100% high.

So what happened here? Why do we no longer have to worry about setting the height to 100%? Well this is one of the cool things Flexbox gives you for free. By default every flex item will stretch vertically to fill in the entire height of the flex container. We can in fact change this behaviour, and we will see how this is done in a future article.

Setting the size of the side bar properly

So another feature of Flexbox is being able to set the size of a flex item by using the flex-basis property. The flex-basis property allows you to specify an initial size of a flex item, before any growing or shrinking takes place. We’ll understand more about this in an upcoming article.

For now I just want you to understand one important thing. And that is using width to specify the size of the sidebar is not a good idea. Let’s see why.

Say that potentially, if the screen is mobile we want the side bar to now appear across the top of the chat shell, acting like a top bar instead. We can do this by changing the direction flex items can flex inside a flex container. For example, add the following CSS to the #chat-container selector. Then reload the page.

flex-direction: column;

So as you can see we are back to a blank shell. So firstly let’s understand what we actually did here. By setting the flex-direction property to column, we changed the direction of how the flex items flex. By default flex items will flex from left to right. However when we set flex-direction to column, it changes this behaviour forcing flex items to flex from top to bottom instead. On top of this, when the direction of flex changes, the sizing and alignment of flex items changes as well.

When flexing from left to right, we get a height of 100% for free as already mentioned, and then we made sure the side bar was set to be 275 pixels wide, by setting the width property.

However now that we a flexing from top to bottom, the width of the flex item by default would be 100% wide, and you would need to specify the height instead. So try this. Add the following property to the #side-bar selector to set the height of the side bar. Then reload the page.

height: 275px;

Now we are seeing the side bar again, as we gave it a fixed height too. But we still have that fixed width. That’s not what we wanted. We want the side bar (ie our new top bar) here to now be 100% wide. Comment out the width for a moment and reload the page again.

So now we were able to move our side bar so it appears on top instead, acting like a top bar. Which as previously mentioned might be suited for mobile device widths. But to do this we had to swap the value of width to be the value of height. Wouldn’t it be great if this size was preserved regardless of which direction our items are flexing.

Try this, remove all widths and height properties from the #side-bar selector and write the following instead. Then reload the page.

flex-basis: 275px;

As you can see we get the same result. Now remove the flex-direction property from the #chat-container selector. Then once again reload the page.

Once again we are back to our final output. But now we also have the flexibility to easily change the side bar to be a top bar if we need to, by just changing the direction items can flow. Regardless of the direction of flex, the size of our side bar / top bar is preserved.

Conclusion

Ok so once again we didn’t build much, but we did cover a lot of concepts about Flexbox around sizing. 

#css #programming #webdev 

Elian  Harber

Elian Harber

1655540400

Bot: IRC, Slack, Telegram and RocketChat Bot Written in Go

go-bot

IRC, Slack & Telegram bot written in Go using go-ircevent for IRC connectivity, nlopes/slack for Slack and Syfaro/telegram-bot-api for Telegram.

2016-01-17 11 21 38 036

Compiling and testing the bot and plugins (Debug)

This project uses the new Go 1.11 modules if you have Go 1.11 installed, just clone the project and follow the instructions bellow, when you build Go will automatically download all dependencies.

To test the bot, use the debug console app.

  • Clone this repository or use go get github.com/go-chat-bot/bot
  • Build everything: go build ./...
  • Build and execute the debug app:
    • cd debug
    • go build
    • ./debug
  • This will open a console where you can type commands
  • Type !help to see the list of available commands

Testing your plugin

  • Add your plugin to debug/main.go import list
  • Build the debug app
  • Execute it and test with the interactive console

Protocols

Slack

To deploy your go-bot to Slack, you need to:

  • Create a new bot user integration on Slack and get your token
  • Import the package github.com/go-chat-bot/bot/slack
  • Import the commands you would like to use
  • Call slack.Run(token)

Here is a full example reading the Slack token from the SLACK_TOKEN env var:

package main

import (
    "os"

    "github.com/go-chat-bot/bot/slack"
    _ "github.com/go-chat-bot/plugins/catfacts"
    _ "github.com/go-chat-bot/plugins/catgif"
    _ "github.com/go-chat-bot/plugins/chucknorris"
    // Import all the commands you wish to use
)

func main() {
    slack.Run(os.Getenv("SLACK_TOKEN"))
}

IRC

To deploy your own go-bot to IRC, you need to:

  • Import the package github.com/go-chat-bot/bot/irc
  • Import the commands you would like to use
  • Fill the Config struct
  • Call irc.Run(config)

Here is a full example:

package main

import (
    "github.com/go-chat-bot/bot/irc"
    _ "github.com/go-chat-bot/plugins/catfacts"
    _ "github.com/go-chat-bot/plugins/catgif"
    _ "github.com/go-chat-bot/plugins/chucknorris"
    // Import all the commands you wish to use
    "os"
    "strings"
)

func main() {
    irc.Run(&irc.Config{
        Server:   os.Getenv("IRC_SERVER"),
        Channels: strings.Split(os.Getenv("IRC_CHANNELS"), ","),
        User:     os.Getenv("IRC_USER"),
        Nick:     os.Getenv("IRC_NICK"),
        Password: os.Getenv("IRC_PASSWORD"),
        UseTLS:   true,
        Debug:    os.Getenv("DEBUG") != "",})
}

To join channels with passwords just put the password after the channel name separated by a space:

Channels: []string{"#mychannel mypassword", "#go-bot"}

Telegram

To deploy your go-bot to Telegram, you need to:

  • Follow Telegram instructions to create a new bot user and get your token
  • Import the package github.com/go-chat-bot/bot/telegram
  • Import the commands you would like to use
  • Call telegram.Run(token, debug)

Here is a full example reading the telegram token from the TELEGRAM_TOKEN env var:

package main

import (
    "os"

    "github.com/go-chat-bot/bot/telegram"
    _ "github.com/go-chat-bot/plugins/catfacts"
    _ "github.com/go-chat-bot/plugins/catgif"
    _ "github.com/go-chat-bot/plugins/chucknorris"
    // Import all the commands you wish to use
)

func main() {
    telegram.Run(os.Getenv("TELEGRAM_TOKEN"), os.Getenv("DEBUG") != "")
}

Rocket.chat

To deploy your go-bot to Rocket.chat, you need to:

  • Import the package github.com/go-chat-bot/bot/rocket
  • Import the commands you would like to use
  • Call rocket.Run(config)

Here is a full example:

package main

import (
    "os"

    "github.com/go-chat-bot/bot/rocket"
    _ "github.com/go-chat-bot/plugins/godoc"
    _ "github.com/go-chat-bot/plugins/catfacts"
    _ "github.com/go-chat-bot/plugins/catgif"
    _ "github.com/go-chat-bot/plugins/chucknorris"
)

func main() {
    config := &rocket.Config{
        Server:   os.Getenv("ROCKET_SERVER"),
        Port:     os.Getenv("ROCKET_PORT"),
        User:     os.Getenv("ROCKET_USER"),
        Email:    os.Getenv("ROCKET_EMAIL"),
        Password: os.Getenv("ROCKET_PASSWORD"),
        UseTLS:   false,
        Debug:    os.Getenv("DEBUG") != "",
    }
    rocket.Run(config)
}

Google Chat

To deploy your go-bot to Google Chat (also known as Hangouts Chat, not plain Hangouts) you will first need to follow documentation to setup pub/sub project in Google Cloud. This will enable your bot to receive messages even when it is behind a firewall.

Condensed, the steps you will need to take are as follows:

  • Create new project in google cloud console
    • ID of the project will be used in Config.PubSubProject
  • Create service credentials for this project
    • Path to downloaded credentials file should be in env variable GOOGLE_APPLICATION_CREDENTIALS
    • Choose "Pub/Sub Editor" role for the credential
  • Enable Pub/Sub API in cloud console
  • Create new topic in the Pub/Sub (say "google-chat")
    • Use the value of "Topic Name" (not "Topic ID") for Config.TopicName (e.g. /project//topics/)
  • Modify permissions on created topic so that "chat-api-push@system.gserviceaccount.com" has Pub/Sub Publisher permissions
  • Enable hangouts chat api in Cloud Console
  • Go to hangouts chat API config in the Cloud Console and fill in info
    • Connection settings - use Pub/Sub and fill in topic string you created above

Config.SubscriptionName should be unique for each environment or you'll not process messages correctly. If you encounter issues make sure your credentials are correct and permissions for topics/queues are set up correctly.

Config.WelcomeMessage is sent each time the bot joins a new room or private chat.

Full example is here:

package main

import (
    "os"

    "github.com/go-chat-bot/bot/google-chat"
    _ "github.com/go-chat-bot/plugins/godoc"
    _ "github.com/go-chat-bot/plugins/catfacts"
    _ "github.com/go-chat-bot/plugins/catgif"
    _ "github.com/go-chat-bot/plugins/chucknorris"
)

func main() {
    googlechat.Run(&googlechat.Config{
        PubSubProject:    os.Getenv("HANGOUTS_PROJECT"),
        TopicName:        os.Getenv("HANGOUTS_TOPIC"),
        SubscriptionName: os.Getenv("HANGOUTS_SUB"),
        WelcomeMessage:   os.Getenv("HANGOUTS_WELCOME"),
}

Deploying your own bot

To see an example project on how to deploy your bot, please see my own configuration:

Plugins

Please see the plugins repository for a complete list of plugins.

You can also write your own, it's really simple.

Author: go-chat-bot
Source Code: https://github.com/go-chat-bot/bot 
License: MIT license

#go #golang #bot #telegram 

Waylon  Bruen

Waylon Bruen

1646908560

Go-chat-bot: IRC, Slack & Telegram Bot Written in Go

go-bot

IRC, Slack & Telegram bot written in Go using go-ircevent for IRC connectivity, nlopes/slack for Slack and Syfaro/telegram-bot-api for Telegram.

2016-01-17 11 21 38 036

Plugins

Please see the plugins repository for a complete list of plugins.

You can also write your own, it's really simple.

Compiling and testing the bot and plugins (Debug)

This project uses the new Go 1.11 modules if you have Go 1.11 installed, just clone the project and follow the instructions bellow, when you build Go will automatically download all dependencies.

To test the bot, use the debug console app.

  • Clone this repository or use go get github.com/go-chat-bot/bot
  • Build everything: go build ./...
  • Build and execute the debug app:
    • cd debug
    • go build
    • ./debug
  • This will open a console where you can type commands
  • Type !help to see the list of available commands

Testing your plugin

  • Add your plugin to debug/main.go import list
  • Build the debug app
  • Execute it and test with the interactive console

Protocols

Slack

To deploy your go-bot to Slack, you need to:

  • Create a new bot user integration on Slack and get your token
  • Import the package github.com/go-chat-bot/bot/slack
  • Import the commands you would like to use
  • Call slack.Run(token)

Here is a full example reading the Slack token from the SLACK_TOKEN env var:

package main

import (
    "os"

    "github.com/go-chat-bot/bot/slack"
    _ "github.com/go-chat-bot/plugins/catfacts"
    _ "github.com/go-chat-bot/plugins/catgif"
    _ "github.com/go-chat-bot/plugins/chucknorris"
    // Import all the commands you wish to use
)

func main() {
    slack.Run(os.Getenv("SLACK_TOKEN"))
}

IRC

To deploy your own go-bot to IRC, you need to:

  • Import the package github.com/go-chat-bot/bot/irc
  • Import the commands you would like to use
  • Fill the Config struct
  • Call irc.Run(config)

Here is a full example:

package main

import (
    "github.com/go-chat-bot/bot/irc"
    _ "github.com/go-chat-bot/plugins/catfacts"
    _ "github.com/go-chat-bot/plugins/catgif"
    _ "github.com/go-chat-bot/plugins/chucknorris"
    // Import all the commands you wish to use
    "os"
    "strings"
)

func main() {
    irc.Run(&irc.Config{
        Server:   os.Getenv("IRC_SERVER"),
        Channels: strings.Split(os.Getenv("IRC_CHANNELS"), ","),
        User:     os.Getenv("IRC_USER"),
        Nick:     os.Getenv("IRC_NICK"),
        Password: os.Getenv("IRC_PASSWORD"),
        UseTLS:   true,
        Debug:    os.Getenv("DEBUG") != "",})
}

To join channels with passwords just put the password after the channel name separated by a space:

Channels: []string{"#mychannel mypassword", "#go-bot"}

Telegram

To deploy your go-bot to Telegram, you need to:

  • Follow Telegram instructions to create a new bot user and get your token
  • Import the package github.com/go-chat-bot/bot/telegram
  • Import the commands you would like to use
  • Call telegram.Run(token, debug)

Here is a full example reading the telegram token from the TELEGRAM_TOKEN env var:

package main

import (
    "os"

    "github.com/go-chat-bot/bot/telegram"
    _ "github.com/go-chat-bot/plugins/catfacts"
    _ "github.com/go-chat-bot/plugins/catgif"
    _ "github.com/go-chat-bot/plugins/chucknorris"
    // Import all the commands you wish to use
)

func main() {
    telegram.Run(os.Getenv("TELEGRAM_TOKEN"), os.Getenv("DEBUG") != "")
}

Rocket.chat

To deploy your go-bot to Rocket.chat, you need to:

  • Import the package github.com/go-chat-bot/bot/rocket
  • Import the commands you would like to use
  • Call rocket.Run(config)

Here is a full example:

package main

import (
    "os"

    "github.com/go-chat-bot/bot/rocket"
    _ "github.com/go-chat-bot/plugins/godoc"
    _ "github.com/go-chat-bot/plugins/catfacts"
    _ "github.com/go-chat-bot/plugins/catgif"
    _ "github.com/go-chat-bot/plugins/chucknorris"
)

func main() {
    config := &rocket.Config{
        Server:   os.Getenv("ROCKET_SERVER"),
        Port:     os.Getenv("ROCKET_PORT"),
        User:     os.Getenv("ROCKET_USER"),
        Email:    os.Getenv("ROCKET_EMAIL"),
        Password: os.Getenv("ROCKET_PASSWORD"),
        UseTLS:   false,
        Debug:    os.Getenv("DEBUG") != "",
    }
    rocket.Run(config)
}

Google Chat

To deploy your go-bot to Google Chat (also known as Hangouts Chat, not plain Hangouts) you will first need to follow documentation to setup pub/sub project in Google Cloud. This will enable your bot to receive messages even when it is behind a firewall.

Condensed, the steps you will need to take are as follows:

  • Create new project in google cloud console
    • ID of the project will be used in Config.PubSubProject
  • Create service credentials for this project
    • Path to downloaded credentials file should be in env variable GOOGLE_APPLICATION_CREDENTIALS
    • Choose "Pub/Sub Editor" role for the credential
  • Enable Pub/Sub API in cloud console
  • Create new topic in the Pub/Sub (say "google-chat")
    • Use the value of "Topic Name" (not "Topic ID") for Config.TopicName (e.g. /project//topics/)
  • Modify permissions on created topic so that "chat-api-push@system.gserviceaccount.com" has Pub/Sub Publisher permissions
  • Enable hangouts chat api in Cloud Console
  • Go to hangouts chat API config in the Cloud Console and fill in info
    • Connection settings - use Pub/Sub and fill in topic string you created above

Config.SubscriptionName should be unique for each environment or you'll not process messages correctly. If you encounter issues make sure your credentials are correct and permissions for topics/queues are set up correctly.

Config.WelcomeMessage is sent each time the bot joins a new room or private chat.

Full example is here:

package main

import (
    "os"

    "github.com/go-chat-bot/bot/google-chat"
    _ "github.com/go-chat-bot/plugins/godoc"
    _ "github.com/go-chat-bot/plugins/catfacts"
    _ "github.com/go-chat-bot/plugins/catgif"
    _ "github.com/go-chat-bot/plugins/chucknorris"
)

func main() {
    googlechat.Run(&googlechat.Config{
        PubSubProject:    os.Getenv("HANGOUTS_PROJECT"),
        TopicName:        os.Getenv("HANGOUTS_TOPIC"),
        SubscriptionName: os.Getenv("HANGOUTS_SUB"),
        WelcomeMessage:   os.Getenv("HANGOUTS_WELCOME"),
}

Deploying your own bot

To see an example project on how to deploy your bot, please see my own configuration:

Author: Go-chat-bot
Source Code: https://github.com/go-chat-bot/bot 
License: MIT License

#go #golang #bot 

Nigel  Uys

Nigel Uys

1652942940

Slack: Slack API in Go

Slack API in Go 

This is the original Slack library for Go created by Norberto Lopes, transferred to a GitHub organization.

You can also chat with us on the #slack-go, #slack-go-ja Slack channel on the Gophers Slack.

This library supports most if not all of the api.slack.com REST calls, as well as the Real-Time Messaging protocol over websocket, in a fully managed way.

Project Status

There is currently no major version released. Therefore, minor version releases may include backward incompatible changes.

See CHANGELOG.md or Releases for more information about the changes.

Installing

go get

$ go get -u github.com/slack-go/slack

Example

Getting all groups

import (
    "fmt"

    "github.com/slack-go/slack"
)

func main() {
    api := slack.New("YOUR_TOKEN_HERE")
    // If you set debugging, it will log all requests to the console
    // Useful when encountering issues
    // slack.New("YOUR_TOKEN_HERE", slack.OptionDebug(true))
    groups, err := api.GetUserGroups(false)
    if err != nil {
        fmt.Printf("%s\n", err)
        return
    }
    for _, group := range groups {
        fmt.Printf("ID: %s, Name: %s\n", group.ID, group.Name)
    }
}

Getting User Information

import (
    "fmt"

    "github.com/slack-go/slack"
)

func main() {
    api := slack.New("YOUR_TOKEN_HERE")
    user, err := api.GetUserInfo("U023BECGF")
    if err != nil {
        fmt.Printf("%s\n", err)
        return
    }
    fmt.Printf("ID: %s, Fullname: %s, Email: %s\n", user.ID, user.Profile.RealName, user.Profile.Email)
}

Minimal Socket Mode usage:

See https://github.com/slack-go/slack/blob/master/examples/socketmode/socketmode.go

Minimal RTM usage:

As mentioned in https://api.slack.com/rtm - for most applications, Socket Mode is a better way to communicate with Slack.

See https://github.com/slack-go/slack/blob/master/examples/websocket/websocket.go

Minimal EventsAPI usage:

See https://github.com/slack-go/slack/blob/master/examples/eventsapi/events.go

Contributing

You are more than welcome to contribute to this project. Fork and make a Pull Request, or create an Issue if you see any problem.

Before making any Pull Request please run the following:

make pr-prep

This will check/update code formatting, linting and then run all tests

Author: Slack-go
Source Code: https://github.com/slack-go/slack 
License: BSD-2-Clause license

#go #golang #slack 

Elian  Harber

Elian Harber

1655547868

Slacker: Slack Bot Framework

slacker 

Built on top of the Slack API github.com/slack-go/slack with the idea to simplify the Real-Time Messaging feature to easily create Slack Bots, assign commands to them and extract parameters.

Features

  • Supports Slack Apps using Socket Mode
  • Easy definitions of commands and their input
  • Available bot initialization, errors and default handlers
  • Simple parsing of String, Integer, Float and Boolean parameters
  • Contains support for context.Context
  • Built-in help command
  • Replies can be new messages or in threads
  • Supports authorization
  • Bot responds to mentions and direct messages
  • Handlers run concurrently via goroutines
  • Produces events for executed commands
  • Full access to the Slack API github.com/slack-go/slack

Dependencies

Install

go get github.com/shomali11/slacker

Preparing your Slack App

To use Slacker you'll need to create a Slack App, either manually or with an app manifest. The app manifest feature is easier, but is a beta feature from Slack and thus may break/change without much notice.

Manual Steps

Slacker works by communicating with the Slack Events API using the Socket Mode connection protocol.

To get started, you must have or create a Slack App and enable Socket Mode, which will generate your app token (SLACK_APP_TOKEN in the examples) that will be needed to authenticate.

Additionally, you need to subscribe to events for your bot to respond to under the Event Subscriptions section. Common event subscriptions for bots include app_mention or message.im.

After setting up your subscriptions, add scopes necessary to your bot in the OAuth & Permissions. The following scopes are recommended for getting started, though you may need to add/remove scopes depending on your bots purpose:

  • app_mentions:read
  • channels:history
  • chat:write
  • groups:history
  • im:history
  • mpim:history

Once you've selected your scopes install your app to the workspace and navigate back to the OAuth & Permissions section. Here you can retrieve yor bot's OAuth token (SLACK_BOT_TOKEN in the examples) from the top of the page.

With both tokens in hand, you can now proceed with the examples below.

App Manifest

Slack App Manifests make it easy to share a app configurations. We provide a simple manifest that should work with all the examples provided below.

The manifest provided will send all messages in channels your bot is in to the bot (including DMs) and not just ones that actually mention them in the message.

If you wish to only have your bot respond to messages they are directly messaged in, you will need to add the app_mentions:read scope, and remove:

  • im:history # single-person dm
  • mpim:history # multi-person dm
  • channels:history # public channels
  • groups:history # private channels

You'll also need to adjust the event subscriptions, adding app_mention and removing:

  • message.channels
  • message.groups
  • message.im
  • message.mpim

Examples

Example 1

Defining a command using slacker

package main

import (
    "context"
    "log"
    "os"

    "github.com/shomali11/slacker"
)

func main() {
    bot := slacker.NewClient(os.Getenv("SLACK_BOT_TOKEN"), os.Getenv("SLACK_APP_TOKEN"))

    definition := &slacker.CommandDefinition{
        Handler: func(botCtx slacker.BotContext, request slacker.Request, response slacker.ResponseWriter) {
            response.Reply("pong")
        },
    }

    bot.Command("ping", definition)

    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()

    err := bot.Listen(ctx)
    if err != nil {
        log.Fatal(err)
    }
}

Example 2

Defining a command with an optional description and example. The handler replies to a thread.

package main

import (
    "context"
    "log"
    "os"

    "github.com/shomali11/slacker"
)

func main() {
    bot := slacker.NewClient(os.Getenv("SLACK_BOT_TOKEN"), os.Getenv("SLACK_APP_TOKEN"))

    definition := &slacker.CommandDefinition{
        Description: "Ping!",
        Example:     "ping",
        Handler: func(botCtx slacker.BotContext, request slacker.Request, response slacker.ResponseWriter) {
            response.Reply("pong", slacker.WithThreadReply(true))
        },
    }

    bot.Command("ping", definition)

    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()

    err := bot.Listen(ctx)
    if err != nil {
        log.Fatal(err)
    }
}

Example 3

Defining a command with a parameter

package main

import (
    "context"
    "log"
    "os"

    "github.com/shomali11/slacker"
)

func main() {
    bot := slacker.NewClient(os.Getenv("SLACK_BOT_TOKEN"), os.Getenv("SLACK_APP_TOKEN"))

    definition := &slacker.CommandDefinition{
        Description: "Echo a word!",
        Example:     "echo hello",
        Handler: func(botCtx slacker.BotContext, request slacker.Request, response slacker.ResponseWriter) {
            word := request.Param("word")
            response.Reply(word)
        },
    }

    bot.Command("echo <word>", definition)

    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()

    err := bot.Listen(ctx)
    if err != nil {
        log.Fatal(err)
    }
}

Example 4

Defining a command with two parameters. Parsing one as a string and the other as an integer. (The second parameter is the default value in case no parameter was passed or could not parse the value)

package main

import (
    "context"
    "log"
    "os"

    "github.com/shomali11/slacker"
)

func main() {
    bot := slacker.NewClient(os.Getenv("SLACK_BOT_TOKEN"), os.Getenv("SLACK_APP_TOKEN"))

    definition := &slacker.CommandDefinition{
        Description: "Repeat a word a number of times!",
        Example:     "repeat hello 10",
        Handler: func(botCtx slacker.BotContext, request slacker.Request, response slacker.ResponseWriter) {
            word := request.StringParam("word", "Hello!")
            number := request.IntegerParam("number", 1)
            for i := 0; i < number; i++ {
                response.Reply(word)
            }
        },
    }

    bot.Command("repeat <word> <number>", definition)

    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()

    err := bot.Listen(ctx)
    if err != nil {
        log.Fatal(err)
    }
}

Example 5

Defines two commands that display sending errors to the Slack channel. One that replies as a new message. The other replies to the thread.

package main

import (
    "context"
    "errors"
    "log"
    "os"

    "github.com/shomali11/slacker"
)

func main() {
    bot := slacker.NewClient(os.Getenv("SLACK_BOT_TOKEN"), os.Getenv("SLACK_APP_TOKEN"))

    messageReplyDefinition := &slacker.CommandDefinition{
        Description: "Tests errors in new messages",
        Handler: func(botCtx slacker.BotContext, request slacker.Request, response slacker.ResponseWriter) {
            response.ReportError(errors.New("Oops!"))
        },
    }

    threadReplyDefinition := &slacker.CommandDefinition{
        Description: "Tests errors in threads",
        Handler: func(botCtx slacker.BotContext, request slacker.Request, response slacker.ResponseWriter) {
            response.ReportError(errors.New("Oops!"), slacker.WithThreadError(true))
        },
    }

    bot.Command("message", messageReplyDefinition)
    bot.Command("thread", threadReplyDefinition)

    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()

    err := bot.Listen(ctx)
    if err != nil {
        log.Fatal(err)
    }
}

Example 6

Showcasing the ability to access the github.com/slack-go/slack API and upload a file

package main

import (
    "context"
    "fmt"
    "log"
    "os"

    "github.com/shomali11/slacker"
    "github.com/slack-go/slack"
)

func main() {
    bot := slacker.NewClient(os.Getenv("SLACK_BOT_TOKEN"), os.Getenv("SLACK_APP_TOKEN"))

    definition := &slacker.CommandDefinition{
        Description: "Upload a word!",
        Handler: func(botCtx slacker.BotContext, request slacker.Request, response slacker.ResponseWriter) {
            word := request.Param("word")
            client := botCtx.Client()
            ev := botCtx.Event()

            if ev.Channel != "" {
                client.PostMessage(ev.Channel, slack.MsgOptionText("Uploading file ...", false))
                _, err := client.UploadFile(slack.FileUploadParameters{Content: word, Channels: []string{ev.Channel}})
                if err != nil {
                    fmt.Printf("Error encountered when uploading file: %+v\n", err)
                }
            }
        },
    }

    bot.Command("upload <word>", definition)

    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()

    err := bot.Listen(ctx)
    if err != nil {
        log.Fatal(err)
    }
}

Example 7

Showcasing the ability to leverage context.Context to add a timeout

package main

import (
    "context"
    "errors"
    "log"
    "os"
    "time"

    "github.com/shomali11/slacker"
)

func main() {
    bot := slacker.NewClient(os.Getenv("SLACK_BOT_TOKEN"), os.Getenv("SLACK_APP_TOKEN"))

    definition := &slacker.CommandDefinition{
        Description: "Process!",
        Handler: func(botCtx slacker.BotContext, request slacker.Request, response slacker.ResponseWriter) {
            timedContext, cancel := context.WithTimeout(botCtx.Context(), time.Second)
            defer cancel()

            select {
            case <-timedContext.Done():
                response.ReportError(errors.New("timed out"))
            case <-time.After(time.Minute):
                response.Reply("Processing done!")
            }
        },
    }

    bot.Command("process", definition)

    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()

    err := bot.Listen(ctx)
    if err != nil {
        log.Fatal(err)
    }
}

Example 8

Showcasing the ability to add attachments to a Reply

package main

import (
    "context"
    "log"
    "os"

    "github.com/shomali11/slacker"
    "github.com/slack-go/slack"
)

func main() {
    bot := slacker.NewClient(os.Getenv("SLACK_BOT_TOKEN"), os.Getenv("SLACK_APP_TOKEN"))

    definition := &slacker.CommandDefinition{
        Description: "Echo a word!",
        Handler: func(botCtx slacker.BotContext, request slacker.Request, response slacker.ResponseWriter) {
            word := request.Param("word")

            attachments := []slack.Attachment{}
            attachments = append(attachments, slack.Attachment{
                Color:      "red",
                AuthorName: "Raed Shomali",
                Title:      "Attachment Title",
                Text:       "Attachment Text",
            })

            response.Reply(word, slacker.WithAttachments(attachments))
        },
    }

    bot.Command("echo <word>", definition)

    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()

    err := bot.Listen(ctx)
    if err != nil {
        log.Fatal(err)
    }
}

Example 9

Showcasing the ability to add blocks to a Reply

package main

import (
    "context"
    "log"
    "os"

    "github.com/shomali11/slacker"
    "github.com/slack-go/slack"
)

func main() {
    bot := slacker.NewClient(os.Getenv("SLACK_BOT_TOKEN"), os.Getenv("SLACK_APP_TOKEN"))

    definition := &slacker.CommandDefinition{
        Description: "Echo a word!",
        Handler: func(botCtx slacker.BotContext, request slacker.Request, response slacker.ResponseWriter) {
            word := request.Param("word")

            attachments := []slack.Block{}
            attachments = append(attachments, slack.NewContextBlock("1",
                slack.NewTextBlockObject("mrkdwn", "Hi!", false, false)),
            )

            response.Reply(word, slacker.WithBlocks(attachments))
        },
    }

    bot.Command("echo <word>", definition)

    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()

    err := bot.Listen(ctx)
    if err != nil {
        log.Fatal(err)
    }
}

Example 10

Showcasing the ability to create custom responses via CustomResponse

package main

import (
    "context"
    "errors"
    "fmt"
    "log"
    "os"

    "github.com/shomali11/slacker"
    "github.com/slack-go/slack"
)

const (
    errorFormat = "> Custom Error: _%s_"
)

func main() {
    bot := slacker.NewClient(os.Getenv("SLACK_BOT_TOKEN"), os.Getenv("SLACK_APP_TOKEN"))

    bot.CustomResponse(NewCustomResponseWriter)

    definition := &slacker.CommandDefinition{
        Description: "Custom!",
        Handler: func(botCtx slacker.BotContext, request slacker.Request, response slacker.ResponseWriter) {
            response.Reply("custom")
            response.ReportError(errors.New("oops"))
        },
    }

    bot.Command("custom", definition)

    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()

    err := bot.Listen(ctx)
    if err != nil {
        log.Fatal(err)
    }
}

// NewCustomResponseWriter creates a new ResponseWriter structure
func NewCustomResponseWriter(botCtx slacker.BotContext) slacker.ResponseWriter {
    return &MyCustomResponseWriter{botCtx: botCtx}
}

// MyCustomResponseWriter a custom response writer
type MyCustomResponseWriter struct {
    botCtx slacker.BotContext
}

// ReportError sends back a formatted error message to the channel where we received the event from
func (r *MyCustomResponseWriter) ReportError(err error, options ...slacker.ReportErrorOption) {
    defaults := slacker.NewReportErrorDefaults(options...)

    client := r.botCtx.Client()
    event := r.botCtx.Event()

    opts := []slack.MsgOption{
        slack.MsgOptionText(fmt.Sprintf(errorFormat, err.Error()), false),
    }
    if defaults.ThreadResponse {
        opts = append(opts, slack.MsgOptionTS(event.TimeStamp))
    }

    _, _, err = client.PostMessage(event.Channel, opts...)
    if err != nil {
        fmt.Println("failed to report error: %v", err)
    }
}

// Reply send a attachments to the current channel with a message
func (r *MyCustomResponseWriter) Reply(message string, options ...slacker.ReplyOption) error {
    defaults := slacker.NewReplyDefaults(options...)

    client := r.botCtx.Client()
    event := r.botCtx.Event()
    if event == nil {
        return fmt.Errorf("Unable to get message event details")
    }

    opts := []slack.MsgOption{
        slack.MsgOptionText(message, false),
        slack.MsgOptionAttachments(defaults.Attachments...),
        slack.MsgOptionBlocks(defaults.Blocks...),
    }
    if defaults.ThreadResponse {
        opts = append(opts, slack.MsgOptionTS(event.TimeStamp))
    }

    _, _, err := client.PostMessage(
        event.Channel,
        opts...,
    )
    return err
}

Example 11

Showcasing the ability to toggle the slack Debug option via WithDebug

package main

import (
    "context"
    "github.com/shomali11/slacker"
    "log"
    "os"
)

func main() {
    bot := slacker.NewClient(os.Getenv("SLACK_BOT_TOKEN"), os.Getenv("SLACK_APP_TOKEN"))

    definition := &slacker.CommandDefinition{
        Description: "Ping!",
        Handler: func(botCtx slacker.BotContext, request slacker.Request, response slacker.ResponseWriter) {
            response.Reply("pong")
        },
    }

    bot.Command("ping", definition)

    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()

    err := bot.Listen(ctx)
    if err != nil {
        log.Fatal(err)
    }
}

Example 12

Defining a command that can only be executed by authorized users

package main

import (
    "context"
    "log"
    "os"

    "github.com/shomali11/slacker"
)

func main() {
    bot := slacker.NewClient(os.Getenv("SLACK_BOT_TOKEN"), os.Getenv("SLACK_APP_TOKEN"))

    authorizedUsers := []string{"<User ID>"}

    authorizedDefinition := &slacker.CommandDefinition{
        Description: "Very secret stuff",
        AuthorizationFunc: func(botCtx slacker.BotContext, request slacker.Request) bool {
            return contains(authorizedUsers, botCtx.Event().User)
        },
        Handler: func(botCtx slacker.BotContext, request slacker.Request, response slacker.ResponseWriter) {
            response.Reply("You are authorized!")
        },
    }

    bot.Command("secret", authorizedDefinition)

    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()

    err := bot.Listen(ctx)
    if err != nil {
        log.Fatal(err)
    }
}

func contains(list []string, element string) bool {
    for _, value := range list {
        if value == element {
            return true
        }
    }
    return false
}

Example 13

Adding handlers to when the bot is connected, encounters an error and a default for when none of the commands match

package main

import (
    "log"
    "os"

    "context"
    "fmt"

    "github.com/shomali11/slacker"
)

func main() {
    bot := slacker.NewClient(os.Getenv("SLACK_BOT_TOKEN"), os.Getenv("SLACK_APP_TOKEN"))

    bot.Init(func() {
        log.Println("Connected!")
    })

    bot.Err(func(err string) {
        log.Println(err)
    })

    bot.DefaultCommand(func(botCtx slacker.BotContext, request slacker.Request, response slacker.ResponseWriter) {
        response.Reply("Say what?")
    })

    bot.DefaultEvent(func(event interface{}) {
        fmt.Println(event)
    })

    definition := &slacker.CommandDefinition{
        Description: "help!",
        Handler: func(botCtx slacker.BotContext, request slacker.Request, response slacker.ResponseWriter) {
            response.Reply("Your own help function...")
        },
    }

    bot.Help(definition)

    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()

    err := bot.Listen(ctx)
    if err != nil {
        log.Fatal(err)
    }
}

Example 14

Listening to the Commands Events being produced

package main

import (
    "fmt"
    "log"
    "os"

    "context"

    "github.com/shomali11/slacker"
)

func printCommandEvents(analyticsChannel <-chan *slacker.CommandEvent) {
    for event := range analyticsChannel {
        fmt.Println("Command Events")
        fmt.Println(event.Timestamp)
        fmt.Println(event.Command)
        fmt.Println(event.Parameters)
        fmt.Println(event.Event)
        fmt.Println()
    }
}

func main() {
    bot := slacker.NewClient(os.Getenv("SLACK_BOT_TOKEN"), os.Getenv("SLACK_APP_TOKEN"))

    go printCommandEvents(bot.CommandEvents())

    bot.Command("ping", &slacker.CommandDefinition{
        Handler: func(botCtx slacker.BotContext, request slacker.Request, response slacker.ResponseWriter) {
            response.Reply("pong")
        },
    })

    bot.Command("echo <word>", &slacker.CommandDefinition{
        Description: "Echo a word!",
        Example:     "echo hello",
        Handler: func(botCtx slacker.BotContext, request slacker.Request, response slacker.ResponseWriter) {
            word := request.Param("word")
            response.Reply(word)
        },
    })

    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()

    err := bot.Listen(ctx)
    if err != nil {
        log.Fatal(err)
    }
}

Example 15

Slack interaction example

package main

import (
    "context"
    "github.com/shomali11/slacker"
    "github.com/slack-go/slack"
    "github.com/slack-go/slack/socketmode"
    "log"
    "os"
)

func main() {
    bot := slacker.NewClient(os.Getenv("SLACK_BOT_TOKEN"), os.Getenv("SLACK_APP_TOKEN"))

    bot.Interactive(func(s *slacker.Slacker, event *socketmode.Event, callback *slack.InteractionCallback) {
        if callback.Type != slack.InteractionTypeBlockActions {
            return
        }

        if len(callback.ActionCallback.BlockActions) != 1 {
            return
        }

        action := callback.ActionCallback.BlockActions[0]
        if action.BlockID != "mood-block" {
            return
        }

        var text string
        switch action.ActionID {
        case "happy":
            text = "I'm happy to hear you are happy!"
        case "sad":
            text = "I'm sorry to hear you are sad."
        default:
            text = "I don't understand your mood..."
        }

        _, _, _ = s.Client().PostMessage(callback.Channel.ID, slack.MsgOptionText(text, false),
            slack.MsgOptionReplaceOriginal(callback.ResponseURL))

        s.SocketMode().Ack(*event.Request)
    })

    definition := &slacker.CommandDefinition{
        Handler: func(botCtx slacker.BotContext, request slacker.Request, response slacker.ResponseWriter) {
            happyBtn := slack.NewButtonBlockElement("happy", "true", slack.NewTextBlockObject("plain_text", "Happy 🙂", true, false))
            happyBtn.Style = "primary"
            sadBtn := slack.NewButtonBlockElement("sad", "false", slack.NewTextBlockObject("plain_text", "Sad ☹️", true, false))
            sadBtn.Style = "danger"

            err := response.Reply("", slacker.WithBlocks([]slack.Block{
                slack.NewSectionBlock(slack.NewTextBlockObject(slack.PlainTextType, "What is your mood today?", true, false), nil, nil),
                slack.NewActionBlock("mood-block", happyBtn, sadBtn),
            }))
            if err != nil {
                panic(err)
            }
        },
    }

    bot.Command("mood", definition)

    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()

    err := bot.Listen(ctx)
    if err != nil {
        log.Fatal(err)
    }
}

Example 16

Configure bot to process other bot events

package main

import (
        "context"
        "log"
        "os"

        "github.com/shomali11/slacker"
)

func main() {
        bot := slacker.NewClient(
                os.Getenv("SLACK_BOT_TOKEN"),
                os.Getenv("SLACK_APP_TOKEN"),
                slacker.WithBotInteractionMode(slacker.BotInteractionModeIgnoreApp),
        )

        bot.Command("hello", &slacker.CommandDefinition{
                Handler: func(botCtx slacker.BotContext, request slacker.Request, response slacker.ResponseWriter) {
                        response.Reply("hai!")
                },
        })

        ctx, cancel := context.WithCancel(context.Background())
        defer cancel()

        err := bot.Listen(ctx)
        if err != nil {
                log.Fatal(err)
        }
}

Example 17

Override the default event input cleaning function (to sanitize the messages received by Slacker)

package main

import (
        "context"
        "log"
        "os"
    "fmt"
    "strings"

        "github.com/shomali11/slacker"
)

func main() {
    bot := slacker.NewClient(os.Getenv("SLACK_BOT_TOKEN"), os.Getenv("SLACK_APP_TOKEN"), slacker.WithDebug(true))
    bot.CleanEventInput(func(in string) string {
        fmt.Println("My slack bot does not like backticks!")
        return strings.ReplaceAll(in, "`", "")
    })

        bot.Command("my-command", &slacker.CommandDefinition{
                Handler: func(botCtx slacker.BotContext, request slacker.Request, response slacker.ResponseWriter) {
                        response.Reply("it works!")
                },
        })

        ctx, cancel := context.WithCancel(context.Background())
        defer cancel()

        err := bot.Listen(ctx)
        if err != nil {
                log.Fatal(err)
        }
}

Contributing / Submitting an Issue

Please review our Contribution Guidelines if you have found an issue with Slacker or wish to contribute to the project.

Troubleshooting

My bot is not responding to events

There are a few common issues that can cause this:

  • The OAuth (bot) Token may be incorrect. In this case authentication does not fail like it does if the App Token is incorrect, and the bot will simply have no scopes and be unable to respond.
  • Required scopes are missing from the OAuth (bot) Token. Similar to the incorrect OAuth Token, without the necessary scopes, the bot cannot respond.
  • The bot does not have the correct event subscriptions setup, and is not receiving events to respond to.

Author: Shomali11
Source Code: https://github.com/shomali11/slacker 
License: MIT license

#go #golang #slack #chat #bot