Skip to content

Instantly share code, notes, and snippets.

@lmarkus lmarkus/README.MD
Last active Jun 25, 2019

Embed
What would you like to do?
Extracting / Exporting custom emoji from Slack

Extracting Emoji From Slack!

Slack doesn't provide an easy way to extract custom emoji from a team. (Especially teams with thousands of custom emoji) This Gist walks you through a relatively simple approach to get your emoji out.

If you're an admin of your own team, you can get the list of emoji directly using this API: https://api.slack.com/methods/emoji.list. Once you have it, skip to Step 3

HOWEVER! This gist is intended for people who don't have admin access, nor access tokens for using that list.

Follow along...

Step 1

Open your Slack team on your browser (I used FireFox in this example)

Next, Open your developer tools, and go to the network tab. Look for a POST request on /emoji.list step1

Step 2

Right Click on the request, and choose to open it in a new tab. step2

This will cause the browser to replay the request, yielding a JSON file with all your emoji information. step3

Save this file somewhere as emoji.json

Step 3

Run download.sh on the file. (Make sure you chmod +x it to make it executable. Details on the download.sh file.

./download.sh emoji.json

Sit back and wait. This will create a folder called output and will save all your emoji to it.

Optional Step 4

To bulk upload your emoji into a new team, use this chrome extension: https://chrome.google.com/webstore/detail/neutral-face-emoji-tools/anchoacphlfbdomdlomnbbfhcmcdmjej

Notes

1- This downloads files sequentially, one at a time. I didn't want to incurr Slack's rage by hammering their edge server with concurrent downloads. 2- This will duplicate aliased emoji

#!/usr/bin/env bash
######
## UPDATE for 2019: I completely changed my approach on how to obtain the emoji dump.
## The new approach results in a JSON file, so the processing is a bit diferent than
## with the previous version. This version will also take care of aliased emoji.
# Use:
# Make this file executable, and feed it the results from the Slack emoji URL dump. Files will be downloaded to `output`
# chmod +x download.sh
# ./download.sh emoji.json
# Input File
INPUT="$1"
# Create output directory where downloaded emoji will be stored
mkdir -p output;
# Clean Up Source File:
# Break up the file into individual lines for processing (Comma and { to NewLine)
# Slack's emoji JSON brings an unwanted escape character "\". We need to remove it.
# We'll also remove unwanted quote marks `"` and curly braces "{" "}"
RAW_LIST=$(cat "${INPUT}" | tr ",{" "\\n" | sed -E 's/[\\"{}]//g')
# Separate into Custom Emoji (Ignoring slack's default ones) and Aliases
# Filter for custom emoji (ie: Anything on emoji.slack-edge.com), and remove the ":" separator
EMOJI_LIST=$( echo "${RAW_LIST}" | grep "https://emoji.slack-edge.com" | sed 's/:https/ https/')
# Filter for the aliases, and remove the separator
ALIAS_LIST=$( echo "${RAW_LIST}" | grep ":alias:" | sed 's/:alias:/ /' )
# First download all the emoji
echo "${EMOJI_LIST}" |
while read -r line || [[ -n "$line" ]]; do
parts=($line)
url=${parts[1]}
name=${parts[0]}
extension=${url##*.}
echo "Downloading ${name}.${extension}"
curl -s -o "output/${name}.${extension}" "${url}"
done;
# Now duplicate all the aliases
echo "${ALIAS_LIST}" |
while read -r line || [[ -n "$line" ]]; do
parts=($line)
alias=${parts[0]}
source=${parts[1]}
target=$(echo "${EMOJI_LIST}" | grep "${source} ")
extension=${target##*.}
echo "Looking for source of ${alias} in ${source} -> ${target}"
echo "copying output/${source}.${extension} to output/${alias}.${extension}"
cp "output/${source}.${extension}" "output/${alias}.${extension}"
done;
@mynamebrody

This comment has been minimized.

Copy link

commented Nov 10, 2016

Bummer it doesn't work for me. I haven't tried debugging it at all yet, but at quick glance, I think they changed some IDs

@eddiejhong

This comment has been minimized.

Copy link

commented Nov 14, 2016

var url, name, emoji = [];

$('#custom_emoji .emoji_row') // This is the emoji selector's Custom section.
  .each(function () { 
   // Extract the name
    name = $(this).find(':nth-child(2)')
      .html()
      .replace(/:/g, ''); // without the enclosing colons.
    
    // Extract the url from the background-image property.
    url = $(this).find('span')
      .attr('data-original')
      .replace(/.*["'](.*)['"].*/, '$1'); // Remove the`url("` and `")` portions.
    
    // Dump to console, then copy and paste the results into a file (eg: emojiURLs.txt).
    console.log(name,url)
  });
@ekilah

This comment has been minimized.

Copy link

commented Nov 20, 2016

@eddiejhong 's update works for me. however https://api.slack.com/methods/emoji.list/test will give you a json list, which was good enough / better for me

@phil-r

This comment has been minimized.

Copy link

commented Jan 14, 2017

Feel free to use my script to download all custom emojis from your team: https://github.com/phil-r/slack-emoji

@dogeared

This comment has been minimized.

Copy link

commented Apr 25, 2017

I forked this gist and expanded on it @lmarkus. Let me know what you think: https://gist.github.com/dogeared/f8af0c03d96f75c8215731a29faf172c

@mfowlewebs

This comment has been minimized.

Copy link

commented Jun 15, 2018

this is all broken. slack switched to using virtualized lists for the emoji, so someone has to write something to trigger scrolling through the emoji list, & to grab each screen full of results. these old techniques of just running querySelectorAll & compiling the results is not going to work since most of the emoji are not in the DOM at any given time.

another day where i think virtualized list components are the worst bloody thing. you really fucked up the traditional web page, mangled it real good, react-virtualized. :(

@provjeremys

This comment has been minimized.

Copy link

commented Jul 10, 2018

@mfowlewebs et. al.

My take on the process, you'll still need to use the download script locally.

var scrollTime = $(document).height() * 2.5
// Scroll to bottom of page to load all Emoji. Slow connections may wish to adust the above factor past 2.5
$("html, body").animate({ scrollTop: $(document).height() }, scrollTime);

var url, name;
var eFile = '';
// After waiting for the scroll, grab url/name for each emoji
window.setTimeout(function () {
  var devnull = $('.emoji_row').each(function () {
    url = $(this).find('.emoji-wrapper').css('background-image');
    name = $(this).find('.custom_emoji_name').html();
    if (name) {
      url = url.replace(/.*["](.+?)["].*/, '$1'); // Remove the`url("` and `")` portions.
      // Slack now has messaging on this element for "already in use," be sure we only get the name
      var nameStart = name.indexOf(':');
      var nameEnd = name.indexOf(':', nameStart + 1);
      console.log('wtf ' + nameStart + ', ' + nameEnd + ' is ' + name.substring(nameStart+1, nameEnd))
      eFile += name.substring(nameStart+1, nameEnd) + ' ' + url + '\n';
    }
  })
  console.log(eFile);
}, scrollTime + 1000);
@itsrachelle

This comment has been minimized.

Copy link

commented Jul 12, 2018

My version of this gist that solves the issue @mfowlewebs brought up

@totalnoob91

This comment has been minimized.

Copy link

commented Aug 28, 2018

Hi guys, I am a TOTAL noob to this stuff. I created a "custom emoji" on slack and I would like to download it. I have a Mac and have absolutely NO idea how to run the scripts you guys have created. I would assume to open "terminal" and copy and paste but I have the suspicion that it is not that simple. Could someone please give me a quick tutorial on how to run these scripts so that I can get my "custom emoji" form slack and be able to use it on my phone? thanks!

@lmarkus

This comment has been minimized.

Copy link
Owner Author

commented Feb 2, 2019

UPDATE for 2019:
We were doing it wrong all along.
As it turns out, there's a much easier way to get the emoji list. I've updated the gist, and added a Readme with the new approach.

Enjoy your emoji, and give me a follow on twitter @lennymarkus

@AlexanderBartash

This comment has been minimized.

Copy link

commented Feb 10, 2019

Here is a fixed version which worked for me:

#!/usr/bin/env bash
######
## UPDATE for 2019: I completely changed my approach on how to obtain the emoji dump.
## The new approach results in a JSON file, so the processing is a bit diferent than
## with the previous version.  This version will also take care of aliased emoji.

# Use:
# Make this file executable, and feed it the results from the Slack emoji URL dump. Files will be downloaded to `output`
# 	chmod +x download.sh
# 	./download.sh emoji.json




# Input File
INPUT="$1"

# Create output directory where downloaded emoji will be stored
mkdir -p output;


# Clean Up Source File:
# Break up the file into individual lines for processing (Comma and { to NewLine)
# Slack's emoji JSON brings an unwanted escape character "\". We need to remove it.
# We'll also remove unwanted quote marks `"` and curly braces "{"  "}"

RAW_LIST=$(cat "${INPUT}" | tr ",{" "\\n" | sed -E 's/[\\"{}]//g')

# Separate into Custom Emoji (Ignoring slack's default ones) and Aliases

# Filter for custom emoji (ie: Anything on emoji.slack-edge.com), and remove the ":" separator
EMOJI_LIST=$( echo "${RAW_LIST}" | grep "https://emoji.slack-edge.com" | sed 's/:https/ https/')

# Filter for the aliases, and remove the separator
ALIAS_LIST=$( echo "${RAW_LIST}" | grep ":alias:" | sed 's/:alias:/ /' )


# First download all the emoji
echo "${EMOJI_LIST}" |
while read -r line || [[ -n "$line" ]]; do
	parts=($line)
	url=${parts[1]}
	tmp=${url%\/*.*}
	name=${tmp##*\/}
	extension=${url##*.}

	echo "Downloading output/${name}.${extension} ${url}"
	curl -s -o "output/${name}.${extension}" "${url}"

done;

# Now duplicate all the aliases
echo "${ALIAS_LIST}" |
while read -r line || [[ -n "$line" ]]; do
	parts=($line)
	alias=${parts[0]}
	source=${parts[1]}


	target=$(echo "${EMOJI_LIST}" | grep "${source} ")
	extension=${target##*.}


	echo "Looking for source of ${alias} in ${source} -> ${target}"
	echo "copying output/${source}.${extension} to output/${alias}.${extension}"
	cp "output/${source}.${extension}" "output/${alias}.${extension}"

done;
@darkvertex

This comment has been minimized.

Copy link

commented Apr 16, 2019

For me, the last paste works for main download but not for the aliasing loop. ¯\_(ツ)_/¯

@willsheppard

This comment has been minimized.

Copy link

commented May 3, 2019

I didn't see any emoji.list POST in the network tab at all, instead each emoji had an individual entry, i.e. one network request per emoji.

So using Firefox, I opened the network tab, then manually scrolled through all the custom emojis so they would all load.
Then I right-clicked on the list of network requests and chose "copy all as HAR", I saved that to a file emojis.json, and used that as the input for AlexanderBartash's script above, which downloaded them all.

@gtdeng

This comment has been minimized.

Copy link

commented May 10, 2019

It works! Looks like Slack hasn't changed their endpoint; I've used the updated script to download all the emojis. Tho had to fire up my VM to run the download script in linux as OSX kept complaining about the /bin/bash header.

@AlexanderBartash

This comment has been minimized.

Copy link

commented May 15, 2019

I didn't see any emoji.list POST in the network tab at all

In chrome I do not see it either. I see it only in FF with the native inspector when reload the page.

@YodaDaCoda

This comment has been minimized.

Copy link

commented May 16, 2019

I didn't see emoji.list, but when I went to "Customize Slack", I was able to see emoji.adminList which I was able to download with curl.

Then I wrote my own python script to do the downloading.

#!/usr/bin/env python3

#argument handling
import sys

#for parsing json
import json

#for extracting information from url & making folder
import os

#for downloading files
import urllib.request

if len(sys.argv) != 2:
    print('Usage: %s file.json' % sys.argv[0])
    sys.exit()

with open(sys.argv[1], 'r') as fp:
    obj = json.load(fp)

folder = 'emojis'

os.mkdir(folder)

for emoji in obj['emoji']:
    name = emoji['name'] + os.path.splitext(emoji['url'])[1]
    url = emoji['url']
    print(name)
    urllib.request.urlretrieve(url, folder + '/' + name)
@pihentagy

This comment has been minimized.

Copy link

commented May 17, 2019

The original solution worked for me. Thanks for your work!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.