Realtime Group Chat with only Emojis: EmojiChat

My first chat app built on a weekend for anonymous and simply fun conversations!

EmojiChat Desktop View

EmojiChat Desktop

Check it out at: emojichat.nilay.cc

It all started with the discovery of Repl.itA collaborative coding platform that allows anyone to quickly hack up a server with endpoints and host it with https right in their web-based code editor!

As soon as I realized that I don’t need to set up a server to be able to deploy web apps I was excited. I started hacking up a bunch of projects and EmojiChat was one of them.

The Time I got Sassy with CSS

At work, we needed a CSS engineer to convert designs into code. We heavily paid a freelancer to do it. I, coming in from a back-end/firmware background was very new to front-end already. Although I knew the basics of CSS with some early experience in Bootstrap, I lacked practice which Design to CSS conversion needs.

Determined to learn CSS I had taken a Udemy course in Advanced CSS. Within a week or two I was mastering flexbox and SASS. I soon realized that I can quickly hack up a UI based on the designs in my mind. And thus I was able to easily hack up the UI of EmojiChat.

The EmojiChat UI uses SCSS for styling. I tried to follow the BEM methodology while building the HTML/CSS.

The Minimal Dark Themed Design

EmojiChat Mobile View

EmojiChat Mobile View

As you may have guessed the UI wasn't a planned or prototyped design. It was stupid simple and colors were directly picked up from VSCode 😅️.

Building the Backend

The back-end runs a NodeJS server primarily running Socket.IO. This enables real-time communication between front-end and back-end across multiple clients.

An Anonymous group chat meant we need a way to identify users. I used a UUID generator function as described in this Stack Overflow Solution:

function uuidv4() {
  return 'xxyxxxyxyy'.replace(/[xy]/g, function (c) {
    var r = (Math.random() * 16) | 0,
      v = c == 'x' ? r : (r & 0x3) | 0x8
    return v.toString(16)
  })
}

[Update]: You are better off using the UUID NPM package instead! The package will handle the uniqueness reliability for you and is a better solution for larger projects.

Whenever a new client connected to the Server, it would send the init string as a chat-init event to the server. The server then responds with the following:

{
  user_id: "New User ID",
  user_name: "Randomly Generated Name",
  old_messages: oldMessagesList[],
  stats: stats[],
}

Behind the scenes the server would generate the unique id using the aforementioned unique id generator and assign it as the user id in the packet above. The user_name is a randomly generated name using the Random Name library. The Server would also send the old messages and some stats like total number of users and messages.

Every time a user sent a message it would hit the chat event on the socket. This message would be processed by the server in the following way:

  • Retrieve Meta info of the message (id, name, timestamp).
  • Parse the message for emoji or admin commands.
  • Append the message in a temporary global store.
  • Broadcast the message (in case of emoji) to all clients.

The Emoji parsing was carried out by using a regex parser for emojis.

Admin Commands were an interface by which the admin user could send commands using a simple text-tag-pass-code command format. This allowed me as an admin user to create text messages (and not just emoji), delete any old messages and so on! This allowed the chat to be moderated.

The temporary global store allowed to store all the messages. But this was not persistent across server reboots and crashes. This meant all the old messages would be deleted after a server restart! To solve this I developed a periodic backup scheduler: the Backup Bot 🤖️. The backup bot would periodically backup the store to a persistent storage like JSONstore. It would also send a cute message to notify users...

Backup Bot Notification Message

Backup Bot Notification Message

The Frontend

The front-end was developed in Vanilla Javascript driving the logic behind the HTML/CSS parts I had discussed earlier. Why VanillaJS? Because I was just moving into front-end frameworks like Angular. I'm a professional React developer now. Angular was an overkill for a weekend project like this chat app 😅️. If I had the choice now, I would go with react 100%.

The front-end basically behaved as a client for Socket.IO. It allowed sending and receiving of messages with the help of event handlers (functions). The sending event handler attached to the send message button would send the typed messaged with the meta data as context. This meta data had the user_id as well. This was previously obtained from the server on the first connection and saved into the browser's localStorage or cookie to be sent with later messages. This is how we could identify users on the back-end even after the user disconnected and reconnected after any duration!

The messages broadcast by the server were listened by another event handler. This handler is what constructed the html component for the chat messages dynamically using DOM manipulations.

Building this web-app was a fun and inspiring experience. Being my first chat app and one of my first web apps, it was amazing I could pull this off just over a weekend. I had lots of fun even on the initial iteration. The app was released as a generic chat app (without restricting to emoji) and later on the emoji restriction was added to achieve the desired goal. From then onwards I have been developing projects like this and have been getting better everyday!

Stay tuned for more!

You made it to the end. Thanks for reading! Here are some potatoes 🥔️🥔️🥔️🥔️.