Skip to content

Instantly share code, notes, and snippets.

@TimetravelerDD
Forked from greird/slack-files-downloader.sh
Last active September 11, 2024 01:13
Show Gist options
  • Select an option

  • Save TimetravelerDD/20ebd61a20b2d8071070a372d60544f1 to your computer and use it in GitHub Desktop.

Select an option

Save TimetravelerDD/20ebd61a20b2d8071070a372d60544f1 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
# -p Add date prefix(YYYY-MM-DD) from json filename
# -c Add counter to filenames starting from 02 if duplicates exist
# Set the export folder name
export_folder="export"
# Set maximum filename length
max_filename_length=150
while getopts "ospc" flag
do
case $flag in
o) overwrite=true;;
s) silent=true;;
p) prefix=true;;
c) counter=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 '.[] | select(.files != null) | .files[0] | [.title, .name, .url_private_download, .filetype] | del(..|nulls)' | sed 's/ //g')
do
if [ "$a" == '[]' ]
then
continue
fi
title=$(echo $a | jq -r '.[0]')
name=$(echo $a | jq -r '.[1]')
url=$(echo $a | jq -rc '.[2]')
filetype=$(echo $a | jq -r '.[3]')
if [[ $filetype == $usertype ]] || [[ -z $usertype ]] || [[ -z $filetype ]]
then
# Extract extension from name
extension="${name##*.}"
# Use title if available, otherwise use name without extension
if [[ ! -z $title ]] && [[ $title != "null" ]]
then
filename=$(echo "$title" | sed -e 'y/āáǎàçēéěèīíǐìōóǒòūúǔùǖǘǚǜüĀÁǍÀĒÉĚÈĪÍǏÌŌÓǑÒŪÚǓÙǕǗǙǛÜ/aaaaceeeeiiiioooouuuuuuuuuAAAAEEEEIIIIOOOOUUUUUUUUU/')
# Check if title already includes the extension
if [[ "${filename##*.}" != "$extension" ]]
then
filename="${filename}.$extension"
fi
else
filename=$(echo "${name%.*}" | sed -e 'y/āáǎàçēéěèīíǐìōóǒòūúǔùǖǘǚǜüĀÁǍÀĒÉĚÈĪÍǏÌŌÓǑÒŪÚǓÙǕǗǙǛÜ/aaaaceeeeiiiioooouuuuuuuuuAAAAEEEEIIIIOOOOUUUUUUUUU/')
filename="${filename}.$extension"
fi
# Replace forward slashes and colons with dashes
filename=$(echo "$filename" | sed 's/[\/:]/-/g')
# Limit filename length
if [ ${#filename} -gt $max_filename_length ]; then
filename="${filename:0:$max_filename_length}"
# Ensure we don't cut off in the middle of the extension
filename="${filename%.*}.${filename##*.}"
fi
if [[ $prefix == true ]]
then
filename_prefix=$file
filename_prefix="${filename_prefix##*/}"
filename_prefix="${filename_prefix%.*}"
filename="${filename_prefix}-${filename}"
fi
if [[ ! -z $filename ]] && [[ $filename != "null" ]]
then
file_path="$export_folder/$channel/$filename"
if [ -f "$file_path" ] && [[ $overwrite != true ]]
then
if [[ $counter == true ]]
then
counter_value=2
filename_without_ext="${filename%.*}"
ext="${filename##*.}"
new_filename="${filename_without_ext}_$counter_value.$ext"
while [ -f "$export_folder/$channel/$new_filename" ]
do
let counter_value++
new_filename="${filename_without_ext}_$counter_value.$ext"
done
filename=$new_filename
else
if [[ $silent != true ]]
then
printf "$filename already exists in destination folder. Skipping!\n"
fi
continue
fi
fi
printf "Downloading $filename...\n"
mkdir -p "$export_folder/$channel"
curl --progress-bar $url -o "$export_folder/$channel/$filename"
fi
fi
done
done
fi
done
@TimetravelerDD
Copy link
Author

taking inspiration from some of the other forks I have added my own version which has:

  • readable date prefix
  • title as filename
  • file name length limit
  • removes illegal characters
  • make sure file extension is there

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