Sending Emails from Express Application
by John Vincent
Posted on July 1, 2017
This is not a trivial task. Let's discuss.
Sending emails from an Express Application is a standard requirement.
Nodemailer
npm package Nodemailer is the standard.
npm install nodemailer --save
Gmail variables are defined in the environment. Thus, to access
email.js
const {
GMAIL_SERVICE, GMAIL_AUTH_TYPE, GMAIL_AUTH_USER, GMAIL_AUTH_CLIENT_ID, GMAIL_AUTH_CLIENT_SECRET,
GMAIL_AUTH_REFRESH_TOKEN, GMAIL_AUTH_ACCESS_TOKEN, GMAIL_FROM_EMAIL, GMAIL_SUPPORT_EMAIL
} = process.env;
All email tasks are performed in class EmailUtils
, email.js
const nodemailer = require('nodemailer');
The actual sending of the email
sendEmail(emailData) {
let auth = {
"type": GMAIL_AUTH_TYPE,
"user": GMAIL_AUTH_USER,
"clientId": GMAIL_AUTH_CLIENT_ID,
"clientSecret": GMAIL_AUTH_CLIENT_SECRET,
"refreshToken": GMAIL_AUTH_REFRESH_TOKEN,
"accessToken": GMAIL_AUTH_ACCESS_TOKEN
};
const transporter = nodemailer.createTransport({
service: GMAIL_SERVICE,
auth
});
logger.info(`Attempting to send email from ${emailData.from}`);
transporter
.sendMail(emailData)
.then(info => console.log(`Email sent: ${info.response}`))
.catch(err => console.log(`Problem sending email: ${err}`));
}
emailData
has a specific structure
const subject = 'Subject';
const text = template.replace('{{email_url}}', email_url);
const html = `<p>Html email </p><ul><li>Name: abcd</li><li>Email: abc@def.com</li><li>Message: Hi</li></ul>`;
var mailOptions = {
from: '"My Title"' + GMAIL_FROM_EMAIL,
to,
subject,
text
};
Note that Html is optional, if it is not defined the text variable will be used.
Nodemailer Configuration
Nodemailer OAuth2 document is a good reference. I will configure using 3. Set up 3LO authentication
Gmail Configuration
This YouTube video was nearly there.
This is slightly useful
The Gmail variables are stored in the environment
GMAIL_SERVICE=Gmail
GMAIL_AUTH_TYPE=OAuth2
GMAIL_AUTH_USER=<gmail address used for the authentication, see below>
GMAIL_FROM_EMAIL=email@johnvincent.io
GMAIL_SUPPORT_EMAIL=support@johnvincent.io
GMAIL_AUTH_CLIENT_ID
GMAIL_AUTH_CLIENT_SECRET
GMAIL_AUTH_REFRESH_TOKEN
GMAIL_AUTH_ACCESS_TOKEN
- Google API Manager
- Select or add a project,
Project = johnvincentio
- Gmail API 4. Enable
- Credentials
- OAuth consent Screen. 6. Product name: your Project 7. Save
- Credentials
- Create Credentials
10. OAuth client id
11. Web Application,
name = johnvincentio
12. or maybe: Other,name = johnvincentio
12. Authorized redirect URIs: 13. https://developers.google.com/oauthplayground/ 14. Create> 15. Copy theclientId
toGMAIL_AUTH_CLIENT_ID
16. CopyclientSecret
toGMAIL_AUTH_CLIENT_SECRET
- Google Developers OAuth 2.0 Playground
- Click gear icon (top right)
- Check: Use your own OAuth credentials
- Enter the client id and Client Secret fields from OAuth Client id (same as above).
- Left pane, input your own scopes
17. https://mail.google.com
18. Authorize APIs
19. Allow my email address to access my email.
20. Exchange authorization code for tokens.
21. Check: Auto-refresh the token before it expires
22. Copy refresh token to
GMAIL_AUTH_REFRESH_TOKEN
Extra Gmail Addresses using G Suite
- Login to Gmail
- Settings
- Accounts
- Add another email address 5. support@johnvincent.io 6. Check: treat as an alias 7. Specify a different “reply-to” address 8. Reply to address: 9. support@johnvincent.io 10. next step>>> 11. send verification> 12. Email will arrive. Click on the link 13. Confirm> 14. Refresh Gmail 15. Settings 16. Accounts
Repeat for email@johnvincent.io
Random Strings
email.js
const randomstring = require('randomstring');
To create the URL
userTaskEmail(id, req, to) {
let random = randomstring.generate({
length: 20,
charset: 'alphanumeric'
});
let email_url = `${req.protocol}://${req.get('host')}/user/a/b/${id}/${random}`;