Want To Send Emails? Let’s Develop A Solution In Under 15 Minutes
Most of us, at some point in our career, have always come across a requirement to implement an email solution. Now it could have been at your workplace, the amazing personal project that you are working on or as an integral part of the minimum viable product ( MVP).
Some common use cases could be:
- Sending emails on completion of a particular workflow in your application.
- Administrators sending reminder or invitation emails to selected users from a dashboard.
- Users inviting others to collaborate on workflow & so on
Possibilities & use-cases are limitless.
However, truth be told, always the timeline is strict & stakeholders want it:
The typical set of features you would be asked to implement for an email solution:
- Only authenticated users or admins should be able to send emails.
- Ability to add multiple recipients.
- Should be able to configure templates i.e. change content, change subject lines, add/remove images & call to action buttons on the fly.
- Ensure 100% delivery rate.
…the list might go on, but FOCUS🧐!!
The most important aspect that I feel from the above list is delivery, configurable templates & authentication.
Imagine, today you prepare one email-template, then you are asked to change the:
You do realize the vicious loop here, right? Which ensures you are going nowhere 🙄
Wouldn’t it be nice if we could minimize this or even eliminate the trouble of creating & configuring email templates?
Let’s devise a solution with the following pieces, addressing the above requirements.
We’ll have the client-side of the application developed using Angular. An important package for us will be @angular/fire & firebase. The dependency graph for our application will look like below.
Here, we plan to have a sign-in screen to capture details & authenticate the users along with a send-email screen with a little mix of toast messages, to do the actual magic.
Sign-in Screen & Authentication 🛡️
You would never want any random users of your application to send emails, right?
Even in most real-world projects, you would have some sort of authentication to pass before you enable rolling out emails or allow access to authorized features of your platform.
Firebase authentication to the rescue. 🔥
Having implemented in numerous projects, I feel this is the quickest, most versatile & economical way to integrate an authentication layer to your application.
Myriad of sign-in options are available to integrate into your application.
I went ahead with passwordless sign-in, which is similar to medium’s sign-in with email option.
This not just offers, a seamless experience, moreover, it also removes the need to remember passwords for your end-users & for you as a developer, to implement another “forgot password” & “verify email” workflow. Additionally ensuring, you always have genuine users of your platform
You can even opt-in for drop-in authentication solution from Firebase which will take care of your authentication workflow & also provides you a sleek UI.
Regardless of the solution you choose, you will need to configure the URL property for the “sendEmail” method we saw above & white-list the domain in Firebase console. This will redirect your users to the authorized section of your application upon successfully sign-in.
Send Email Screen 📨
Let’s create a simple reactive form to capture the following email related details & showcase our solution:
- Sender’s name
- Recipient’s name
- Recipient’s email ID
Add the much-needed validations, which come out of the box from angular.
Here, we have wired an action button to open a dialog & capture details. Validations we added above will ensure, no shady data is sent to the server. We also added an angular material snack-bar to render user messages. Currently, you see an error message because we don’t have a working backend for our UI.
We will get to it in a moment, till then:
Bonus Tip: Guard Your Application Routes⚔️
Are You Using Firebase Authentication? Write An Auth-Guard With Just 2 LINES Of CODE
Tired of writing verbose auth-guard code? Let’s explore the shortest way to secure your application routes with…
So far we have been successful in building a very secure & strong foundation for our application. Before we move on to create the backend, let’s go ahead & create an email-template that we’ll be using going forth.
Dynamic Email Templates:
A very indispensable part of this solution, which ultimately makes it very robust & re-usable is the ease with which we can generate & configure email templates.
Let’s now define:
- What content we want to send over to the user.
- Color scheme
SendGrid offers a simplistic yet feature-rich drag-drop interface to create templates. We will use the same to create one for our application.
Dynamic data can be set in the handlebars.
They got you covered on multiple recipients, dynamic footers & much more. Have a look at the complete set of dynamic parameters available for you here.
Any of the administration or marketing team members can now effortlessly focus on content creation & you as a developer can focus on what you do the best.
Bringing ideas to life.
You can have multiple transactional or marketing templates created in SendGrid & all you need is a template ID to send it through your backend.
How do we finally send some emails? 🚀
One instant thought would be to create a Node.js HTTP API endpoint, integrate it with a feasible & popular option like nodemailer & sent the emails away .
However, we are here to reduce the templating code & keep us away from the hassle of:
- Making HTTP requests, deserializing them.
- Interceptors to take care of authentication headers, token etc.
Remember, we want it quick & efficient.
Keeping this in mind, let’s develop the much awaited
Backend For Our Email Solution 🔧
We will create a cloud function to handle all the logic of:
- Receiving user parameters from the client application.
- Re-validation of user data.
- Ensuring only authorized users access the cloud function.
- Integration with SendGrid Mail API.
Features of this cloud function:
- Written in typescript.
- HTTPS callable function: Saves us time to verify user token coming in from the client-side & skips the heavy lifting of writing auth-verification code.
- We set the SendGrid API key & the template-ID securely as an environment variable in firebase. (Process to create your SendGrid API key)
- Testing & deploying is just a couple of clicks.
- Scaling & managing compute resources, according to the traffic received.
- Keeping it secure & private.
Security & scaling are the prime factors that motivate me to bring in cloud functions.
I love the concept of how easy it becomes to modularize your application according to functionality & have complete control over its performance & pricing.
Google Cloud functions offer a very generous free tier.
Moreover, whenever you want to reuse, let’s say in our case for the email-cloud function, you can easily wire it up with some other project & utilize it in a very decoupled fashion. Feeling micro-serviced?
Now that we have got all our major design pieces together, time to glue them all.
Cloud Function For Firebase & UI (Angular) Integration 🔌
We need a way to call the HTTPS callable cloud function we created above from our client-side application.
The “sendEmailNow” method below leverages the capabilities of “angularFireFunctions” class from the ‘@angular/fire/functions’ package. “httpsCallable” method returns an observable, to which we can easily set the necessary parameters & subscribe. Like we would have done for any other HTTP request.
Store your function name in the environment file for easy re-use.
With just one line of code, we can establish the communication between the client-side & backend piece of our application.📱📲
And that’s it, here is how the finished application looks like😎
Head over to HSDevstudio to see it live in action.
Bonus Tip: How to not end up paying 💰 for your cloud resources during development?
What else can we do to extend the application?
- You can add multiple recipients.
- Create a text-area on the send-email screen enabling the users to enter dynamic content.
- Create an upload image feature, allowing the users to send custom images or even send it over as attachments 📎.
I have open-sourced the complete codebase for you. Feel free to create a pull-request to extend or enhance the functionality further.
Grab the source-code, hit🌟 on the repository & start building.
- UI codebase (Do not forget to add your firebase config to angular environment)
- Cloud Function integrated with SendGrid (Setup your API keys in firebase config)
Hope you have learned something new today. Do appreciate with some claps. 👏👏
Connect with me on medium or LinkedIn for consultation.
Happy coding. 💻 #staySafe 😷
Like to create practical solution? We might use your quirky mind in our team! Join us in making the next life-centric digital solutions