11.12.2024

How to build a Slackbot in Python on Ubuntu 20.04.

Creating Slackbot using Python on Ubuntu 20.04:

Intro:

Slack - a corporate messenger, which was designed to improve productivity in your workplaces. With it you will be able to exchange messages, create public or private chats, make calls (voice or video calls), and to integrate with different Slackbots. Slackbot is an application which was designed to interact with users through conversations. It has many functions and options, like: send warnings and messages, launching any tasks.

In our tutorial, to deploy Slackbot  we will use Python and Ubuntu 20.04. Slack has a lot of tools in its own arsenal, in order to help you interact with Python's Application Programming Interface (API) and its integrations.

To test abillities of the Python and Slack API, a CoinBot will be launched, which will be monitoring chat and flip a coin when it will be triggered. After all you can upgrade your bot for more practical purposes and your own ideas.

Blot: In our tutorial, we are using Python.3,  that means that if you will be using versions wich were released earlier, bot won't be able to work.

Preparation:

Everything would work, if you have these elements:

1) Slack on your PC and Workplace (workspace) in which you are going to work. If you don't have one, then you should create one on the official Slack website.
2)Virtual machine or PC with public IP address.

Launching Slackbot

Firstly, let's launch our Slack application in the Slack API Control Panel (SCPAPI). Enter menu of your workplace and after that go to SCPAPI.
Then, click on the "Create an App" menu, as on our screenshot:

Thereafter you will be required to name your app. Our name will be "CoinBot", but your name is up to you. After that, choose a Workspace that is more convenient for you, where application will be installed.

 

Afterwards, your app will be ready to work. You could go to the control panel.

From that panel, you can customize your app: upload new permissions, connect notifications to any events, install your application in any Workplace, and a lot of other things.

Now, we need to give special rights to our app, if we want our application to have an acces to send messages in our chats.
To have this permission: we have to click on  "Permissions" context menu, as on our screenshot:

After that, you will be in the "OAuth & Permissions" menu. You need to go lower to the "Scope". There you shoulf select "Bot Token Scopes". In that menu, press the "Add on OAuth Scope" menu:

As a next step, we need to add the permission chat:write. You can search it in the special desk.

After that your app will have a permission to write in chats.

Nextly, after you added this right , you should add your app again to your Workspace.
Go a little lower at this page to the "Oauth Tokens for Your Workspace", than snap on the "Install to Workspace" button:


After our actions, Slack is going to seggest you to look throw permissions which are available for this app. If everything arranges you, click on the button with "Allow":

Than our bot is ready to go, Slack is going to provide you with your user token, it is going to be used to access your Workspace:

Still in that menu you have a button "Reinstall to Workspace", which you can use if you have some errors with your bot, it is going to be reinstalled, after clicking on that button.
Our last thing to do is to add our chatbot in your workspace. If you have an already created channel  you can move to that step now: "Adding a bot to your channel"

In case you don't have chats launched yet, then follow these couple of steps:
Find the "Add channel" context menu, and select "Create a new channel" button in it:


After, select a name for your channel and optionally fill the description bar.

 

Adding a bot to your channel

If you want tio add bot to your cht, you should put ypur cursor on the name of the chat and click on the "View channel details" context menu:


Then switch to  "Integration" menu and click on the  "Add Application" button:

Then search your application by it's name or simply scroll down to find it. In our case "CoinBot":


After all our actions, bot will be launched in our chat:

 

Python setup

We have to set up Python, so we can install and manage our Slack bots.
Firstly, let's install python v.3 and corresponding tool helpers. We are going to do that on our VM with Ubuntu v.20.04 deployed on it.
Initially, Python v.3 is already preinstalled on all Ubuntu servers version 20.04, but to convince we have all updates available, we should download all previous updates on our system using these commands:

sudo apt update
sudo apt -y upgrade

After that, we can see wich version we have :

python3 -V

The answer will look something like this:

Python 3.8.2

Nextly, we should download pip tool, which will get us access to package management:

sudo apt install -y python3-pip

After that we are going to deploy the virtual environment(VE):

python3 -m venv ~/.venvs/slackbot

After that we need to activate it:

source ~/.venvs/slackbot/bin/activate

Now our terminal in brackets will display our virtual environment, it should be something like that:

(slackbot) root@Ubuntu-Bot-Python:~#

Nextly, with pip tool, we are going to install some important Python components:

pip install slackclient slackeventsapi Flask

Explanation: slackclient and slackeventsapi - tools that make using the Slack API easier. Flask - microweb framework which is going to be used to deploy our bot.
After we have seted up Python, we can set up our bot.

Creating a class for Slackbot messages in Python

Slack is using specially formatted JSON data to send messages.
Let's launch a Python class that simulates a coin toss.
Reminder - we do all the actions in a virtual environment. In our case, the virtual environment is root@Ubuntu-Bot-Python:~#
First, using the touch command, create a file called coinbot.py:

touch coinbot.py

Then open this file with the nano editor, you can use any other editor:

nanocoinbot.py

Add the following content to our file:

# import the random library to help us generate the random numbers
import random

# Create the CoinBot Class
class CoinBot:
# Create a constant that contains the default text for the message
COIN_BLOCK = {
"type": "section",
"text": {
"type": "mrkdwn",
"text": (
"Ok! Flipping a coin....\n\n"
),
},
}
&  # The constructor for the class. It takes the channel name as the a
# parameter and then sets it as an instance variable
def __init__(self, channel):
self.channel = channel
# Generate a random number to simulate flipping a coin. Then return the
# crafted slack payload with the coin flip message.
def _flip_coin(self):
rand_int = random.randint(0,1)
if rand_int == 0:
results = "Heads"
else:
results = "Tails"
text = f"The result is {results}"
return {"type": "section", "text": {"type": "mrkdwn", "text": text}},
# Craft and return the entire message payload as a dictionary.
def get_message_payload(self):
return {
"channel": self.channel,
"blocks": [
self.COIN_BLOCK,
*self._flip_coin(),
],
}
Then let's save and close our file with a keyboard shortcut.
Now our bot can send messages, and you can add it to your workspace.

Test messages from our Slackbot

Now let's check that our class creates the correct load.
Create a file called coinbot_test.py:

nano coinbot_test.py

Then add the following content to the created file
Important: Be sure to change the server name to your own in coin_bot = coinbot("#YOUR_CHANNEL_HERE").

from slack import WebClient
from coinbot import CoinBot
import os

# Create a slack client
slack_web_client = WebClient(token=os.environ.get("SLACK_TOKEN"))

# Get a new CoinBot
coin_bot = CoinBot("#YOUR_CHANNEL_HERE")

# Get the onboarding message payload
message = coin_bot.get_message_payload()

# Post the onboarding message in Slack
slack_web_client.chat_postMessage(**message)
Save and close this file.
Before running the test, you need to export your token, which is listed on the Slak API:

Now export your token:

export SLACK_TOKEN="Your token"

Now we can test our bot. Run the following script in your terminal:

python coinbot_test.py

After that, a message about a coin toss will be sent to you in the channel on which you installed your application. Make sure your bot actually gave you either heads or tails.

Creating a Flask app to run Slackbot

Now that your bot can toss a coin, create and send messages, we will deploy Flask, which will process the messages and give some kind of reaction to them if their content matches some criteria.
First, let's configure the firewall settings to allow traffic on port 3000:

sudo ufw allow 3000

Now check the status of ufw:

sudo ufw status

You should see output similar to this:

Output
status: active

To Action From
--    ------    ----
OpenSSH    ALLOW    Anywhere
3000    ALLOW    Anywhere
OpenSSH (v6)    ALLOW    Anywhere (v6)
3000 (v6)    ALLOW    Anywhere (v6)

We will then create a file for our Flask application.
Let's call this file app.py:

touch app.py

Then, open this file with any of the editors. We will use nano:

nano app.py

Let's add the following content to our app.py file:

import os
import logging
from flask import Flask
from slack import WebClient
from slackeventsapi import SlackEventAdapter
from coinbot import CoinBot

# Initialize a Flask app to host the events adapter
app = Flask(__name__)
# Create an events adapter and register it to an endpoint in the slack app for event injestion.
slack_events_adapter = SlackEventAdapter(os.environ.get("SLACK_EVENTS_TOKEN"), "/slack/events", app)

# Initialize a Web API client
slack_web_client = WebClient(token=os.environ.get("SLACK_TOKEN"))

def flip_coin(channel):
"""Craft the CoinBot, flip the coin and send the message to the channel
"""
# Create a new CoinBot
coin_bot = CoinBot(channel)

# Get the onboarding message payload
message = coin_bot.get_message_payload()

# Post the onboarding message in Slack
slack_web_client.chat_postMessage(**message)

# When a 'message' event is detected by the events adapter, forward that payload
# to this function.
@slack_events_adapter.on("message")
def message(payload):
"""Parse the message event, and if the activation string is in the text,
simulate a coin flip and send the result.
"""

# Get the event data from the payload
event = payload.get("event", {})

# Get the text from the event that came through
text = event.get("text")

# Check and see if the activation phrase was in the text of the message.
# If so, execute the code to flip a coin.
if "hey sammy, flip a coin" in text.lower():
# Since the activation phrase was met, get the channel ID that the event
# was executed on
channel_id = event.get("channel")

# Execute the flip_coin function and send the results of
# flipping a coin to the channel
return flip_coin(channel_id)

if __name__ == "__main__":
# Create the logging object
logger = logging.getLogger()

# Set the log level to DEBUG. This will increase verbosity of logging messages
logger.setLevel(logging.DEBUG)

# Add the StreamHandler as a logging handler
logger.addHandler(logging.StreamHandler())

# Run our app on our externally facing IP address on port 3000 instead of
# running it on localhost, which is traditional for development.
app.run(host='0.0.0.0', port=3000)
Save and close the file.
Explanation: We add the following statements because:

import os - we will use to access environment variables

import logging - we will use to log application events.

from flask import Flask - we will use to create a Flask application

from slack import WebClient - we will use to send messages via Slack

from slackeventsapi import SlackEventAdapter - we will use to receive events from Slack and process them

from coinbot import CoinBot - we will use to instantiate your CoinBot and generate the message payload.

Launching your Flask application

After all, our Flask application is ready to work with the application, let's test it.
First, let's add our Slackbot app.
On the Slack API page, go to the "Basik information" section and scroll down to the "App Credentials" subsection:

Click on "Show" as shown in the screenshot and then copy the Signing secret.
Now we export our signature secret with this command:

export SLACK_EVENTS_TOKEN="MY_SIGNING_SECRET_TOKEN"

Now we can test our application.
Start the Flask application using that code:

python3 app.py

Example of the output:

(slackbot) [19:37:05] danial:CoinBot$ python app.py
* Serving Flask app "app" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://0.0.0.0:3000/ (Press CTRL+C to quit)

Now let's finish setting up our application in the Slack UI.
Firstly, we are going to provide our application the right to read, process activities in chat and respond to them.
In the user interface menu, select the "Event Subscriptions" section and switch the "Enable Events" toggle switch to the "On" position, as shown in the screenshot:

 

After, open the "Subscribe to bot events" menu and select message.channels:

 

After our actions, your application in futere will have an opportunity to process messages.
Once you save the changes, you will have a yellow context menu at the top of the screen informing you that you need to reinstall the application in order to apply the following changes.
Click on reinstaliation link in this banner to reinstall the app:


You will then have a context menu with the new permissions applied. If you agree with everything, click "Allow":


After all, our bot will be ready. Mve to your chat and send a message with the phrase "Hey Danny, flip a coin".
Your is going to check your luck and show you the result . Congratulations, we launched our bot!