Last active
August 15, 2018 16:34
-
-
Save Crissov/5bbf9704995317c20955ab2d0caf1045 to your computer and use it in GitHub Desktop.
Scrape Facebook emojis
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let content_security_policy = "script-src 'self'; object-src 'self' https://www.facebook.com/"; // for running in Chrome's JS console | |
/* Let’s see which Unicode 10.0 emojis Facebook already supports. | |
<https://github.com/Crissov/unicode-proposals/issues/254#issuecomment-284831620> */ | |
let myEmojis = new Map([ | |
['1f6f7', 'U+1F6F7 🛷 SLED'], | |
['1f6f8', 'U+1F6F8 🛸 FLYING SAUCER'], | |
['1f91f', 'U+1F91F 🤟 I LOVE YOU HAND SIGN'], | |
['1f928', 'U+1F928 🤨 FACE WITH ONE EYEBROW RAISED'], | |
['1f929', 'U+1F929 🤩 GRINNING FACE WITH STAR EYES'], | |
['1f92a', 'U+1F92A 🤪 GRINNING FACE WITH CRAZY EYES'], | |
['1f92b', 'U+1F92B 🤫 FACE WITH FINGER COVERING CLOSED LIPS'], | |
['1f92c', 'U+1F92C 🤬 SERIOUS FACE WITH SYMBOLS COVERING MOUTH'], | |
['1f92d', 'U+1F92D 🤭 SMILING FACE WITH SMILING EYES AND HAND COVERING MOUTH'], | |
['1f92e', 'U+1F92E 🤮 FACE WITH OPEN MOUTH VOMITING'], | |
['1f92f', 'U+1F92F 🤯 SHOCKED FACE WITH EXPLODING HEAD'], | |
['1f931', 'U+1F931 🤱 BREAST-FEEDING'], | |
['1f932', 'U+1F932 🤲 PALMS UP TOGETHER'], | |
['1f94c', 'U+1F94C 🥌 CURLING STONE'], | |
['1f95f', 'U+1F95F 🥟 DUMPLING'], | |
['1f960', 'U+1F960 🥠 FORTUNE COOKIE'], | |
['1f961', 'U+1F961 🥡 TAKEOUT BOX'], | |
['1f962', 'U+1F962 🥢 CHOPSTICKS'], | |
['1f963', 'U+1F963 🥣 BOWL WITH SPOON'], | |
['1f964', 'U+1F964 🥤 CUP WITH STRAW'], | |
['1f965', 'U+1F965 🥥 COCONUT'], | |
['1f966', 'U+1F966 🥦 BROCCOLI'], | |
['1f967', 'U+1F967 🥧 PIE'], | |
['1f968', 'U+1F968 🥨 PRETZEL'], | |
['1f969', 'U+1F969 🥩 CUT OF MEAT'], | |
['1f96a', 'U+1F96A 🥪 SANDWICH'], | |
['1f96b', 'U+1F96B 🥫 CANNED FOOD'], | |
['1f992', 'U+1F992 🦒 GIRAFFE FACE'], | |
['1f993', 'U+1F993 🦓 ZEBRA FACE'], | |
['1f994', 'U+1F994 🦔 HEDGEHOG'], | |
['1f995', 'U+1F995 🦕 SAUROPOD'], | |
['1f996', 'U+1F996 🦖 T-REX'], | |
['1f997', 'U+1F997 🦗 CRICKET'], | |
['1f9d0', 'U+1F9D0 🧐 FACE WITH MONOCLE'], | |
['1f9d1', 'U+1F9D1 🧑 ADULT'], | |
['1f9d2', 'U+1F9D2 🧒 CHILD'], | |
['1f9d3', 'U+1F9D3 🧓 OLDER ADULT'], | |
['1f9d4', 'U+1F9D4 🧔 BEARDED PERSON'], | |
['1f9d5', 'U+1F9D5 🧕 PERSON WITH HEADSCARF'], | |
['1f9d6', 'U+1F9D6 🧖 PERSON IN STEAMY ROOM'], | |
['1f9d7', 'U+1F9D7 🧗 PERSON CLIMBING'], | |
['1f9d8', 'U+1F9D8 🧘 PERSON IN LOTUS POSITION'], | |
['1f9d9', 'U+1F9D9 🧙 MAGE'], | |
['1f9da', 'U+1F9DA 🧚 FAIRY'], | |
['1f9db', 'U+1F9DB 🧛 VAMPIRE'], | |
['1f9dc', 'U+1F9DC 🧜 MERPERSON'], | |
['1f9dd', 'U+1F9DD 🧝 ELF'], | |
['1f9de', 'U+1F9DE 🧞 GENIE'], | |
['1f9df', 'U+1F9DF 🧟 ZOMBIE'], | |
['1f9e0', 'U+1F9E0 🧠 BRAIN'], | |
['1f9e1', 'U+1F9E1 🧡 ORANGE HEART'], | |
['1f9e2', 'U+1F9E2 🧢 BILLED CAP'], | |
['1f9e3', 'U+1F9E3 🧣 SCARF'], | |
['1f9e4', 'U+1F9E4 🧤 GLOVES'], | |
['1f9e5', 'U+1F9E5 🧥 COAT'], | |
['1f9e6', 'U+1F9E6 🧦 SOCKS'] | |
]); | |
/** EmojiStaticConfig, EmojiConfig */ | |
var defaultSize = 32;// 64 does not work, 128 only works for emojis from Unicode 10 | |
var pixelRatio = 3;// values of 1, 1.5, 2 and 3 are working, possibly others as well, but not 2.5 | |
var schemaAuth = "https:\/\/www\.facebook\.com\/images\/emoji\.php\/v8"; // the digit at the end does not seem to matter much, FB uses `7` or `8` | |
var fileExt = ".png"; | |
var checksumBase = 317426846; | |
var supportedSizes = { | |
"16": "DP16", | |
"18": "DP18", | |
"20": "DP20", | |
"24": "DP24", | |
"28": "DP28", | |
"30": "DP30", | |
"32": "DP32", | |
"64": "DP64", | |
"128": "DP128" | |
}; | |
var types = { | |
FBEMOJI: "f", | |
FB_EMOJI_EXTENDED: "e", | |
MESSENGER: "z", | |
UNICODE: "u" | |
} | |
var FBEMOJI = "f"; | |
var FB_EMOJI_EXTENDED = "e"; | |
var MESSENGER = "z"; | |
var UNICODE = "u"; | |
/** | |
* Facebook emoji URL checksum | |
* @param string codepoints = "{single-digit pixel ratio}/" | |
* + "{decimal pixel width/height}/" | |
* + "{lowercase hexadecimal Unicode positions, separated by underscores}.png" | |
* = `\d/\d{2,3}/[a-f\d_]+\.png` (lax RX) | |
* = `[12]/(16|18|20|24|28|30|32|64|128)/[a-f\d]{4,5}(_[a-f\d]{4,5})*\.png` (stricter RX) | |
* @param int base = 317426846 (default) | |
* @returns string of 2 hexadecimal digits | |
*/ | |
function checksum(path, base) { /* i(k, l) */ | |
// path = unescape(encodeURIComponent(path)); | |
/** `unescape()`: `&` → `&`, `<` → `<`, `>` → `>`, `"` → `"`, `'` → `'` */ | |
for (var pos = 0; pos < path.length; pos++) { | |
base = (base << 5) - base + path.charCodeAt(pos); | |
base &= 4294967295; | |
} | |
return (base & 255).toString(16); | |
} | |
function getURL(codepoints, size, type) { /* j(k, l, m) */ | |
size in supportedSizes || defaultSize; | |
var path = pixelRatio + '/' + size + '/' + codepoints + fileExt; | |
var check = checksum(path, checksumBase); | |
return schemaAuth + '/' + type + check + '/' + path; | |
} | |
function getMessengerURL(codepoints, size) { /* k(l, m) */ | |
return getURL(codepoints, size, types.MESSENGER); | |
} | |
function getFBEmojiURL(codepoints) { /* k(l) */ | |
var size = arguments.length <= 1 || arguments[1] === undefined ? defaultSize : arguments[1]; | |
return getURL(codepoints, size, types.FBEMOJI); | |
} | |
function getFBEmojiExtendedURL(codepoints) { /* k(l) */ | |
var size = arguments.length <= 1 || arguments[1] === undefined ? defaultSize : arguments[1]; | |
return getURL(codepoints, size, types.FB_EMOJI_EXTENDED); | |
} | |
/** Output HTML and automatically click on each link */ | |
function FBemoji(codepoints, alt) { | |
var address = getFBEmojiURL(codepoints); | |
var download = document.createElement("a"); | |
download.setAttribute("id", codepoints); | |
download.setAttribute("download", alt + ".png"); | |
download.setAttribute("title", alt); | |
download.setAttribute("href", address); | |
var thumb = document.createElement("img"); | |
thumb.setAttribute("src", address); | |
thumb.setAttribute("alt", alt); | |
thumb.setAttribute("title", codepoints); | |
download.appendChild(thumb); | |
return document.body.appendChild(download); | |
} | |
var title = document.getElementsByTagName("title")[0]; | |
title.textContent = "Facebook emoji image scraper"; | |
var body = document.getElementsByTagName("body")[0]; | |
body.textContent = ""; // clear all existing body content | |
for (let [codepoint, name] of myEmojis) { | |
var node = FBemoji(codepoint, name); | |
node.click(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Apparently for the emoticons PACMAN
:v
LIKE(y)
and FACE_WITH_COLON_THREE:3
the capitalized name should be used as the codepoint and the type set to "e".