Contribute to help us improve!
Are there edge cases or problems that we didn't consider? Is there a technical pitfall that we should add? Did we miss a comma in a sentence?
If you have any input for us, we would love to hear from you and appreciate every contribution. Our goal is to learn from projects for projects such that nobody has to reinvent the wheel.
Let's collect our experiences together to make room to explore the novel!
To contribute click on Contribute to this page on the toolbar.
Mailer Module
This module enables you to send emails in devon4node. It also provides a template engine using Handlebars.
It is a NestJS module that inject into your application a MailerService
, which is the responsible to send the emails using the nodemailer library.
Configuring
To configure the mailer module, you only need to import it in your application into another module. Example:
@Module({
...
imports: [
MailerModule.forRoot(),
],
...
})
Your must pass the configuration using the forRoot
or forRootAsync
methods.
forRoot()
The forRoot
method receives an MailerModuleOptions
object as parameter. It configures the MailerModule
using the input MailerModuleOptions
object.
The structure of MailerModuleOptions
is:
{
hbsOptions?: {
templatesDir: string;
extension?: string;
partialsDir?: string;
helpers?: IHelperFunction[];
compilerOptions?: ICompileOptions;
},
mailOptions?: nodemailerSmtpTransportOptions;
emailFrom: string;
}
Here, you need to specify the Handlebars compile options, the nodemailer transport options and the email address which will send the emails.
Then, you need to call to forRoot
function in the module imports. Example:
@Module({
...
imports: [
MailerModule.forRoot({
mailOptions: {
host: 'localhost',
port: 1025,
secure: false,
tls: {
rejectUnauthorized: false,
},
},
emailFrom: 'noreply@capgemini.com',
hbsOptions: {
templatesDir: join(__dirname, '../..', 'templates/views'),
partialsDir: join(__dirname, '../..', 'templates/partials'),
helpers: [{
name: 'fullname',
func: person => `${person.name} ${person.surname}`,s
}],
},
}),
...
})
forRootAsync()
The method forRootAsync
enables you to get the mailer configuration in a asynchronous way. It is useful when you need to get the configuration using, for example, a service (e.g. ConfigurationService
).
Example:
@Module({
...
imports: [
MailerModule.forRootAsync({
imports: [ConfigurationModule],
useFactory: (config: ConfigurationService) => {
return config.mailerConfig;
},
inject: [ConfigurationService],
}),
...
})
In this example, we use the ConfigurationService
in order to get the MailerModuleOptions
(the same as forRoot
)
Usage
In order to use, you only need to inject using the dependency injection the MailerService
.
Example:
@Injectable()
export class CatsService {
constructor(private readonly mailer: MailerService) {}
}
Then, you only need to use the methods provided by the MailerService
in your service. Take into account that you can inject it in every place that support NestJS dependency injection.
MailerService
methods
sendPlainMail
The method sendPlainMail
receive a string sends a email.
The method signatures are:
sendPlainMail(emailOptions: SendMailOptions): Promise<SentMessageInfo>;
sendPlainMail(to: string, subject: string, mail: string): Promise<SentMessageInfo>;
Examples:
this.mailer.sendPlainMail({
to: 'example@example.com',
subject: 'This is a subject',
html: '<h1>Hello world</h1>'
});
this.mailer.sendPlainMail('example@example.com', 'This is a subject', '<h1>Hello world</h1>');
sendTemplateMail
The method sendTemplateMail
sends a email based on a Handlebars template. The templates are registered using the templatesDir
option or using the addTemplate
method.
The template name is the name of the template (without extension) or the first parameter of the method addTemplate
.
The method signatures are:
sendTemplateMail(emailOptions: SendMailOptions, templateName: string, emailData: any, hbsOptions?: RuntimeOptions): Promise<SentMessageInfo>;
sendTemplateMail(to: string, subject: string, templateName: string, emailData: any, hbsOptions?: RuntimeOptions): Promise<SentMessageInfo>;
Examples:
this.mailer.sendTemplateMail({
to: 'example@example.com',
subject: 'This is a subject',
html: '<h1>Hello world</h1>'
}, 'template1', { person: {name: 'Dario', surname: 'Rodriguez'}});
this.mailer.sendTemplateMail('example@example.com', 'This is a subject', 'template1', { person: {name: 'Dario', surname: 'Rodriguez'}});
addTemplate
Adds a new template to the MailerService
.
Method signature:
addTemplate(name: string, template: string, options?: CompileOptions): void;
Example:
this.mailer.addTemplate('newTemplate', '<html><head></head><body>{{>partial1}}</body></html>')
Handlebars templates
As mentioned above, this module allow you to use Handlebars as template engine, but it is optional. If you do not need the Handlebars, you just need to keep the hbsOptions
undefined.
In order to get the templates form the file system, you can specify the template folder, the partials folder and the helpers. At the moment of module initialization, it will read the content of the template folder, and will register every file with the name (without extension) and the content as Handlebars template. It will do the same for the partials.
You can specify the extension of template files using the extension
parameter. The default value is .handlebars
Local development
If you want to work with this module but you don’t have a SMTP server, you can use the streamTransport
. Example:
{
mailOptions: {
streamTransport: true,
newline: 'windows',
},
emailFrom: ...
hbsOptions: ...
}
Then, you need to get the sendPlainMail
or sendTemplateMail
result, and print the email to the standard output (STDOUT
). Example:
const mail = await this.mailer.sendTemplateMail(...);
mail.message.pipe(process.stdout);