Skip to content

Instantly share code, notes, and snippets.

@greird
Last active September 11, 2024 01:09
Show Gist options
  • Save greird/94dbea010540022dca6010d9fd74d9d4 to your computer and use it in GitHub Desktop.
Save greird/94dbea010540022dca6010d9fd74d9d4 to your computer and use it in GitHub Desktop.
Download all files from a Slack workspace export folder.
#!/bin/bash
#
# This script will browse a Slack export folder and download all files in a new /export folder
#
# HOW TO:
# 1. As a Workspace admin, download an export of your Slack history (https://www.slack.com/services/export)
# 2. Make sure you have jq installed (https://stedolan.github.io/jq/)
# 3. Place this file at the root of your Slack export folder, next to channels.json
# 4. Run `bash slack-files-downloader.sh` in your terminal
#
# OPTIONS
# -o Overwrite files if they already exist in destination folder, otherwise skip them.
# -s Do not show message when a file is skipped
while getopts "os" flag
do
case $flag in
o) overwrite=true;;
s) silent=true;;
esac
done
printf "\nSelect one specific file type to download or leave empty for any (e.g. mp3, binary, jpg, png):\n"
read usertype
printf "\nSelect a channel to look into or leave empty for all channels:\n"
read userchannel
for channel in $(cat channels.json | jq -rc '.[].name')
do
if [[ $channel == $userchannel ]] || [[ -z $userchannel ]]
then
printf "\n============================================\nLooking into #$channel...\n============================================\n"
for file in "$channel"/*.json
do
for a in $(cat $file | jq -c '.[].files[0] | [.title, .url_private_download, .filetype] | del(..|nulls)' | sed 's/ //g')
do
filetype=$(echo $a | jq -r '.[2]')
if [[ $filetype == $usertype ]] || [[ -z $usertype ]] || [[ -z $filetype ]]
then
filename_raw=$(echo $a | jq -r '.[0]')
filename=$(echo $filename_raw | sed -e 'y/āáǎàçēéěèīíǐìōóǒòūúǔùǖǘǚǜüĀÁǍÀĒÉĚÈĪÍǏÌŌÓǑÒŪÚǓÙǕǗǙǛÜ/aaaaceeeeiiiioooouuuuuuuuuAAAAEEEEIIIIOOOOUUUUUUUUU/')
filename="${filename##*/}"
if [[ ! -z $filename_raw ]] && [[ $filename_raw != "null" ]]
then
if [ -f "export/$channel/$filename" ] && [[ $overwrite != true ]]
then
if [[ $silent != true ]]
then
printf "$filename already exists in destination folder. Skipping!\n"
fi
continue
fi
printf "Downloading $filename...\n"
mkdir -p export/$channel
url=$(echo $a | jq -rc '.[1]')
curl --progress-bar $url -o "export/$channel/$filename"
fi
fi
done
done
fi
done
@rdar-lab
Copy link

rdar-lab commented Aug 7, 2024

Thanks!
Works like a charm

@myself514
Copy link

This iteration will rename files if the same name exist

while getopts "os" flag
do
case $flag in
o) overwrite=true;;
s) silent=true;;
esac
done

printf "\nSelect one specific file type to download or leave empty for any (e.g. mp3, binary, jpg, png):\n"
read usertype

printf "\nSelect a channel to look into or leave empty for all channels:\n"
read userchannel

for channel in $(cat channels.json | jq -rc '.[].name')
do
if [[ $channel == $userchannel ]] || [[ -z $userchannel ]]
then
printf "\n============================================\nLooking into #$channel...\n============================================\n"

    for file in "$channel"/*.json
    do
        for a in $(cat $file | jq -c '.[].files[0] | [.title, .url_private_download, .filetype] | del(..|nulls)' | sed 's/ //g')
        do
            filetype=$(echo $a | jq -r '.[2]')

            if [[ $filetype == $usertype ]] || [[ -z $usertype ]] || [[ -z $filetype ]]
            then
                filename_raw=$(echo $a | jq -r '.[0]')
                
                filename=$(echo $filename_raw | sed -e 'y/āáǎàçēéěèīíǐìōóǒòūúǔùǖǘǚǜüĀÁǍÀĒÉĚÈĪÍǏÌŌÓǑÒŪÚǓÙǕǗǙǛÜ/aaaaceeeeiiiioooouuuuuuuuuAAAAEEEEIIIIOOOOUUUUUUUUU/')
                filename="${filename##*/}"
                
                if [[ ! -z $filename_raw ]] && [[ $filename_raw != "null" ]]
                then
                    if [ -f "export/$channel/$filename" ] && [[ $overwrite != true ]]
                    then
                        base="${filename%.*}"
                        extension="${filename##*.}"
                        counter=1
                        new_filename="${base}$(printf "%04d" $counter).${extension}"

                        while [ -f "export/$channel/$new_filename" ]; do
                            counter=$((counter + 1))
                            new_filename="${base}$(printf "%04d" $counter).${extension}"
                        done

                        filename=$new_filename
                    fi

                    printf "Downloading $filename...\n"
                    
                    mkdir -p "export/$channel"

                    url=$(echo $a | jq -rc '.[1]')
                    
                    curl --progress-bar $url -o "export/$channel/$filename"
                fi
            fi
        done
    done
fi

done

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment