Slack
Slack is the new platform we are expanding to given the needs of our clients! The heart of the bot is still the same, we just made some improvements to it so it can walk around smoothly!
Bot
To perform an exercise based on the Slack platform, you will need to provide an APP and a BOT token. If you already have an app created, you can skip the creation part and go straight to the provisioning part.
App/Bot setup
Create a Workspace in slack (You can skip this step if you have already a workspace).
Navigate to Slack Apps.
Select “Create New App”.
Select the option “From an app manifest”.
Select your workspace.
Selecting the format “YAML”, paste the code inside
bot_manifest.yml
located in the following linkCreate the App.
With the recently created app, and in the Basic Information menu, scroll to
App-Level Tokens
, Generate a token and Scopes.You can use any Token name, the important thing is that you add both scopes to the token:
connections:write
andauthorizations:read
.Generate it, copy it and keep it in a safe place, because you will only see it once.
Now navigate to the “OAuth & permissions” sub-menu inside the Feautures sidebar menu.
Copy the
Bot User OAuth Token
.For the bot to be able to respond to your messages, you must add the App within that channel. You can do this by tagging the App name or adding it manually.
Yeah! You are ready to go now!
Starting the Framework
Once you have installed in all the libraries dependent on the platform, and added it to your workspace, you will need to provide the app and bot token to the framework for it to work and choose the Slack platform on T3SF.start
.
Providing the tokens
The framework expects an APP and BOT token with the names SLACK_BOT_TOKEN
and SLACK_APP_TOKEN
.
You have two common options for this:
- Create a
.env
file On the same path as your
main.py
file create a.env
fileInside of it, add the variable
SLACK_APP_TOKEN
and your app’s token, as following:SLACK_APP_TOKEN=xapp-1-Z03ZJ58JUTF-3463422570419-p11no1l1q9po6qq96p1n383378q17032p08l7n8015mp1mn067q075n9q48m8434
Also, add the variable
SLACK_BOT_TOKEN
and the bot’s token, as following:SLACK_BOT_TOKEN=xoxb-4239546374990-4236264338677-jQqt0XeIMVgDAGNNnJaydQkk
Your file should look like this
SLACK_APP_TOKEN=xapp-1-Z03ZJ58JUTF-3463422570419-p11no1l1q9po6qq96p1n383378q17032p08l7n8015mp1mn067q075n9q48m8434 SLACK_BOT_TOKEN=xoxb-4239546374990-4236264338677-jQqt0XeIMVgDAGNNnJaydQkk
Note
Note that the tokens will be stored and everyone with read access to the file will be able to read them.
- Create a
- Export the variables to your shell environment
Create a variable with the name
SLACK_APP_TOKEN
as following:export SLACK_APP_TOKEN=xapp-1-Z03ZJ58JUTF-3463422570419-p11no1l1q9po6qq96p1n383378q17032p08l7n8015mp1mn067q075n9q48m8434
Create another variable with the name
SLACK_BOT_TOKEN
as following:export SLACK_BOT_TOKEN=xoxb-4239546374990-4236264338677-jQqt0XeIMVgDAGNNnJaydQkk
Your
env
should look like this
[...] SLACK_APP_TOKEN=xapp-1-Z03ZJ58JUTF-3463422570419-p11no1l1q9po6qq96p1n383378q17032p08l7n8015mp1mn067q075n9q48m8434 SLACK_BOT_TOKEN=xoxb-4239546374990-4236264338677-jQqt0XeIMVgDAGNNnJaydQkk [...]
Initializing the framework
As explained in the Initializing T3SF page, you will need to set 3 variables inside your main.py
file.
This example is for an exercise using Slack with a GUI:
from T3SF import T3SF
import asyncio
async def main():
await T3SF.start(MSEL="MSEL_Company.json", platform="Slack", gui=True)
if __name__ == '__main__':
asyncio.run(main())
And that’s it!
Module
To maintain the modular structure of the framework, we developed a module with all the platform specific functions inside. Including the integrated bot and the functions to contact the Slack API.
The file structure is shown below:
Slack
├── bot.py
├── __init__.py
└── slack.py
Class Functions
- Formatter(title=None, description=None, color='#5bc0de', image=None, author=None, buttons=None, text_input=None, checkboxes=None)
Creates the embed messages, with a different set of options.
- title
The title of the message.
- type:
str
- required:
False
- description
The description/main text of the message.
- type:
str
- required:
False
- color
Parameter with the color of the embedded message.
- type:
str
- required:
False
- default:
“#5bc0de”
- image
Attach an image to the message.
- type:
array
- required:
False
- author
Attach the author of the message.
- type:
array
- required:
False
- buttons
Attach buttons to the message.
- type:
array
- required:
False
- text_input
Attach a text area input to the message.
- type:
array
- required:
False
- checkboxes
Attach textboxes to the message
- type:
array
- required:
False
- async SendMessage(title: str = None, description: str = None, color_sl=None, channel=None, image=None, author=None, buttons=None, text_input=None, checkboxes=None)
Message sending controller.
- title
The title of the message.
- Type:
str
- Required:
True
- description
The description/main text of the message.
- Type:
str
- Required:
True
- color_sl
Parameter with the color of the embedded message.
- type:
str
- required:
False
- channel
Parameter with the desired destination channel.
- Type:
str
- Required:
False
- image
- Type:
array
- Required:
False
- author
- Type:
array
- Required:
False
- buttons
- Type:
array
- Required:
False
- text_input
- Type:
array
- Required:
False
- checkboxes
- Type:
array
- Required:
False
- async EditMessage(title: str = None, description: str = None, color_sl=None, response=None, image=None, author=None, buttons=None, text_input=None, checkboxes=None)
Message editing controller.
- title
The title of the message.
- Type:
str
- Required:
True
- description
The description/main text of the message.
- Type:
str
- Required:
True
- color_sl
Parameter with the color of the embedded message.
- type:
str
- required:
False
- response
Parameter with the previous response.
- Type:
array
- Required:
False
- image
- Type:
array
- Required:
False
- author
- Type:
array
- Required:
False
- buttons
- Type:
array
- Required:
False
- text_input
- Type:
array
- Required:
False
- checkboxes
- Type:
array
- Required:
False
- async InboxesAuto(self)
Fetches automatically all the inboxes, based in a regular expression (RegEx), notifies the Game masters about differents parts of this process.
- async InjectHandler(self)
Gives the format to the inject and sends it to the correct player’s inbox.
- regex_finder(input)
Tries to get a regular expresion on one string.
- input
The input to find the regular expression.
- Type:
str
- Required:
True
- async PollHandler(T3SF_instance)
Handles the injects with polls. Creates the poll with the two options and sends it to the player’s channel.
- T3SF_instance
An instance of the T3SF class.
- Type:
obj
- Required:
True
- async PollAnswerHandler(T3SF_instance, body=None, payload=None)
Detects the answer in the poll sent. Modifies the poll message and notifies the game master about the selected option.
- T3SF_instance
An instance of the T3SF class.
- Type:
obj
- Required:
True
- body
The body of the interaction.
- Type:
obj
- Required:
False
- payload
The user’s input.
- Type:
obj
- Required:
False
Integrated bot
We integrated the bot to fully manage the platform from within the framework. The bot handles poll responses, commands and environment creation.
- class create_bot(MSEL)
This class creates the bot, will handle the commands, messages and interactions with it.
- MSEL
The location of the MSEL.
- Type:
str
- Required:
True
- slack_main()
Within this method, we will create the following command management functions.
- async regex_handler(ack, body, payload)
Handles the user’s regular expression, at the start of the exercise.
- ack
Acknowledge object to inform Slack that we have received the interaction.
- Type:
obj
- Required:
True
- body
The body of the interaction.
- Type:
obj
- Required:
True
- payload
The user’s input.
- Type:
obj
- Required:
True
- async poll_handler(ack, body, payload)
Detects when the bot receives an interaction (as a response to a poll).
- ack
Acknowledge object to inform Slack that we have received the interaction.
- Type:
obj
- Required:
True
- body
The body of the interaction.
- Type:
obj
- Required:
True
- payload
The user’s input.
- Type:
obj
- Required:
True
- async ping(message, say)
Handles the
!ping
command and returns a pong message.- message
The content of the message, incluiding information about the workspace, channel, user, etc.
- Type:
obj
- Required:
True
- say
A method to directly reply on the same channel to the message/command.
- Type:
obj
- Required:
True
- async start(message, say)
Handles the
!start
command and starts the exercise.- message
The content of the message, incluiding information about the workspace, channel, user, etc.
- Type:
obj
- Required:
True
- say
A method to directly reply on the same channel to the message/command.
- Type:
obj
- Required:
True
- async start_bot()
This function will create a task to start the bot immediately.
- async run_async_incidents()
This function intancies the T3SF class and starts the exercise making use of T3SF.ProcessIncidents.
- async create_environment()
This function creates the environment for the exercise.
- async get_admins()
It will get all the administrators in the workspace and return an array with their IDs.