I’ve recently built a piece of software (DevDeck) to allow developers to use an Elgato Stream Deck as a productivity tool. The software works on a modular basis, allowing anyone to write a plugin for the Stream Deck. One of the plugins that I have written for DevDeck is a Slack integration so that you can change your Slack status via the Stream Deck.
This is what my Stream Deck typically looks like:
I can use the Slack icon to access a load of controls that are specific to Slack:
A slack status is typically made up of a status text and a status emoji. I reckoned that if I could find a good way of displaying emojis, I could use the emoji as the icon for the status toggles. You can see my status toggles on the middle row of this image.
After doing a bit of digging I figured there were two possible options for displaying emojis on the stream deck. I would either have to include an emoji font, or include a set of emoji icons with my plugin.
There are well over 1,000+ emojis, so shipping an emoji icon set with the plugin was going to significantly add to the download size of the plugin, so at first I leaned more strongly towards trying to get an emoji font to work.
After experimenting with a few different fonts, I realised that emoji fonts are often use rasterized images, or only work at specific resolutions. Despite these limitations, these fonts are also often several megabytes in size. Using an emoji font wasn’t going to work, unless I wanted the emoji to be really tiny on the Stream Deck keys which are 512x512 pixels.
So if a font won’t work and I’m against shipping the entire emoji collection with my plugin, perhaps a middle-ground will work.
What if an API existed where I could request emojis I need on-the-fly and at the resolution I need? This would allow my software to use emoji images without having to ship large fonts or even larger bundles of emoji images.
Next step, pick a domain: emojiapi.dev
Sourcing emoji images
The first thing that I needed to do was to find a set of emoji images that I could use. Fortunately I found the Noto Emoji repository whose licence permits the distribution of emojis.
Noto Emoji provides emojis in PNG and SVG image format, but with the SVG images I can have my API derive any file format and image size that it needs.
How does it work?
emojiapi.dev is written in Node.js as a serverless application that runs on AWS Lambda and AWS API Gateway.
When a request is received over the API, the request is either for an original SVG version of the emoji, or for a rasterized format (such as JPEG, PNG, TIFF, WEBP, etc.).
In the case where an SVG is requested the API can simply return the original image.
On the other hand, if a rasterized image is requested, the API will first check to see if that rasterized image has already been generated. If it hasn’t, the API will first need to generate the rasterized image before returning it.
All images (SVG or rasterized) are stored in AWS S3.
This concept is designed to be “lazy”, where rasterized images are calculated on an as-needed basis.
I also wanted to keep any requests that need handling by the API to an absolute minimum. As a result the API is fronted by a CDN — in this case, I’ve used AWS CloudFront.
CloudFront has been configured with a high TTL to cache responses from the API for a long period of time because the images are unlikely to change. This means that CloudFront should serve up the requested emoji without invoking the API if it has already been cached by the CloudFront edge node handling the request.
ou can request an SVG of an emoji with the following
And, the rasterized format using the following
If like me you aren’t overly clued up on what all the emojis are called, you can find a list of them here.
I never set out to build an emoji API, it just happened to be a nice side-project that came out of trying to develop a piece of software that would allow software developers to use a stream deck as a productivity tool.
Over time I’m sure there is plenty of functionality that can be added to the emoji API or emojiapi.dev website, but for now it addresses the need that I had. 🙂