Slack bot in Python – #4 Sending Direct Messages

As you learned about creating a basic slack bot in python and added slash commands, and event handling features in our previous tutorials, today you’ll learn to send a direct message to a member.

Getting started with Sending Direct messages with Slack bot in Python

This is the fourth part of our Slack Bot Python tutorial series and if you’re a newbie creating a slack bot in python, it is highly recommended to go through our firstsecond, and third parts of this tutorial. If you’re not familiar with slack, you can check Slack’s Official website to know about it. In this tutorial today, you’ll learn to add event handling features to our slack bot which we created in the previous tutorials. This time you’ll not create a different code but you’ll edit the same Repl which you used while creating slash commands and event handling.

What are Direct Messages?

A direct message is an end-to-end encrypted message between any two users on slack. Any message inside a channel is visible to all the teammates in that channel with necessary permissions but a direct message is only visible to the sender and the receiver. It is just a chat between any two persons in a workspace. You can also chat with your bot in direct messages and send or receive messages from your bot as DMs. DMs are used so that the conversation between any two users is not accessible by any other user in the workspace. You can also make your slack bot in python send DMs through your script.

Algorithm

In order to create slash commands for your Slack Python bot, you’ll have to follow the following algorithm:

  1. Provide the permissions to send direct messages to your bot.
  2. Add a message event for the bot to be able to read.
  3. Re-install your app to your workspace.
  4. Start creating direct messages for your Slack Bot in python code.
  5. Run the flask server.

Add the permissions to your Bot API

In order to add the permission to our API settings for our slack bot, we’ll need to go to slack’s API site and click on the Your Apps button on the top right corner of the page, and select the bot by its name (here Webmatrices Bot).

Selecting the Bot
Selecting the Bot

Now, you need to select OAuth and Permissions from the left side toolbar.

Select OAuth and Permissions
Select OAuth and Permissions

Now scroll the page down to Bot Token Scopes and click on Add an OAuth Scope Button.

Click on Add an OAuth Scope Button

Now select im:write permission from the dropdown list.

im:write permission
im:write permission

Now, since in the last tutorial, we permitted the bot only to be able to handle the reaction events, we’ll now go to Event Subscriptions on the left sidebar of the page and scroll the page down to Subscribe to bot events section, and click on Add Bot User Event and select message.channels permissions from the dropdown and click on Save Changes.

Select Message Event subscription
Select Message Event subscription

Now you’ve added the permission and added the subscription to read messages so now you need to re-install your app to the workspace. Scroll to the top of the OAuth and Permissions page and you’ll find the Reinstall to Workspace button under your Bot Token, click on it and then click on Allow.

Now all your changes are saved and you’re ready to code your bot for direct messages.

Diving into the Code

As you have already imported all the libraries required for creating a slack client listener, API, and importing bot tokens and secrets in previous tutorials, now you can directly add the function to be executed for sending direct messages to the keep_alive.py file of the same code.

At first, you need to create a create an event listener for on message events using slackeventsapi‘s SlackEventHandler class. You can use @slack_event_adapter.on('message') and attach the function you want to execute with it as follows:

1. First, define the function name (here: direct_messages) taking a single parameter, payload.

@slack_event_adapter.on('message')
def direct_messages(payload):

2. Now we need to create a trigger word so that the bot does not send a direct message every time someone messages to the workspace but only if someone uses a special triggering word. Here, you’ll make the bot send warnings to the user using the word shit in the workspace through direct messages. We’ll take the payload upcoming from the API and will save its event as an event variable and then save the text message from the event variable as a text variable

event = payload.get('event', {})
text = event.get('text')

3. Now we’ll check if the text that the user has sent is shit or not.

if "shit" in text:

4. If the text is equal to the trigger word (here shit), we’ll get the channel ID and user ID from the event variable.

channel_id = event.get('channel')
user_id = event.get('user')

5. Now we need to make sure that the trigger word is not used by the bot itself. For this, we’ll get the bot id using slack’s client library and make sure it’s not equal to the user id of the user who sent the trigger word, i.e., shit.

BOT_ID = client.api_call("auth.test")['user_id']
if BOT_ID != user_id:

6. Now, finally we’ll send a direct message to the user warning not the use word again in the workspace. For sending a Direct Message, we can use the same .chat_postMessage() function that we used in the first tutorial but we’ll have to use @user_id as the channel name in order to send a DM.

client.chat_postMessage(channel=f"@{user_id}", text=f'You just used the word "shit". Please use a sincere language while chatting in <#{channel_name}> else you may be banned from the workspace for using abusive words.')

Make sure you add all these codes before defining the run function used to run the flask server and run your code. Now, you can try sending the word shit in your workspace and you’ll receive a DM from your bot.

Complete Code

from keep_alive import keep_alive
keep_alive()
from flask import Flask, request, Response
from threading import Thread
import slack_sdk as slack
import os
from pathlib import Path
from dotenv import load_dotenv
from slackeventsapi import SlackEventAdapter

#Set the path of .env file using pathlib
token_path=Path('.') / '.env'
#loading env with load_dotenv function of python-dotenv module
load_dotenv(dotenv_path=token_path)
#saving bot api token as variable
bot_api_token=os.environ['bot_token']

client=slack.WebClient(token=bot_api_token)

app = Flask('')
#Note that this piece of code should be added just after the assigning of app variable
slack_event_adapter=SlackEventAdapter(os.environ['signing_token'], '/slack/events', app)
BOT_ID = client.api_call("auth.test")['user_id']

@app.route('/')
def home():
    return "The bot is alive!!"

@app.route('/greet', methods=['POST'])
def greet_command():
  data = request.form
  channel_id = data.get('channel_id')
  client.chat_postMessage(channel=channel_id, text="Howdy, How are you doing?")
  return Response(), 200

@slack_event_adapter.on('reaction_added')
def reaction(payload):
  event = payload.get('event', {})
  channel_id = event.get('item', {}).get('channel')
  user_id = event.get('user')
  client.chat_postMessage(channel=channel_id, text=f"<@{user_id}>, you just reacted to a message.")

@slack_event_adapter.on('message')
def direct_messages(payload):
  event = payload.get('event', {})
  text = event.get('text')
  if "shit" in text:
    channel_id = event.get('channel')
    user_id = event.get('user')
    if BOT_ID != user_id:
      client.chat_postMessage(channel=f"<@{user_id}>", text=f"Please use a sincere language while chatting in {channel_id} else you may be banned from the workspace for using abusive words.")

def run():
  app.run(host='0.0.0.0',port=8080)

def keep_alive():
  t = Thread(target=run)
  t.start()

Output:

Slack bot in Python - Sending Direct Messages
Slack bot in Python – Sending Direct Messages

Conclusion

So, now you’ve learned to send direct messages through your slack bot in python. Now you can use this script to create your own DMs. You can create such bots and host them on different servers to keep them alive 24×7 and you can sell them to companies to earn from your bot.

  • May 12, 2022
  • 1