I ❤️emojis, and I love Slack’s emoji reactions even more. They help bridge that physical gap when working remotely. Our 21st-century hieroglyphs - a quick hit to sign a feeling. That’s why I asked myself: if Slack emoji reactions are awesome, how can I make them awesomer

Meet Mister Moji, an open source library combining a Slackbot, Raspberry Pi and LED Matrix. Anytime someone reacts to your message with an emoji, Mister Moji will display the name of the person reacting and the emoji:

A LED Matrix board. "@Ryan.Hagerty [pizza emoji]" is scrolling across the board.

Here you can see me reacting to my own message because I had to test this somehow.

This was pretty fun to make, and I want you to be able to make it too. To start, head on over to the Mister Moji Github repo. I provided an equipment list and instructions to build your own. 🎉

While it was fun, there were a lot of challenges to overcome. Here’s a couple of the most time-consuming problems I faced.

You have limited resources.

When you combine running multiple Python libraries to display data to an LED device over a Raspberry Pi Zero, you’re going to need to eek out every ounce of performance. 

I discovered early on that while loading and displaying an image was trivial, dynamically loading an image based on a Slack event API response would cause a fatal OVERFLOW_BUFFER crash. 

I tried the gamut - event emitters to delegate the Slack event response (which was a whole other issue), loading my functions dynamically, and the normal developer ‘Google the problem till it hurts’ workflow. It wasn’t until I dove into the code of the RPI RGB Matrix library that I found the solution. 

Inside the Python wrapper for setImage was an optional argument that allowed us to use a safer, slower way to set an image by reading the buffer directly. 

After employing the slower method to set the image, everything worked! But code giveth, and code taketh, and now my scrolling message was a stuttering, janky animation. 

Getting around the animation jank was mostly a task of image optimization:

  • Instead of employing the Python image library to resize the original image, I created a batch action to resize all the images to my desired 24x24px.
  • As an additional step to the batch action, I removed the transparency and replaced it with a black background.
  • Finally, I used the flag --led-pwm-lsb-nanoseconds=280, which adjusts the frame rate at which bits are displayed. A higher than default value, in this case 280, provides a smoother animation without compromising a noticeable frame rate. 

If you’re curious, the batch action took over 45 minutes to complete due to my second major issue...

There are a lot of emojis - like a lot.

When I first started testing my Slackbot, I noticed Slack only returns the human readable name of the emoji, such as: heart_eyes or joy. Unfortunately, every set of emoji images available on the web contains the unicode name, (U+1F600). “No big deal.” I thought. “If worse comes to worst, I’ll just rename the image files manually. There’s probably like 300.”

Including variations, there are over 3,000 emojis. That’s a big nope to rename by hand. To overcome this, two things had to happen. 

First, I discovered an indispensable repo Emoji Data that contains a magic json file with tons of information on each emoji, including both their respective unicode name and human readable name that Slack uses - the short_name

Secondly, I created a small node script that renames all my emoji unicode images to short_hand names. For example, 1f3a3.png becomes fishing_pole_and_fish.png and now my script knows exactly what image to look for when receiving reaction data from Slack - yea!

If you’re interested, I also put that script up in a Github repo as well. It’s not extensible or robust out of the box, but it might be useful to someone Googling like I was. 

An astute observer like yourself is probably asking, “Why didn’t you use an emoji font instead of dealing with images?” A great question with two answers.

  1. The font I’m using to display the user name is a BDF font. A BDF font is short for bitmap font, which means it will look good on low resolution devices like LED displays.
  2. Here’s the real blocker: if you remember in the section above, I discuss limited resources, and I talk about optimizing pixels on a 2KB image file to improve performance. The NotoColorEmoji.ttf emoji font file is 9MB. I’ll let you extrapolate from there. 

Thanks for reading! Hope you enjoyed it, and don’t forget, here’s the repo. If you like what you see or want to ask any more questions - hit me up! 👋