EmailJS vs SendGrid vs AWS SES: The Good, The Bad & The Ugly
Table of Contents
- Introduction
- SendGrid
- AWS SES
- EmailJS
- Show Me The Code!
- Outroduction(?)
Introduction
I recently launched my business’ website and wanted to share my experience with the email services I had the (dis)pleasure of working with.
I started building my Azure Static Web App in the Fall 2021, I built the basic components first and then put them all together after a brief hiatus in the Spring 2022 (Thanks, Elden Ring).
SendGrid
When I initially set up the site I used Twilio’s SendGrid service to send myself an email whenever a user submits the contact form. This worked great, I was happy with their pricing, and once I confirmed that it was working as intended I stopped messing with the contact form.
Fast forward a few months and I was finally ready to publish the site, I went to confirm the contact form was working properly and… drumroll… nothing happened when I submitted it.
Perplexed, I went to my SendGrid portal and found that the account had been deactivated. I checked my email to see if I had missed something but I hadn’t received any warnings or notices. I reached out to their support team who were friendly but ultimately unhelpful.
What I learned is that they will close accounts they deem “dormant” and when pressed for specific details, they were unable to give answers. They encouraged me to set up a new account but here are the reasons that wouldn’t work for me:
- Without knowing the exact guidelines for what constitutes a “dormant” account, I could not be assured this wouldn’t happen again.
- Without receiving any sort of alert before my account gets closed, I would have no way to know that my customers are unable to reach me.
The latter is more egregious, a service provider closing customer accounts without letting them know either in advance or after the fact is a risk my business could not accept.
With that revelation, I dropped SendGrid and moved my contact form to Amazon’s Simple Email Service.
AWS SES
The transition to AWS SES was unfortunately short-lived. I had created an account in their sandbox environment and implemented it in my site, the last step was to apply for a rate limit increase (The sandbox trial has several limitations).
After submitting my use-case to AWS they denied my account claiming that my use of Amazon SES could have a “negative impact on their service”, whatever that means.
Without even being able to get off the ground with AWS SES, I continued my search.
EmailJS
Now that I had been met with disappointment from two of the biggest managed email services, I decided to look at simpler options.
I found EmailJS and it looked like exactly what I needed: minimal fuss, generous pricing tiers and marketed as developer-friendly.
I did hit a couple snags with this service that I’ll talk about below but first I want to express my satisfaction with their platform. The documentation was simple and I was able to get up and running in only a few minutes, it linked with my google workspace email easily and, most importantly, it worked for my needs!
Here’s a couple things to watch out for with EmailJS.
- They say that it is meant to be used client-side without the need for a server. That’s great for simplicity but it can result in leaking account secrets because if you didn’t already know, client code is public.
- In fact, by default it doesn’t even work in the server. You have to enable a setting in the account portal under security “Allow EmailJS API for non-browser applications”.
- The Rest API documentation is somewhat vague on the implementation details with accessToken
Show Me The Code!
Without further ado, here’s what it takes to implement EmailJS.
The client-side docs are simple and readily available at https://www.emailjs.com/docs/sdk/send/
The server-side Rest API docs weren’t quite as clear
const axios = require('axios');const templateParams = {
example: "Value"
};const serviceID = process.env["EMAILJS_SERVICE_ID"]
const templateID = process.env["EMAILJS_TEMPLATE_ID"]
const publicKey = process.env["EMAILJS_PUBLIC_KEY"]
const privateKey = process.env["EMAILJS_PRIVATE_KEY"]
const data = {
service_id: serviceID,
template_id: templateID,
user_id: publicKey,
template_params: templateParams,
accessToken: privateKey
}const emailjsURL = "https://api.emailjs.com/api/v1.0/email/send"
const headers = {
"Content-Type": "application/json"
}
await axios.post(emailjsURL, JSON.stringify(data), {headers})
.then((response) => {
console.log('SUCCESS!', response.status, response.text);
//...Do success things
}, (error) => {
console.log('FAILED...', error);
//...Do error things
})
Outroduction(?)
Thank you for reading about my email service experience!
It is unfortunate that the big players in this space only care about big successful clients instead of helping small users become big and successful, but such is business.
Hopefully this post will serve as a beacon of hope for any others caught in a similar storm.
-Andrew