Sending Emails from SAP CAP Applications Using Microsoft 365 & Microsoft Graph API
Share

[[{“value”:”

In this blog, we will learn how to send emails from an SAP Cloud Application Programming Model (CAP) application using Microsoft Graph API.

Instead of storing Microsoft credentials directly in the CAP application, we will configure the OAuth credentials in an SAP BTP Destination and let the SAP Cloud SDK use that destination when calling Microsoft Graph.

The complete flow looks like this:

MaheshSirsat_0-1789131115260.png

The CAP application will expose a simple action:

MaheshSirsat_1-1789131115270.png

We can then call this action from Postman, another application, or another backend process.

Prerequisites

Before starting, make sure you have:

  • Microsoft work account
  • Microsoft 365 / Exchange Online mailbox
  • Permission to create an App Registration
  • Permission to grant admin consent for API permissions
  • SAP BTP account
  • SAP CAP Node.js application

Security note: Never publish your actual Client Secret, Tenant ID, or other sensitive credentials in a GitHub repository or SAP Community article.

Part A – Configure Microsoft Entra ID

Step 1 – Open Microsoft Azure Portal

Open the Microsoft Azure Portal and sign in using your Microsoft work or school account.

Search for and open:

Microsoft Entra ID

MaheshSirsat_20-1789131297037.png

Step 2 – Get the Tenant ID

Inside Microsoft Entra ID, open the tenant overview.

You will find the Tenant ID.

MaheshSirsat_3-1789131115287.png

Copy this value and keep it safely because we will use it later when configuring the SAP BTP Destination.

What is Tenant ID?

The Tenant ID identifies your Microsoft Entra organization.

Step 3 – Register an Application

Navigate to: Microsoft Entra ID → App registrations

MaheshSirsat_4-1789131115289.png

Select: New registration

For this example, we will use:

Application name: SAP-CAP-Mail-Sender

Supported account types

Microsoft provides different options when registering an application.

The available options include scenarios such as:

  • Accounts in this organizational directory only
  • Accounts in any organizational directory
  • Accounts in any organizational directory and personal Microsoft accounts
  • Personal Microsoft accounts only

For this implementation, select:

Accounts in this organizational directory only

Why do we choose Single Tenant?

Our CAP application is intended to communicate with a mailbox belonging to one Microsoft 365 organization.

We therefore don’t need users from other Microsoft Entra tenants to authenticate with this application.

A single-tenant application keeps the application scoped to the organization’s own Microsoft Entra directory.

For a multi-tenant SaaS application, the design would be different and a multi-tenant registration could be considered.

For this use case, select the single-tenant option and click Register.

For Redirect URI, we don’t need to configure one for this server-to-server client-credentials scenario.

MaheshSirsat_5-1789131115297.png

Step 4 – Collect Application Information

After registration, open:

SAP-CAP-Mail-Sender → Overview

You will find:

  • Application (client) ID
  • Directory (tenant) ID

Copy both values.

MaheshSirsat_6-1789131115300.png

Your configuration notes should now look like:

Microsoft Graph Configuration

=============================

Application Name: SAP-CAP-Mail-Sender

Client ID: <your-client-id>

Tenant ID:<your-tenant-id>

Step 5 – Create a Client Secret

Navigate to: Certificates & secrets

Under Client secrets, select: New client secret

MaheshSirsat_7-1789131115308.png

Provide a description such as:  SAP CAP Mail Integration

Select an expiration period according to your organization’s policy.

Click Add.

MaheshSirsat_8-1789131115308.png

Microsoft will display information including:

  • Description
  • Secret ID
  • Value
  • Expiration

Important

Copy the Value immediately.

The secret value is only displayed when the secret is initially created.

The Secret ID is not the value that the application uses for authentication.

Your configuration notes should now look like:

Microsoft Graph Configuration

=============================

Client ID: <your-client-id>

Tenant ID: <your-tenant-id>

Client Secret: <your-client-secret>

Security

Do not place the client secret in:

  • GitHub
  • CAP source code
  • Frontend JavaScript
  • package.json
  • Public configuration files

For this architecture, the credentials will be maintained in the SAP BTP Destination.

Step 6 – Configure Microsoft Graph API Permissions

Now open: API permissions → Add a permission

Select: Microsoft Graph

Then select:  Application permissions

MaheshSirsat_21-1789131480745.png

Why Application Permissions?

Our CAP backend needs to send an email without requiring a user to be interactively logged in.

The flow is:

MaheshSirsat_10-1789131115347.png

There is no browser-based user authentication involved when the CAP backend calls Graph using the client-credentials approach.

Therefore, we use Application permissions for this app-only scenario.

Step 7 – Add Mail.Send Permission

Under Application permissions, search for: Mail.Send

Expand: Mail

Select: Mail.Send

Then click: Add permissions

MaheshSirsat_11-1789131115350.png

The permission allows the registered application to send email using Microsoft Graph.

Step 8 – Grant Admin Consent

Application permissions require administrator consent.

If you have the required administrator privileges, grant consent for the organization.

After consent has been successfully granted, the permission should show as granted for the tenant.

MaheshSirsat_12-1789131115352.png

Without the required consent, the CAP application will not be able to obtain the required application access to Microsoft Graph.

Important Security Consideration

At this point, the application has the:

Mail.Send

application permission.

Depending on the organization’s Microsoft 365 configuration, this can provide broad mail-sending capability.

For a production implementation, the Microsoft 365 administrator should consider restricting the application to only the mailbox or mailboxes that the application actually needs.

This is especially important when using application permissions because the application is not acting on behalf of an individual interactive user.

At this point, Your configuration notes should now look like:

Microsoft Graph Configuration
=============================
Application Name: SAP-CAP-Mail-Sender
Tenant ID: <YOUR_TENANT_ID>
Client ID: <YOUR_CLIENT_ID>
Client Secret: <YOUR_CLIENT_SECRET>
Sender Email: <YOUR_MAILBOX>
Graph Permission: Mail.Send
Admin Consent: Granted

Step 9 – Identify the Sender Mailbox

We now need a Microsoft 365 mailbox from which the application will send emails.

For example: sender@yourcompany.com

The mailbox will later be referenced in the Microsoft Graph endpoint:

/v1.0/users/<sender-mailbox>/sendMail

Microsoft Configuration Completed

At this point, Your configuration notes should now look like:

Microsoft Graph Configuration
=============================
Application Name: SAP-CAP-Mail-Sender
Tenant ID: <YOUR_TENANT_ID>
Client ID: <YOUR_CLIENT_ID>
Client Secret: <YOUR_CLIENT_SECRET>
Sender Email: <YOUR_MAILBOX>
Graph Permission: Mail.Send
Admin Consent: Granted

Part B – Configure SAP BTP Destination

Now that Microsoft Entra ID and Microsoft Graph are configured, we can connect the SAP CAP application to Microsoft Graph through an SAP BTP Destination.

Navigate to:

SAP BTP Cockpit → Connectivity → Destinations

Create a new destination.

Use the following configuration pattern:

Name: MS_GRAPH_MAIL

Type: HTTP

URL: https://graph.microsoft.com

Proxy Type: Internet

Authentication:OAuth2ClientCredentials

Configure the OAuth credentials: Client ID(<YOUR_CLIENT_ID> )

Client Secret:<YOUR_CLIENT_SECRET>

For the token service URL, use:

https://login.microsoftonline.com/<TENANT_ID>/oauth2/v2.0/token

Add the OAuth scope: https://graph.microsoft.com/.default

The .default scope tells Microsoft Entra ID to issue a token containing the application permissions that have already been configured and consented for the application.

After completing the configuration, the destination should contain the required connectivity and authentication information.

MaheshSirsat_13-1789131115354.jpeg

 

Why use a BTP Destination?

Instead of writing credentials directly inside the CAP application, the application only refers to:

destinationName: “MS_GRAPH_MAIL”

The SAP Cloud SDK resolves the destination and uses the configured authentication details when making the request.

This keeps authentication configuration outside the application source code and makes it easier to manage between environments.

Part C – Create the CAP Mail Service

Now let’s expose an action from our CAP service that accepts:

  • Recipient
  • Subject
  • Body

For example:

action sendMail(     to: String,     subject: String,    body: String ) returns String;

MaheshSirsat_14-1789131115356.png

 

This allows another application or API client to call the CAP service and request an email to be sent.

Step 10 – Install SAP Cloud SDK HTTP Client

From the CAP project directory, install:

npm install @SAP-cloud-sdk/http-client

We will use the HTTP client to execute the request through the BTP Destination.

Step 11 – Implement the CAP Action

The implementation performs the following operations:

  1. Read the action parameters.
  2. Validate the recipient, subject, and body.
  3. Identify the sender mailbox.
  4. Build the Microsoft Graph sendMail endpoint.
  5. Create the Microsoft Graph mail payload.
  6. Call Microsoft Graph through the BTP Destination.
  7. Return the result to the caller.

this.on(“sendMail”, async (req) => {

try {
const { to, subject, body } = req.data;

// 1. Validate input
if (!to) {
return req.error(400, “Recipient email is required”);
}

if (!subject) {
return req.error(400, “Email subject is required”);
}

if (!body) {
return req.error(400, “Email body is required”);
}

// 2. Sender mailbox
const senderEmail = “your-sender@yourcompany.com”;

// 3. Microsoft Graph API URL
const graphUrl = `/v1.0/users/${encodeURIComponent(senderEmail)}/sendMail`;

// 4. Microsoft Graph request body
const mailPayload = {
message: {
subject: subject,
body: {
contentType: “HTML”,
content: body
},
toRecipients: [
{
emailAddress: {
address: to
}
}
]
},
saveToSentItems: true
};

// 5. Call Microsoft Graph through BTP Destination
const response = await executeHttpRequest(
{
destinationName: “MS_GRAPH_MAIL”
},
{
method: “POST”,
url: graphUrl,
headers: {
“Content-Type”: “application/json”
},
data: mailPayload
}
);

// 6. Successful response
console.log(“Microsoft Graph response:”, response.status);
return “Email sent successfully”;
} catch (error) {
console.error(“Microsoft Graph email error:”, error.response?.data || error.message );

return req.error(
500,
“Failed to send email: ” +
(error.response?.data?.error?.message ||
error.message)
);
}
});

MaheshSirsat_15-1789131115358.png

Understanding the Important Part

The most important part of the implementation is:

const response = await executeHttpRequest(
{
destinationName: “MS_GRAPH_MAIL”
},
{
method: “POST”,
url: graphUrl,
headers: {
“Content-Type”: “application/json”
},
data: mailPayload
}
);

The CAP application does not directly contain the OAuth token-generation logic.

This separation makes the application code simpler and keeps the authentication configuration in the BTP environment.

Step 12 – Configure the Sender Email

In the implementation:

const senderEmail = “your-sender@yourcompany.com”;

Replace this with the Microsoft 365 mailbox that the application is configured to use.

The mailbox becomes part of the Microsoft Graph endpoint:

/v1.0/users/sender@example.com/sendMail

Step 13 – Bind the Destination for Local Testing

When running the CAP application locally, the application still needs access to the destination configuration.

Therefore, the corresponding destination service instance should be bound to the local CAP application/environment according to your BTP setup.

MaheshSirsat_16-1789131115371.png

Once the destination is available to the local CAP application, we can test the service.

Step 14 – Test the CAP Service

Example request:

POST {{server}}/odata/v4/complaint/sendMail
Content-Type: application/json

{
“to”: “recipient@example.com”,
“subject”: “Test from SAP CAP”,
“body”: “<h2>Hello!</h2><p>This email was sent from SAP CAP using Microsoft Graph.</p>”
}

MaheshSirsat_17-1789131115373.png

If the configuration is correct, the CAP service returns:

Email sent successfully

The recipient should then receive the email in their mailbox.

MaheshSirsat_18-1789131115375.png

Understanding the Complete Flow

Let’s look at what happens when we send the request.

MaheshSirsat_19-1789131115404.png

 

Conclusion

In this implementation, we successfully integrated an SAP CAP application with Microsoft 365 email using Microsoft Graph API.

The important pieces are:

  • Microsoft Entra App Registration provides the application identity.
  • Mail.Send Application permission allows app-only mail sending.
  • Admin consent enables the configured application permission.
  • SAP BTP Destination stores the OAuth connectivity configuration.
  • SAP Cloud SDK resolves the destination from the CAP application.
  • The CAP service builds and sends the Microsoft Graph sendMail request.
  • The Microsoft 365 mailbox sends the final email.

The key advantage of this approach is that the CAP application does not need to manage Microsoft OAuth credentials directly in its source code. The authentication and connectivity configuration is maintained through the SAP BTP Destination while the application focuses on the business logic of sending the email.

“}]] 

  Read More Technology Blog Posts by Members articles 

#abap

By ali

Leave a Reply