Technical Articles
Send an email from a nodejs application
Hi All,
For a small business application we want to send e-mails from our nodejs application. In this blog post I will show you how you can use sap-cf-mailer based on nodemailer to send emails through an SMTP server defined in your destinations.
Test SMTP server
Instead of testing the code with your own email account and loading your mailbox full with test emails, you can use mailtrap as test SMTP server. It’s free for one inbox.
Create an account on mailtrap and create a new inbox. Open the inbox and take a look at the settings. All mails send over this SMTP server will be delivered here without sending them to the real receiver.
MAIL destination
We need to create a mail destination that links to our SMTP server.
In this destination we configured following properties:
- Name: a name for the destination
- Type: MAIL
- username and password from your mailtrap SMTP server
- mail.smtp: smtp server address
- mail.port: smtp server port
- mail.from: if there is no mail from specified in the code, we will use this email address to send the mails.
NodeJS application
To send mails, we first have to read this destination properties and then send them to the nodemailer library. To make things a lot easier, I created a new library that will read the destination service and add it to the nodemailer for you.
Your application needs a reference to a destination service to be able to read the mailtrap-destination. this is how my mta.yaml file looks like
ID: sap-cf-mailer-example
_schema-version: "2.1"
description: Example sap cf mailer
version: 0.0.1
modules:
- name: approuter
type: approuter.nodejs
path: approuter
parameters:
disk-quota: 256M
memory: 256M
requires:
- name: uaa
- name: destination_service
- name: mail_api
group: destinations
properties:
forwardAuthToken: true
name: mail_api
strictSSL: false
url: '~{url}'
- name: srv
type: nodejs
path: srv
parameters:
memory: 512M
disk-quota: 256M
provides:
- name: mail_api
properties:
url: ${default-url}
requires:
- name: uaa
- name: destination_service
resources:
- name: destination_service
type: org.cloudfoundry.existing-service
- name: uaa
type: org.cloudfoundry.existing-service
In the srv folder, just install the sap-cf-mailer library with:
$ npm install -s sap-cf-mailer
in your nodeJS application you can use it to send text or HTML emails.
const express = require('express');
const app = express();
const SapCfMailer = require('sap-cf-mailer').default;
const transporter = new SapCfMailer("MAILTRAP");
app.use(express.json());
app.get('/sendmail', async (req, res) => {
// use sendmail as you should use it in nodemailer
const result = await transporter.sendMail({
to: 'someoneimportant@sap.com',
subject: `This is the mail subject`,
text: `body of the email`
});
res.send(result);
});
const port = process.env.PORT || 3000;;
app.listen(port, function () {
console.log('myapp listening on port ' + port);
});
The result
After running the application you can check in the mailtrap inbox which email is sent to who!
So, now you can send emails in your nodejs cloud foundry application using the sap-cf-mailer module. For more advanced features like sending html emails and attachments your can consult the nodemailer documentation.
kr,
Joachim
Hi Joachim, thanks a lot for your post! As I'm quite new to cloud foundry deployment it took me quite some time to understand mta.yml configuration magic (especially "resources") but after all I was able to repeat your steps and got email from nodejs. please keep on posting!
Best regards,
Egor
Hi Joachim Van Praet
I'm trying to use nodemailer to send an email but it doesn't find the host. This host. The difference with your tutorial is that destination endpoint is SAP Cloud Connector and it's an on premiser server mail.
I'm trying to send the email with these options but it seems it doesn't work:
Hi sara moreno da silva ,
Unfortunately the connection is not working for onpremise destinations yet.
I will keep this in mind, when I have time I will add it.
Feel free to add this feature yourself and send me a pull request.
kr,
Joachim
Hi Joachim Van Praet
I'm trying to integrate the Gmail SMTP server instead of the Mailtrap.
I've tried several destination parameter combinations but was unable to make it work. it says.
This is my destination configuration
Hi Joachim,
thank you for this great description and the NPM Packages that make the consumption a breeze. I've added an example to my SAP Cloud Application Programming Model (CAP) demo application with this commit:
https://github.com/gregorwolf/bookshop-demo/commit/adf6836ce91d327267538080e5c4d69738597af4
The only pitfall that I run into was that the suggested properties in the MAIL destination doesn't fit to your names:
Did SAP change something here and we need an update for your NPM package?
Thanks Gregor,
I think SAP changed this.
I've adapted the properties in version 0.0.4.
old property names still work.
kr
Joachim
Hi Joachim,
thank you for the update. But it seems that your update isn't yet published to https://www.npmjs.com/package/sap-cf-mailer. I would suggest you add a GitHub Action to get it automatically published. Check out the example in: .github/workflows/npm-publish.yml.
CU
Gregor
Thanks a lot for your post!
We configured as well the mailtrap destination in our CF environment using the following parameters:
If the picture is not readable, the params are like this:
Name: mailtrap
Type: MAIL
Description: <does not matter>
Proxy Type: Internet
User: <as in the mailtrap login>
Password: <as in the mailtrap login>
Additional property - mail.smtp.from: <my email address>
Additional property - mail.smtp.host: smtp.mailtrap.io
Additional property - mail.smtp.port: 587
Joachim Van Praet is the package already able to connect to onPremise SMTP server ?
If not, is there any other way to use our own SMTP server in cloud foundry environment?
Hi Tim,
At this moment it is not possible to connect to onpremise smtp over cloud connector whit this lib.
You can try to fork the repo and add onpremise support.
nodemailer allows proxy config
https://nodemailer.com/smtp/proxies/
and in the index.ts file at line 27 you can try to read the proxy config and add it in the transport config. I do not know how to handle the authentication for the proxy here.
https://github.com/jowavp/sap-cf-mailer
kr,
Joachim
Hi Joachim Van Praet
Thank you for sharing this post.
I did follow the above steps, but while using my Outlook work account's SMTP configurations, in the destination service, with basic authentication, I'm getting the following error:
Is there any other way to configure, using my work account's SMTP, and consume it in the Cloud Project?
Thank you
Harsha
Hi Harsha,
I think you have to contact your mail box administrator for that.
Seems like basic authentication is disabled for you user.
Maybe you can try to use an SMTP from an email delivery solution (e.g. mailjet, sendgrid, ...)
kr,
Joachim
Hi Joachim,
Could you possibly make the project source code public? It would be really helpfull to see the bigger picture (from what i'm seeing here, you have a couple of projects: srv and approuter)
Thanks in advance and best regards
Mihai
Hi Joachim Van Praet
I am getting the error, VError: No service matches destination.
Do i need to add the destination in package.json inside cds requires?
Kindly help.
Thanks
Kanika
Hi Kanika,
could you find a solution. I have the same error.
Thanks!
Hi Oliver
Nop , I used UI5 to send email 🙂
Thanks
Kanika
Very very helpful. I needed to create a SMTP destination in BTP and couldn't figure out what to add for the SMTP server, etc. This blog solved the problem. Mailtrap is awesome!
THANK YOU JOACHIM!!
Shantanu.