This content originally appeared on Level Up Coding - Medium and was authored by AaravShakunt
In my journey so far, all the companies I’ve worked with use Slack as their go-to communications tool. A lot of communications happen through these numerous channels which often causes confusion. Thankfully, Slack has an official API that allows us to create pipelines for information, which makes creating automated reports through some simple code.
The combination of Slack along with Regex and Google Sheets API has been my go-to tool for creating automated reports for teams, which has clearly helped different teams avoid manual work.
This article is a practical starting guide with boiler code for different kinds of applications which can be easily combined to create a working application.
Setting up Slack API
- Create a Workspace
I recommend setting up a sample workspace to test the API. Setting up a workspace is fairly simple which I will leave up to you to figure out. - Go to The slack API website
- Go to “Your Apps”

4. Click on Create New App

5. Set up an app from scratch and fill the details as per your project requirements

Setting Scopes
Any particular thing you wish to do with your app can be done by setting scopes which are basically permissions you provide to the bot for your workspace.
To set/change scopes for your bot, the following steps need to be followed:
- Go to OAuth & Permissions

2. Add the scope by selection Add an OAuth Scope

3. Install app to workspace

4. If not already done, copy your OAuth Token which will be needed in the program

Sending your First Message
Scopes required:
chat:write
Steps to write messages in Python:
- Setup the scopes
- Add the bots to the channel you wish to send your message to by doing the following:
1. Make a new channel(or choose an existing one)
2. While sending messages, type “@” and choose your bot in the dropdown to add it to the channel
3. Add the bot by trying to send the message while only tagging your bot. It will allow you to add the bot into the respective channel. - Setup a new Python project and store your key inside the .env file
- Open your terminal and run the following command to install the slack modules required for our project:
pip install slack
pip install slackclient - To send the message, write the following code:
import keys
import slack
client = slack.WebClient(token=keys.SLACK_KEY)
client.chat_postMessage(channel="client-tester1", text="Hello World")
The WebClient is a part of the Slack SDK for Python and is used to make API calls to the Slack workspace.
The chat_postMessage method of the WebClient to post a message to a Slack channel. The channel parameter specifies the target channel where the message will be posted, and the text parameter contains the content of the message ("Hello World" in this case).
Note: To run the above code, please add the scope: chat:write:bot
Detecting available channels
Scopes required:
channels:read, groups:read
Steps to write messages in Python:
- Setup the scopes
- Use this function:
def list_all_channels(client: slack.WebClient) -> List[Dict]:
return client.conversations_list(types="public_channel,private_channel", exclude_archived=True)["channels"]
The documentation for it is here: conversations.list method | Slack
Note: The exclude_archived argument is very important in development domains as many old slack channels which are archived are invisible that tend to make the method reach its limit without any warning.
Reading the Content of a Channel
Scopes required:
channels:history,groups:history
Steps to write messages in Python:
- Setup the scopes
- Use this code:
def read_all_messages(self, channel: str) -> list:
messages = []
latest = None
while True:
# Fetch messages in batches using the conversations_history method
response = self.client.conversations_history(channel=channel, latest=latest, limit=1000)
if not response["ok"]:
# Handle error, print a message, or raise an exception as needed
print(f"Error fetching messages: {response['error']}")
break
# Add fetched messages to the list
messages.extend(response["messages"])
# Check if there are more messages to fetch
if not response["has_more"]:
break
# Set the latest timestamp for the next batch
latest = messages[-1]["ts"]
return messages
This function works by making use of the client.conversations_history method. The method has a limit of 1000 messages at a time so we have to create a while loop which runs till the “has_more” is false. This allows us to add all the messages to a list called messages for a channel and work with it.
The Entire Code
import slack
from typing import List, Dict
import keys
class SlackHelper:
def __init__(self, token: str):
self.client = slack.WebClient(token=token)
def send_message(self, channel: str, message: str) -> List:
return self.client.chat_postMessage(channel=channel, text=message)
def list_all_channels(self) -> List[Dict]:
return self.client.conversations_list(types="public_channel,private_channel", exclude_archived=True)["channels"]
def read_all_messages(self, channel: str) -> list:
messages = []
latest = None
while True:
# Fetch messages in batches using the conversations_history method
response = self.client.conversations_history(channel=channel, latest=latest, limit=1000)
if not response["ok"]:
# Handle error, print a message, or raise an exception as needed
print(f"Error fetching messages: {response['error']}")
break
# Add fetched messages to the list
messages.extend(response["messages"])
# Check if there are more messages to fetch
if not response["has_more"]:
break
# Set the latest timestamp for the next batch
latest = messages[-1]["ts"]
return messages
def main():
slack_helper = SlackHelper(token=keys.SLACK_KEY)
# Example usage
slack_helper.send_message(channel="client-tester1", message="Test Message")
for data in slack_helper.list_all_channels():
print(data["name"])
all_messages = slack_helper.read_all_messages(channel="C03SMDRPARG")
for message in all_messages:
print(message['text'])
if __name__ == "__main__":
main()
More Basic Features
A. Listening to Messages (Event Handling)
Set Up Slack Event Subscriptions
- Go to Event Subscriptions in your Slack App settings.
- Turn Event Subscriptions ON.
- Set the Request URL to https://yourserver.com/slack/events.
- Subscribe to bot events like: message.channels (for messages in channels) andapp_mention (for when the bot is mentioned)
- Save the settings.
a. Responding to specific keywords or commands:
from slack_bolt import App
app = App(token=keys.SLACK_KEY, signing_secret="your_signing_secret")
@app.message("hello")
def say_hello(message, say):
say("Hello there!")
b. Detecting mentions (@your-bot) and replying dynamically:
@app.event("app_mention")
def handle_mention(event, say):
say(f"Hello <@{event['user']}>! How can I assist you?")
B. Slash Commands
Enable Slash Commands in Slack
Before your bot can receive slash command interactions, you need to configure them in your Slack app:
- Go to your Slack App settings at https://api.slack.com/apps/
- Select your app and navigate to Slash Commands.
- Click Create New Command and fill in the details:
- Command: /status
- Request URL: https://yourserver.com/slack/status
- Short Description: “Get system status”
4. Save the settings.
Repeat these steps for any additional commands (e.g., /command).
a. Setting up a Slack slash command (e.g., /status to get system status):
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route("/slack/status", methods=["POST"])
def status_command():
return jsonify({"text": "System is running smoothly!"})
b. Handling requests and sending responses:
@app.route("/slack/command", methods=["POST"])
def handle_command():
data = request.form
if data.get("command") == "/status":
return jsonify({"text": "Everything is operational!"})
return jsonify({"text": "Unknown command."})
C. Adding Interactive Buttons
Before your bot can receive button interactions, you need to enable interactivity in your Slack app:
- Go to your Slack App settings at https://api.slack.com/apps/
- Select your app and navigate to Interactivity & Shortcuts.
- Turn Interactivity ON.
- Set the Request URL to an endpoint in your API (e.g., https://yourserver.com/slack/actions).
- Save the settings.
a. Sending a message with a button:
client.chat_postMessage(
channel="#general",
text="Click the button below!",
blocks=[
{
"type": "actions",
"elements": [
{
"type": "button",
"text": {"type": "plain_text", "text": "Click Me"},
"action_id": "button_click"
}
]
}
]
)
b. Handling button interactions:
@app.action("button_click")
def handle_button_click(ack, body, say):
ack()
say(f"<@{body['user']['id']}> clicked the button!")
The entire code for this section
from typing import List, Dict, Optional
import os
from slack_sdk import WebClient
from slack_sdk.errors import SlackApiError
from dotenv import load_dotenv
from fastapi import HTTPException
load_dotenv()
class SlackService:
def __init__(self):
self.token = os.getenv('SLACK_BOT_TOKEN')
if not self.token:
raise ValueError("SLACK_BOT_TOKEN not found in environment variables")
self.client = WebClient(token=self.token)
# Verify auth
try:
self.client.auth_test()
except SlackApiError as e:
raise ValueError(f"Slack authentication failed: {str(e)}")
async def send_message(self, channel: str, message: str) -> dict:
return self.client.chat_postMessage(channel=channel, text=message)
async def send_interactive_message(
self,
channel: str,
header: str = "Interactive Message",
message: str = "Please select an option below",
buttons: List[Dict[str, str]] = None
) -> dict:
try:
# Default buttons if none provided
if not buttons:
buttons = [
{"text": "Option 1", "value": "opt_1", "action_id": "button_1"},
{"text": "Option 2", "value": "opt_2", "action_id": "button_2"}
]
blocks = [
{
"type": "header",
"text": {
"type": "plain_text",
"text": header
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": message
}
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": {
"type": "plain_text",
"text": button["text"]
},
"value": button["value"],
"action_id": button["action_id"]
} for button in buttons
]
}
]
response = self.client.chat_postMessage(
channel=channel,
text=message, # Ensure text is included
blocks=blocks
)
if not response["ok"]:
raise SlackApiError("Failed to send interactive message", response)
# Return only the necessary parts of the response
return {"ok": response["ok"], "message": "Interactive message sent successfully"}
except SlackApiError as e:
raise HTTPException(
status_code=500,
detail=f"Slack API error: {str(e)}"
)
async def list_channels(self) -> List[Dict]:
"""
List all channels (public and private) that the bot is a member of.
Requires scopes: channels:read, groups:read
"""
try:
response = self.client.conversations_list(
types="public_channel,private_channel",
exclude_archived=True
)
return response["channels"]
except SlackApiError as e:
raise HTTPException(
status_code=500,
detail=f"Error listing channels: {str(e)}"
)
async def read_channel_messages(self, channel: str, limit: int = 100) -> List[Dict]:
"""
Read messages from a channel.
Requires scopes: channels:history, groups:history
Args:
channel: Channel ID to read messages from
limit: Maximum number of messages to return (default 100)
Returns:
List of message objects
"""
try:
messages = []
latest = None
# Keep fetching messages until we have enough or there are no more
while len(messages) < limit:
response = self.client.conversations_history(
channel=channel,
latest=latest,
limit=min(1000, limit - len(messages)) # Slack API max is 1000
)
if not response["ok"]:
raise SlackApiError(f"Error fetching messages: {response.get('error')}", response)
batch = response["messages"]
if not batch:
break
messages.extend(batch)
# Check if there are more messages to fetch
if not response.get("has_more", False):
break
# Set the latest timestamp for pagination
latest = messages[-1]["ts"]
return messages[:limit] # Ensure we don't return more than requested
except SlackApiError as e:
raise HTTPException(
status_code=500,
detail=f"Error reading channel messages: {str(e)}"
)
async def read_all_messages(self, channel: str) -> List[Dict]:
"""
Read ALL messages from a channel (handles pagination automatically).
Requires scopes: channels:history, groups:history
Args:
channel: Channel ID to read messages from
Returns:
List of all message objects
"""
try:
messages = []
latest = None
while True:
# Fetch messages in batches
response = self.client.conversations_history(
channel=channel,
latest=latest,
limit=1000 # Maximum allowed by Slack API
)
if not response["ok"]:
raise SlackApiError(f"Error fetching messages: {response.get('error')}", response)
batch = response["messages"]
if not batch:
break
messages.extend(batch)
# Check if there are more messages to fetch
if not response.get("has_more", False):
break
# Set the latest timestamp for pagination
latest = messages[-1]["ts"]
return messages
except SlackApiError as e:
raise HTTPException(
status_code=500,
detail=f"Error reading all channel messages: {str(e)}"
)
Using Slack API for Real-Life Problems
- The template provided is a basic template that offers a base for a lot of scripting that can be done via this API. To use this in real-life applications, it can be paired with things like Regex, Google Sheets, databases, etc., for the best applications.
- The Slack API is well documented, so make use of the documentation to debug and understand the different methods and use cases.
- For testing the slack commands on local, you can try using grok to create a temporary testing domain name.
This article provides all that you need to get started with working with the Slack API and creating interactive bots for your slack channel. It’s gone through the basics of reading and sending messages to sending interactive buttons, responding to messages and slash commands. I would love to hear more about any new things that you try out that are not covered in this article. They could help me create more things on Slack as well!
A Beginner’s Guide to Working with Slack API in Python was originally published in Level Up Coding on Medium, where people are continuing the conversation by highlighting and responding to this story.
This content originally appeared on Level Up Coding - Medium and was authored by AaravShakunt

AaravShakunt | Sciencx (2025-03-19T14:13:53+00:00) A Beginner’s Guide to Working with Slack API in Python. Retrieved from https://www.scien.cx/2025/03/19/a-beginners-guide-to-working-with-slack-api-in-python/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.