How To Download Entire Slack Channel History with Python?

In this article, we can learn how to use the Slack API to retrieve messages from a channel over multiple requests. You need things in order to download the full Slack channel history:

  • slack_sdk
  • YOUR_SLACK_API_TOKEN
  • YOUR_CHANNEL_ID

slack_sdk

To accomplish this in Python, we can use the slack_sdk library, which provides an interface for working with the Slack API.

We need to install it first:

pip install slack_sdk

You can read more information on the github link:

Get Slack Api Token

We have to create an app in order to generate a user token. So to issue a Slack API token for your workspace, you need to follow these steps:

  1. Create a Slack App:

  2. Set up Basic Information:

    • Give your app a name
    • select the workspace where you want to install it.
    • Click on "Create App."
  3. Configure App Permissions:

    • go to "OAuth & Permissions." (left sidebar)
    • Under the "Scopes" section, add the necessary permissions
      • For fetching channel history, we need at least the channels:history scope.
    • Click on the "Install to Workspace"

In case of wrong scope you will get warning like:

The server responded with: {'ok': False, 'error': 'missing_scope', 'needed': 'channels:history,groups:history,mpim:history,im:history', 'provided': 'identify,app_configurations:read,app_configurations:write'}
  1. Retrieve the OAuth Token:

    • After installation, you'll be redirected to the "OAuth & Permissions" page.
    • Find and copy the "Bot User OAuth Token" under the "OAuth Tokens & Redirect URLs" section.
    • This token will be used as your YOUR_SLACK_API_TOKEN.

Code - Download Slack History

Then, you can use the following Python script to retrieve the entire history of a Slack channel:

TOKEN='xoxb-xxxxx-xxxxxx-xxxxxxxxxxx'

channels = {
    'général': 'CSNLXXXXXX',
    'veille': 'G01XXXXXX'
}

# Import WebClient from Python SDK (github.com/slackapi/python-slack-sdk)
from slack_sdk import WebClient
from slack_sdk.errors import SlackApiError
import json

# WebClient insantiates a client that can call API methods
# When using Bolt, you can use either `app.client` or the `client` passed to listeners.
client = WebClient(token=TOKEN)
# Store conversation history
conversation_history = []


def backup_channel(channel_name, channel_id):
    '''
    :channel_id: ID of the channel you want to send the message to
    '''
    try:
        print('Getting messages from', channel_name)
        # Call the conversations.history method using the WebClient
        # conversations.history returns the first 100 messages by default
        # These results are paginated
        result = client.conversations_history(channel=channel_id)
        all_message = []
        all_message += result["messages"]
        while result['has_more']:
            print("\tGetting more...")
            result = client.conversations_history(channel=channel_id, cursor=result['response_metadata']['next_cursor'])
            all_message += result["messages"]
        # Save to disk
        filename = f'{channel_name}.json'
        print(f'  We have downloaded {len(all_message)} messages from {channel_name}.')
        print('  Saving to', filename)
        with open(filename, 'w') as outfile:
            json.dump(all_message, outfile)
    except SlackApiError as e:
        print("Error using conversation: {}".format(e))


if __name__ == "__main__":
    # Iterate channels
    for chan_name, chan_id in channels.items():
        backup_channel(chan_name, chan_id)

Replace 'YOUR_SLACK_API_TOKEN' with your Slack API token and 'YOUR_CHANNEL_ID' with the ID of the Slack channel for which you want to download the history.

This script retrieves messages in chunks (limited by messages_per_request) until there are no more messages in the channel. The retrieved messages are then saved to a JSON file, but you can modify the script to process the messages as needed. Note that Slack's API rate limits should be taken into consideration when making a large number of requests.

Resources