Email and SAAS
Every SAAS product has to wrestle with sending emails, here is how I do it
DISCLAIMER: I’m a Senior Software Engineer with many years of experience behind me and a particular way I like to work. This may not be for you, but there will be things in here that will apply to all SAAS products.
Types of Emails you’ll send
- Welcome email when user signs up
- Password reset when they forget their password
- Bounced emails
- Weekly Summaries
- Alert to problems with account (payment, configuration, failures, etc)
- What’s new in your app, keep them engaged
How will emails get trigger? Since I’m using Heroku for most of my stuff, I use their free addon Scheduler. The only draw back is it runs either hourly or daily. I need to trigger stuff daily, weekly, and monthly. So, instead, I have their scheduler daily call a simple bash script which in turn calls specific node scripts to trigger the emails.
#!/bin/bash # A poor mans's cron scheduler. Since Heroku only has a schedule that runs daily, then we need to pick up some tasks that run weekly, or monthly as well as daily. NOW=$(date +"%D"); # Day of week 1 = Monday, 7 = Sunday DOW=$(date +"%u"); # Day of month in "01" format DOM=$(date +"%d"); # Send Weekly Jobs on Sunday, remember 7 = Sunday # https://linux.die.net/man/1/date if [ $DOW = "7" ]; then echo Running Weekly Jobs for $NOW node task.js --task schedule-weekly-summary fi # Runs jobs on first day of the month if [ $DOM = "01" ]; then echo Running Monthly Jobs for $NOW node task.js --task schedule-month-summary fi echo Running Daily Jobs for $NOW node task.js --task schedule-welcome-emails
Dealing with Bounced emails
What do you do when emails bounce? For example, in my SaaS, my users send emails to their customers. If those emails they send bounce, how do you notify them? In my app, I have some webhooks that Postmark will hit with information about bounces or spam complaints. You’ll need to handle these bounces and spam complaints in some manner.
Inbound Email Processing?
I don’t do this yet, but it’s on the road map.
Templates in code or use your Provider
I much prefer the benefits of having the email templates reside right in my code base as opposed to configuring a template on my Provider. Postmark and others provide a convenient way to make templates and just plug in variables, however I feel I have way more control over the whole process when they reside locally.
Advantages of using a Provider’s Templates
- A non-technical person can design and configure the emails if they are provided the inputs.
- Sending less over the wire when sending an email. This one seems like a big deal, but I have yet to run into this being any sort of issue.
Pitfalls of using the Provider’s Templates
- Disconnected: What if you remove a variable in the code, but don’t update the template? Then the emails fail and worse yet, these are hard to test.
- Hard to test. If you have have to wait to send an email before it’s rendered, then you cannot test in your code.
- Environments. What do you do when you have different environments such as prod and staging? You might have to open up two different accounts.
- Experimenting is tough since you have to use a completely different account then someone copy the changes into the production account.
- Vendor Lock In: I’ve changed mail providers a few times from Mandrill to SparkPost to SendGrid to Postmark. When you use local templates, switching is trivial.
Tools and services I use
- Postmark: Fast, simple, no frills, no fuss, everything you need at a price I can handle. It also offers a mailcatch option so all my staging emails just go into a black hole.
- MJML: A special email framework that makes responsive emails. Cuts way down on the boilerplate of emails. Email clients seem to be “stuck in 1999” and DO NOT support good CSS formattting.
- Nunjucks: This adds the logic I need in my templates. MJML alone does not cut it.
- MailDev: A local SMTP server you run in docker and will catch and display the emails received. Indispensable for local email development.
- NodeMailer: One interface in your app that can easily switch between providers (transports)
- CurlyLint: Inspects my Nunjucks templates to ensure it’s properly formatted
Photo by Onlineprinters on Unsplash
Did this help you out? It took me a few days to piece together all this information together, I hope this saves you some time (who knows, maybe the future me will be thankful I wrote this down). Let me know your thoughts. [email protected]