The file, app.js was mentioned in the manifest.yaml earlier as a reference. It contains the main logic of your microservice. It implements how the service reacts when called from SAP Sales Cloud and SAP Service Cloud Version 2 and what actions it performs in response.
In this section, let’s go ahead and create a new file named app.js in the root folder of your project. Then, copy the provided code snippet into this file.
The first part of the code handles the setup and authentication:
- It imports the required Node.js modules or dependencies such as express and axios.
- It creates a Basic Authentication token using your SAP Sales Cloud and SAP Service Cloud Version 2 credentials, which are stored as environment variables in the manifest.yaml file.
- It defines a base URL that points to your SAP Sales Cloud and SAP Service Cloud Version 2 API endpoint.
- It also sets default HTTP headers for Axios to ensure that every API request payload is sent in JSON format with the proper authorization.
The next part defines the Express application and its routes. The app.post('/onCreateSubCase', ...) route, highlighted in the screenshot, is the core of your microservice. This function acts as a webhook endpoint. It is triggered automatically when an event occurs in SAP Sales Cloud and SAP Service Cloud Version 2 (for example, when a new case is created).
Inside this function, the logic performs the following steps:
- It reads the event payload (the request body) and extracts key information such as the case ID.
- It checks whether the created case already has a parent case.
- If the case does not have a parent, the function creates a new Subcase by sending a POST request to the SAP Sales Cloud and SAP Service Cloud Version 2 API endpoint /v1/case-service/cases.
It uses Axios to send this request, with a JSON payload containing information like the subject, type, priority, and relationship to the original case.
There are also several console.log() and console.error() statements included in the code to provide debug information during runtime. These log messages indicate key events such as when the server starts, when a Subcase is created, or if an error occurs during the process. When the microservice is deployed to Cloud Foundry, these log messages can be viewed using the command cf logs <app-name> --recent. This allows you to verify that the microservice is running correctly and helps you troubleshoot any issues that arise during testing.
The new Subcase will automatically appear in SAP Sales Cloud and SAP Service Cloud Version 2, linked to the original case.
In addition, the app.js file defines a health check endpoint (/health). This is a simple GET request that confirms whether the microservice can successfully reach the SAP Sales Cloud and SAP Service Cloud Version 2 API. You can use this endpoint later in the SAP Sales Cloud and SAP Service Cloud Version 2 Autoflow to test if your microservice deployment is running properly.
Here’s the full Node.js code example for your reference. You can use it as-is for the exercise or modify it to implement your own custom logic.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
var express = require('express');
var app = express();
const axios = require('axios');
const token = Buffer.from(`${process.env.SSC_USER}:${process.env.SSC_PASSWORD}`).toString('base64');
const base_url = `${process.env.SERVICE_URL}/sap/c4c/api`;
axios.defaults.headers.common['Authorization'] = `Basic ${token}`;
axios.defaults.headers.common['content-type'] = 'application/json';
app.use(express.json());
console.log('Start....');
app.post('/onCreateSubCase', async function (req, res) {
try {
const data = req.body;
const id = data?.data?.currentImage?.id;
if (data.data && data.data.currentImage && !data.data.currentImage.parentCaseId) {
const subCaseData = {
subject: `Sub Case of ${data.data.currentImage.displayId}`,
caseType: 'ZCAS',
origin: 'MANUAL_DATA_ENTRY',
status: '01',
priority: '03',
account: {
id: data.data.currentImage.account.id
},
relatedObjects: [
{
objectId: id,
type: '2886',
role: '13'
}
]
};
const response = await axios.post(`${base_url}/v1/case-service/cases`, subCaseData);
console.log('Sub Case created:', response.data);
}
res.status(200).send('OK');
} catch (error) {
console.error('Error creating sub case:', error.message);
res.status(500).send('Error creating sub case');
}
});
app.get('/health', async function (req, res) {
try {
await axios.get(`${base_url}/v1/case-service/cases`);
console.log('Healthy - connection to Service Cloud works');
res.send('OK');
} catch (error) {
console.error('Health check failed:', error.message);
res.status(500).send('Error');
}
});
app.listen(process.env.PORT || 4000, () => {
console.log(`Server running on port ${process.env.PORT || 4000}`);
});