Loading handlebar templates for sending emails with nodemailer from a remote server is simple and straightforward

I currently have a nestjs application with a POST /email endpoint that utilizes nodemailer to send emails based on handlebar templates. The template used depends on the selection made in the API call (template=xxx).

For example,

http://localhost:3000/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="93f6fef2fafface7fcaee7f6e0e7d3f4fef2faffbdf0fcfe">[email protected]</a>&name=John&template=email2

Currently, these handlebar templates are stored statically in a folder named ./templates. However, I am looking to load these templates from a remote location such as an S3 bucket instead. This change would allow me to easily add, edit, and delete templates as needed.

The proposed process is outlined in the following sequence diagram:

https://i.stack.imgur.com/5p0ZD.png

Is it possible to achieve this setup? Are there alternative approaches that could be considered?

The existing NestJs configuration is quite simple and is based on the guidelines provided in this tutorial here. The static handlebar templates are located in the src/template folder.

// app.module.ts
@Module({
    imports: [
        ConfigModule.forRoot(),
        MailerModule.forRootAsync({
            imports: [ConfigModule],
            useFactory: async (config: ConfigService) => {
                return {
                    transport: {
                        host: config.get('EMAIL_HOST'),
                        secure: false,
                        auth: {
                            user: config.get('EMAIL_USER'),
                            pass: config.get('EMAIL_PASSWORD'),
                        },
                    },
                    defaults: {
                        from: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="3851565e57784c5d4b4c165c5d">[email protected]</a>',
                    },
                    template: {
                        dir: join(__dirname, './templates'),
                        adapter: new HandlebarsAdapter(),
                        options: {
                            strict: true,
                        },
                    },
                };
            },
            inject: [ConfigService],
        }),
    ],
    controllers: [AppController],
    providers: [AppService],
})
export class AppModule {}
// app.controller.ts
@Controller()
export class AppController {
    constructor(private mailerService: MailerService) {}

    @Post('/email')
    async getHello(
        @Query('to') to: string,
        @Query('name') name: string,
        @Query('template') template: string,
    ): Promise<SentMessageInfo> {
        const info = await this.mailerService.sendMail({
            to,
            subject: 'Greeting from NestJS NodeMailer',
            template,
            context: {
                name,
            },
        });
        console.log('Preview URL: %s', getTestMessageUrl(info));
    }

Answer №1

To achieve this, one method is to retrieve the templates as a string. For example, if you store your template in S3, you can fetch or download the template from there. Then, you can extract the content and use the compile function (here) to convert the string into an HBS template. This process could be implemented within your getHello function.

A helpful tutorial on using compile can be found here. Essentially, all you need to do is fetch your .txt or .hbs file and compile it.

Alternatively, if you are already downloading the file, another approach would be to save it in the templates folder and access the template directly from the .hbs file. However, I have not personally tried this method myself.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Exploring the integration of Stripe Checkout with React and Express.js

Seeking assistance with integrating Stripe Checkout into my React application. I need to create a route in my nodejs/express server that will provide the session id required for setting up Stripe Checkout on the front end. The aim is to redirect users to s ...

Maintaining personalized variable values for individual connected clients in Node.js: What's the best approach?

I have recently started working with Node.js and I am using Visual Studio 2015 with the Basic Node.js Express 4 app template. After setting some values through a post request from the client, I noticed that when I open another tab and send another post re ...

Even after shutting down my PeerConnection, the black screen persists. I would appreciate assistance in resolving this issue

Welcome to the Room.js Client Side Code! import React, { useEffect, useRef, useState } from "react"; import io from "socket.io-client"; import Peer from "simple-peer"; import styled from "styled-components"; const C ...

Failure to establish a cross-origin connection with socket.io on an express.io server

I'm currently working on configuring socket.io to establish a connection with a stream server from a different origin. The stream server is dedicated and forms a part of a larger setup, built on Express.io: var express = require('express.io&apo ...

The program 'node.exe' could not be initiated as it was not located in the PATH directory

When attempting to execute the following command in my VS Code terminal: $ node -v I encounter the error message: winpty: error: cannot start 'node.exe': Not found in PATH Interestingly, running the same command in the standard Command Prompt ...

NodeJS file execution through a stored procedure

Everything I've come across regarding the topic revolves around using a NodeJS program to call a stored procedure. Inquiring: Is it feasible to reverse this process? Can a stored procedure be designed to call/execute a NodeJS file/program instead? I& ...

Numerous applications within our parse-server ecosystem

Is there a solution available for running multiple applications on a single parse-server? If so, what would be the best approach to transfer existing data from multiple parse servers while ensuring that the IDs and other relationships remain intact? For ...

Is there a way to transfer a document from Node.js to an EJS template?

I am looking to retrieve a specific file and pass it to an embedded JavaScript (ejs) template. Can someone guide me on how to successfully transfer the file from a node endpoint to the embedded JavaScript template? ...

What is the best method for transforming a string into JSON format using Node.js?

Looking for assistance in listing the data from a CSV file stored in S3 using Node.js code. Below is the provided code, but I am seeking help to achieve the expected output as shown: CODE: const AWS = require('aws-sdk'); const fs = require(&apo ...

Utilizing Mongoose for incorporating embedded documents within forms

Within my Mongoose schema named Question, I have a straightforward setup for storing questions and their corresponding answers. Answers are defined in a separate schema and stored as embedded documents within the Questions collection. Below is the outline ...

I'm encountering an issue where the npm install process is getting stuck while attempting to extract the xxxx package

When running the sudo npm install command on my local machine, everything works fine. However, once I pulled the code into an EC2 Ubuntu machine, the npm install process gets stuck at a certain point. The output shows "sill doParallel extract 1103" and I ...

Is it a good idea to utilize triggers when bootstrapping an application?

Currently, I am in the process of developing an internal web application for managing building parts. The main focus is on a table containing projects that are interconnected with other tables. Whenever a new project is created by a user, my goal is to ini ...

Guide on exporting values from a Promise within an imported module

Recently, I encountered a challenge where I needed to integrate a pure ESM package into a non-module. Unfortunately, modifying the script to accommodate this requirement was not an option. To tackle this issue, I turned to using the import() function (als ...

Utilizing Node.js and Express for creating efficient routes

I created an API using Express. Within my routes file, I have: app.route('/getBalances') .post(api.getBalances); The api.getBalances function determines the correct controller to load and invokes its getBalances method based on a parame ...

The call stack in mongodb has surpassed its maximum size limit

I am currently executing a method. Method execution var message = "Hello" function1("78945612387", message, null, "Portalsms") Node JS Code function function1(mobileno,body,logExtraInfo,messageType){ request(uri, function (error, resp ...

Using csv-parse to process data efficiently without the need for a repetitive

Currently, I am utilizing the csv-parse Node package for CSV string parsing purposes. According to the documentation, reading the parsed result can be done with code similar to this: const output = [] parse(` "1","2","3" "a","b","c" `) .on('reada ...

Tips for incorporating the "define" function into your Mocha testing

Starting my journey with JavaScript testing, I made the decision to use Mocha. The specific modules I am looking to test are AMD/RequireJS. However, it appears that Mocha only works with CommonJS modules. Consequently, when trying to run it, I encounter t ...

Knejx Js is the embodiment of guarantees

I am trying to figure out how to make this function work. I only receive a promise as the output. codeProducts.forEach((code, index) => { const qt = app.db('products').where('code', code).first().then(result => result.quanti ...

What are effective ways to bypass proxy configurations when setting up npm and its corresponding plugins?

I'm facing a challenge with the proxy settings on my machine as I am not authorized to make changes to them. Despite this, I have installed node.js. Is there a method to override proxy and https-proxy settings via code so I can successfully install np ...

"Utilizing the power of Node.js to perform SQL queries with

I'm having trouble with this SQL query that uses INNER JOIN. The query is returning an error. connection.query("SELECT caracavis.caracname FROM caracavis WHERE firstcaturl ='" + req.body[0].firstcatname + "' AND secondcaturl = '" + r ...