EzMessageManager

EZ Message Manager is the beginning of a web application to schedule sending emails & slack messages to employees based on dynamic queries. I am sharing the features, lessons learned, and the source code.

EZMessageManager has three parts, the frontend, backend, and cron.

History

I needed to schedule recurring messages to new employees about onboarding. For the past couple of months, I have been teaching myself React & Nodejs in my free time. I fell in love with a headless CMS concept and wanted to build a react frontend application on top of a Nodejs using a Strapi backend with Restful API and GraphQL.

I worked with a freelance developer to help expedite the development process, but since we were both novice nodejs/react developers, the code still needs more love.  Given this was a “learning” project for me, I thought it would be best to share it with the world as open-source and allow other developers to learn or contribute their genius.

Technology Stack

Features

  • Manage Employees - Including assigning tags and add metadata fields based on the unique information about each employee. (example: demographic, orgs, manager, expertise)
  • Email Templates - Generate email templates using unlayer. Email templates include the ability to include employee profile fields and employee metadata fields.
  • Contact List - Build dynamic distribution lists of employees based on GraphQL queries.
  • Email Schedules - Schedule emails to send to a contact list using an email template
  • Slack Schedule - Schedule slack messages to a contact list using an email template.
  • JWT Authentication - using Strapi’s built-in JWT authentication for managing users and accounts.

How it Works

Backend - https://github.com/jazmy/ezmessagemanager-backend

The backend (Strapi running on nodejs) can be easily deployed on Heroku and connected directly to Github for automatic builds and deploys. You would want to fork the Github repository, so you have your version to connect to from your own free Heroku account. I am also using a free Heroku Postgres Hobby database.

Note: Using the free version of Heroku that falls asleep after 30 minutes does not work that great for applications like this because your scheduled emails will fail, but it works fine for testing.

Frontend - https://github.com/jazmy/ezmessagemanager-frontend

The frontend is deployed on Netlify and connected directly to my Github repository for automatic builds and deploys. I was able to use their free-tier.

Cron - https://github.com/jazmy/ezmessagemanager-cron

The cron uses PM2, which is a production process manager for nodejs.  I created a procfile, ecosystem.config.js, and updated my package.json start script to run seamlessly on Heroku.

SMTP - I have it set up to use Mailtrap for testing

Contact Lists

Typically with a contact list, you would manually upload a list of employees.  If I wanted to automatically send an email to everyone assigned to a particular organization or hired in the past week, I would have to generate a static list manually.

I needed the ability to create a query that would run every time the scheduled email was triggered. It always got the most up-to-date list of employees based on my criteria without manually making a list myself.

This was tricky, so I decided that my contacts lists would be stored as a GraphQL query in the database and that query would be run each time it was scheduled to send emails.

Note:  If I were going to rewrite it, I would use the built-in Strapi restful API filters

To create a contact list, you need to write a GraphQL query.

Example

This query looks for employees who were hired after 2010-01-08 but before 2021-01-14 and have been assigned the tag with an id: 2

query{ employees (where: { hiredate_gt: "2010-01-08",hiredate_lt: "2021-01-14",tags_in:["2"] }) {id, email, firstname, lastname } }

Challenge:
GraphQL does not allow you to include “Now” variables for the current date/time.  My work-around was to parse the query using regular expressions to find and replace the word “today” with the current date. Then it would look for a numeric value in “brackets” at the end to add or subtract a number of days.

Hired in the last 90 days:

query {
employees (where: { hiredate_gte: "today",tags_in:["1"] }) { id, email, firstname, lastname }
}<-90>

Next Steps

I would love to work with a bored, yet talented, react/nodejs developer who is inspired by this project and wants to geek out with me to make it better.