Skip to Content
Technical Articles
Author's profile photo Ahmet Demirlicakmak

Connecting On Premise Mail Destination and Sending Email Using SAP Cloud SDK JavaScript Version 3 on SAP CAP

 

Hello SAP Community.

This blog post will provide a solution for many faced when developing their business application.

How to connect On-premise SAP BTP destination through a NodeJS application to send email using Cloud Application Programming CAP?

Solutions to these problem were successful for scenarios by Joachim van Praet either creating our own destination in BTP using SMTP providers like Mailtrap, which was not suitable for our use case because it is not on-premise solution.

Other solution provided by Niklas Miroll is tackling the scenario through BTP Cloud Foundry using Java successfuly, but our tech stack was Javascript / NodeJS.

To find a solution, I have checked out the announcement from Marika Marszalkowski and this section of the post about newest updates fascinated me.

 

Sending Emails

We recently released experimental functionality to send e-mails against SAP BTP destinations of type “MAIL”.
In version 3 we will make it available for productive use.
You can find more details in the mail documentation.

After I read the documentation and understand it, I have created a new project to test this feature. And with a simple configuration, you can now connect your on premise mail servers successfully thanks to the wonderful developers of SAP Cloud SDK Team.

 

Let’s move step by step to show how to perform it in a simple CAP application from scratch.

 

1.Requirements – BTP Services Necessary In Setup Account

These are free services on BTP, so it means everyone can test what we perform with a Trial account:

  • Authorization and Trust Management Service
  • Destination Service
  • Connectivity Service

IDE to make our app work is running in SAP Business Application Studio. 

We also need to generate service instance keys for each of those services to test our application. Check image below how to create service instance key aft

I have generated those services and service keys with a naming convention as follows. First parameter is service instance name, second parameter is service instance key. I have created those in BTP as you can see Authorization and Trust Management service below, and complete the rest.

 

mail-xsuaa , mail-xsuaa-key

mail-destination , mail-destination-key

mail-connectivity, mail-connectivity-key

 

Setting%20up%20BTP%20Service%20Instance%20and%20Service%20Key%20in%20BTP%20Cockpit

Figure 1 : Setting up BTP Service Instance and Service Key in BTP Cockpit – Click to Enlarge

 

Destination configuration is very important to handle, in this example we are using SMTP server for Gmail and its configuration is as below in our BTP Destination.

With the ‘New Property’ Tab, you can add more properties or delete the extra ones that are not necessary for your configuration.The destination you are calling should be type ‘MAIL’ and must be configured correctly.

Here is an example for you:

Figure 2 : SMTP Destination Configuration in BTP Subaccount – Click to Enlarge

 

Additional properties we set up in the image that are not clearly visible is as below for this usecase is as below. Please note the configuration may change for different SMTP Server Providers:

mail.smtp.from=<enter e-mail address to send email from here>
mail.smtp.ssl.checkserveridentity=true
mail.smtp.starttls.enable=true
mail.smtp.starttls.required=true
mail.transport.protocol=smtp9
tokenServiceURLType=Dedicated (optional field)

     2. Create a New Project

Open Business Application Studio. Click the top left pane red highlighted>File>New Project From Template.

Figure 3 : Initial Project Setup in SAP Business Application Studio – Click to Enlarge

 

Then choose CAP Project and click Start.

Figure 4 : Choosing CAP Project will Provide Necessary Development Runtime

 

Set your project configuration as below image and click Finish.

Figure 5 :Minimal Features Addition to Run Project

 

3) Fill In Project With Packages and Add Custom Logic

package.json file

We have an empty project with a backbone configuration. An empty db folder, an empty srv folder, a package.json file and mta.yaml file which are important. We will fill those step by step.

  • Go to package.json file. Open the terminal from Terminal > New Terminal and download dependencies generated by CAP Wizard with
npm install​
  • We have installed pregenerated packages, but we need to add 4 more packages to make our BTP services and mail service work. These packages can be installed consecutively through these commands
npm install @sap-cloud-sdk/mail-client
npm install @sap-cloud-sdk/connectivity
npm install @sap/xssec​
npm install passport

 

Mail client package is the newest package from Sap Cloud SDK that provides necessary configuration for on-premise mail handling. Connectivity package is necessary to handle connectivity with on-premise destination. Xssec and passport are necessary to handle authentication.

 

  • To call our destination, we need to add our destination details to the package.json file. This cds requires block should be added after rules block to the package.json, to the end of the package.json file. Here is the full package.json file also for convenience.
"cds": {
    "requires": {
      "[hybrid]": {
        "auth": {
          "kind": "xsuaa"
        },
        "mailService": {
          "kind": "rest",
          "credentials": {
            "destination": "mail_destination",
            "forwardAuthToken": true
          }
        }
      }
    }
  }
{
  "name": "mail-on-premise",
  "version": "1.0.0",
  "description": "A simple CAP project.",
  "repository": "<Add your repository here>",
  "license": "UNLICENSED",
  "private": true,
  "dependencies": {
    "@sap-cloud-sdk/connectivity": "^2.14.0",
    "@sap-cloud-sdk/mail-client": "^2.14.0",
    "@sap/cds": "^6",
    "@sap/xssec": "^3.2.17",
    "express": "^4",
    "passport": "^0.6.0"
  },
  "devDependencies": {
    "sqlite3": "^5.0.4"
  },
  "scripts": {
    "start": "cds run"
  },
  "engines": {
    "node": "^16.15"
  },
  "eslintConfig": {
    "extends": "eslint:recommended",
    "env": {
      "es2020": true,
      "node": true,
      "jest": true,
      "mocha": true
    },
    "globals": {
      "SELECT": true,
      "INSERT": true,
      "UPDATE": true,
      "DELETE": true,
      "CREATE": true,
      "DROP": true,
      "CDL": true,
      "CQL": true,
      "CXL": true,
      "cds": true
    },
    "rules": {
      "no-console": "off",
      "require-atomic-updates": "off"
    }
  },
  "cds": {
    "requires": {
      "[hybrid]": {
        "auth": {
          "kind": "xsuaa"
        },
        "mailService": {
          "kind": "rest",
          "credentials": {
            "destination": "mail_destination",
            "forwardAuthToken": true
          }
        }
      }
    }
  }
}

 

srv folder

  • Create a mail.cds file inside srv folder. Call db file with this simple service
service MailService {
    action sendmail();
}

 

  • Create mail.js file inside srv folder. We are adding our custom logic here and mail client configuration.
const { sendMail } = require('@sap-cloud-sdk/mail-client');

module.exports = srv =>
  srv.on("sendmail", async (req) => {
    const mailConfig = {
      to: 'ahmet.demirlicakmak@aarini.com',
      subject: 'Test On Premise Destination',
      text: 'If you receive this e-mail, you are successful.'
    };
    sendMail({ destinationName: 'mail_destination' }, [mailConfig]);
  });​

 

 

project root

  • Create a test.http file in the project root and fill it as below.
### // Check mail
POST http://localhost:4004/mail/sendmail
Content-Type: application/json
{}

 

4) Connect to Your BTP Services in Hybrid Profile

  • We will test sending e-mail in hybrid profile. Our reasoning is clearly defined in Capire documentation and the reasoning behind using it is as below:
  1. Saving time and effort: We can test new features locally
  2. Particularly selecting individual or combination of services: Although we may need to define many services in deployment, in hybrid approach we have flexibility to use only the ones we are interested.

To bind our service instances to our application, open the terminal and bind each of below service instancess step by step.

cds bind -2 mail-xsuaa:mail-xsuaa-key
cds bind -2 mail-destination:mail-destination-key
cds bind -2 mail-connectivity:mail-connectivity-key

 

5) Final Step – Test Your Application

Start your application with service instance bindings with command

cds watch --profile hybrid

Go to your test.http file and click Send Request shaded in gray.

Figure 6 : Simple CAP Tool to send HTTP Request

 

Now check your e-mail. We want to receive e-mail with subject and text you have filled in mail.js file instantly.

Figure 7 : Open the E-mail Address Provided in mail.js File

6) Conclusion

If you have successfully followed up, you have received an e-mail from your SAP BTP On-Premise destination using SAP Cloud SDK and CAP.

To summarize, you have learned how to set up a simple CAP Project, consuming necessary BTP Services in hybrid mode, how SAP Cloud SDK is used with CAP and connecting on-premise mail servers.

Feel free to share and comment on this post for troubleshooting when necessary. Find the resources about SAP CAP and SAP Cloud SDK in below topics and make sure to follow to be notified with latest use cases:

For Cloud Application Programming – Click Here

For SAP Cloud SDK – Click Here

Assigned Tags

      10 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Preeti Mayank
      Preeti Mayank

      Hi Ahmet,

      Great blog.

      We have tried same way to trigger the mail from CAP project but our mails are going to Junk folder not in Inbox. Can you help with that.

      Also can you share the destination properties in Details.

      Regards,

      Preeti

      Author's profile photo Ahmet Demirlicakmak
      Ahmet Demirlicakmak
      Blog Post Author

      Hi Preeti.

      I have updated the blog post with the additional parameters configuration for the destination to try and test. Please share the results then if it worked or not.

      All the best,

      Ahmet

      Author's profile photo Niklas Miroll
      Niklas Miroll

      Hi Preeti,

      regarding emails arriving in the junk folder: this presumably is not the fault of the SDK as the categorisation is determined by the receiving mail server. Usually factors such as subject and content length, email attributes (such as alt texts, return addresses, etc.) and sender address are used to decide whether an email might be junk or not.

      If you know the recipient and you don't find another way to influence the receiving mail server's behaviour, they could probably also create a rule to not mark your sender email as junk.

      Best regards,
      Niklas

      Author's profile photo Niklas Miroll
      Niklas Miroll

      Hi Ahmet,

      great use of the Cloud SDK functionalities! That would have saved me some work if it had been available 🙂

      Since you mention my blog you might want to include a small notice regarding a major restriction: this only works for sending emails. Retrieving emails (which in my opinion is the trickier part) is not supported by the Cloud SDK. Since your title is "Connecting On Premise Mail Destination [...]" this might be misleading to some.

      Best regards,
      Niklas

      Author's profile photo Ahmet Demirlicakmak
      Ahmet Demirlicakmak
      Blog Post Author

      Hi Niklas.

      Thank you for your necessary input. I am changing the headline based on your suggestion.

      All the best...

      Author's profile photo Junjie Tang
      Junjie Tang

      Thanks Ahmet Demirlicakmak , for sharing your experience.

      The SAP Cloud SDK for JavaScript has released the version 3 (here is the blog post ), and the mail client has been officially published.

      Author's profile photo Vipin Ojha
      Vipin Ojha

      Hi Ahmet Demirlicakmak,

      Thanks for sharing the blog.

      It has helped us to send emails from SAP CAPM projects.

      I am facing one issue with this, It's able to send emails successfully to the same organization's email id's but when we are trying to send the email to external email id's or Gmail we are not getting emails.
      Can you please help me with this?

      Thanks and Regards,
      Vipin Ojha

      Author's profile photo Ivan Mirisola
      Ivan Mirisola

      https://answers.sap.com/answers/13842171/view.html

      Author's profile photo Ivan Mirisola
      Ivan Mirisola

      Hi Ahmet Demirlicakmak,

      Would you mind to add a Note about the requirements to send out e-mails to other e-mail domains thru the smtp service.

      Please read my answer to Vipin:

      https://answers.sap.com/answers/13842171/view.html

      Best regards,
      Ivan

      Author's profile photo Martin Stenzig
      Martin Stenzig

      I tried the same approach and tried to specify an Office 365 mailbox, but fail miserably with the error: he destination 'name: [my name]' does not contain host or port information as properties. Please configure in the "Additional Properties" of the destination.

      I used the process automation documentation (https://help.sap.com/docs/build-process-automation/sap-build-process-automation/configuring-smtp-mail-destination) to setup my destination.

      The big difference to your example is that Office365 does not work with type: Basic Auth, but requires type: OAuth2Password

       

      Any idea?