git clone https://github.com/SAP-samples/multi-cloud-html5-apps-samples
cd managed-html5-runtime-fiori-mta
npm install
npm run build
npm run deploy:cf
Don't forget to enable the "Show Notifications" settings of the Launchpad site that you want to use.
cf create-service-key managed-fiori-uaa uaa-key
cf create-service-key managed-fiori-destination destination-key
cf service-key managed-fiori-uaa uaa-key
cf service-key managed-fiori-destination destination-key
default-env.json
:{
"VCAP_SERVICES": {
"destination": [
{
"label": "destination",
"provider": null,
"plan": "lite",
"name": "notification-test-content-destination-service",
"tags": [
"destination",
"conn",
"connsvc"
],
"instance_guid": "00849954-cdd4-4da2-9c94-a77f1eb7e779",
"instance_name": "notification-test-content-destination-service",
"binding_guid": "ae9d65c6-e542-4abd-95c7-94d70c0f52d9",
"binding_name": null,
"credentials": <INSERT CONTENT OF THE FIRST SERVICE KEY>,
"syslog_drain_url": null,
"volume_mounts": []
}
],
"xsuaa": [
{
"label": "xsuaa",
"provider": null,
"plan": "application",
"name": "notification-test-content-xsuaa-service",
"tags": [
"xsuaa"
],
"instance_guid": "abc0c759-4eee-4767-a09f-226e0d20df59",
"instance_name": "notification-test-content-xsuaa-service",
"binding_guid": "5d93c1b7-9940-4676-aeb0-6f055dc94b5a",
"binding_name": null,
"credentials": <INSERT CONTENT OF THE SECOND SERVICE KEY>,
"syslog_drain_url": null,
"volume_mounts": []
}
]
}
}
package.json
file:{
"name": "notifications-demo",
"scripts": {
"start": "node create.js"
},
"dependencies": {
"@sap-cloud-sdk/core": "^1.46.0",
"axios": "^0.21.1"
}
}
util/NotificationAPI.js
that encapsulates the APIs calls to the destination into methods. Note that we'll use the SAP Cloud SDK here to elegantly retrieve CSRF tokens and send HTTP requests to the destination we created previously.const { getDestination, executeHttpRequest, buildCsrfHeaders } = require("@sap-cloud-sdk/core");
const { setLogLevel } = require('@sap-cloud-sdk/util');
setLogLevel('error', 'env-destination-accessor');
setLogLevel('error', 'destination-accessor-vcap');
setLogLevel('error', 'destination-accessor-service');
setLogLevel('error', 'xsuaa-service');
setLogLevel('error', 'proxy-util');
setLogLevel('error', 'http-client');
setLogLevel('error', 'environment-accessor');
const destinationName = "SAP_Notifications";
const notificationEndpoint = "v2/Notification.svc";
const notificationTypesEndpoint = "v2/NotificationType.svc";
async function _getDestination(destinationName) {
const notifServiceDest = await getDestination(destinationName);
if (!notifServiceDest) {
throw new Error(`failed to get destination: ${destinationName}`);
}
return notifServiceDest;
}
class NotificationService {
static async getNotificationTypes() {
const notifServiceDest = await _getDestination(destinationName);
const response = await executeHttpRequest(notifServiceDest, {
url: `${notificationTypesEndpoint}/NotificationTypes`,
method: "get"
});
return response.data.d.results;
}
static async postNotificationType(notificationType) {
const notifServiceDest = await _getDestination(destinationName);
const csrfHeaders = await buildCsrfHeaders(notifServiceDest, { url: notificationTypesEndpoint });
const response = await executeHttpRequest(notifServiceDest, {
url: `${notificationTypesEndpoint}/NotificationTypes`,
method: "post",
data: notificationType,
headers: csrfHeaders,
});
return response.data.d;
}
static async postNotification(notification) {
const notifServiceDest = await _getDestination(destinationName);
const csrfHeaders = await buildCsrfHeaders(notifServiceDest, { url: notificationEndpoint });
const response = await executeHttpRequest(notifServiceDest, {
url: `${notificationEndpoint}/Notifications`,
method: "post",
data: notification,
headers: csrfHeaders,
});
return response.data.d;
}
}
module.exports = { NotificationService };
DomainNotifications.js
file itself exports the one function that we'll reuse in a moment.const { NotificationService } = require("./util/NotificationAPI");
const NOTIF_TYPE_KEY = "SupplyWarning";
const NOTIF_TYPE_VERSION = "1.0";
function createNotificationType() {
return {
NotificationTypeKey: NOTIF_TYPE_KEY,
NotificationTypeVersion: NOTIF_TYPE_VERSION,
Templates: [
{
Language: "en",
TemplateSensitive: "Low {{product}} supply ({{stock}} items left)",
TemplatePublic: "Ciritical product supply detected",
TemplateGrouped: "Limited Product Supply of {{category}}",
TemplateLanguage: "Mustache",
Subtitle: "{{product}} needs to be reordered"
}
]
}
}
function createNotification({ product, category, stock, recipients }) {
return {
OriginId: "supply-warn-backend",
NotificationTypeKey: NOTIF_TYPE_KEY,
NotificationTypeVersion: NOTIF_TYPE_VERSION,
NavigationTargetAction: "display",
NavigationTargetObject: "masterDetail",
Priority: "High",
ProviderId: "",
ActorId: "",
ActorType: "",
ActorDisplayText: "",
ActorImageURL: "",
Properties: [
{
Key: "product",
Language: "en",
Value: product,
Type: "String",
IsSensitive: false
},
{
Key: "category",
Language: "en",
Value: category,
Type: "String",
IsSensitive: false
},
{
Key: "stock",
Language: "en",
Value: stock,
Type: "String",
IsSensitive: false
}
],
Recipients: recipients.map(recipient => ({ RecipientId: recipient })),
}
}
async function publishSupplyWarningNotification(notification) {
const notifTypes = await NotificationService.getNotificationTypes();
const notifType = notifTypes.find(nType => nType.NotificationTypeKey === NOTIF_TYPE_KEY && nType.NotificationTypeVersion === NOTIF_TYPE_VERSION);
if (!notifType) {
console.log(`Notification Type of key ${NOTIF_TYPE_KEY} and version ${NOTIF_TYPE_VERSION} was not found. Creating it...`);
await NotificationService.postNotificationType(createNotificationType());
}
return await NotificationService.postNotification(createNotification(notification));
}
module.exports = { publishSupplyWarningNotification };
create.js
in the project descriptor above. This script uses axios to pull all product data and filters for products of a defined category that are low on supply. It then uses the exported function of the previous file to create a notification per item and finally prints a success message.const { publishSupplyWarningNotification } = require("./DomainNotifications");
const axios = require("axios");
require('@sap/xsenv').loadEnv();
const categories = {
2: "Condiments",
4: "Dairy Products",
6: "Meat/Poultry"
};
(async () => {
try {
const res = await axios("https://services.odata.org/V2/Northwind/Northwind.svc/Products?$format=json");
const criticalSupplyOfCategory6 = res.data.d.results.filter(a => a.UnitsInStock <= a.ReorderLevel && a.CategoryID === 6);
await Promise.all(criticalSupplyOfCategory6.map(product => publishSupplyWarningNotification({
product: product.ProductName,
category: categories[product.CategoryID],
stock: `${product.UnitsInStock}`,
recipients: ["marius.obert@sap.com"]
})));
console.log("Success");
} catch (e) {
if (e.response) {
console.error(`${e.response.statusText} (${e.response.status}): ${JSON.stringify(e.response.data.error.message)}.`)
} else {
console.error(e)
}
}
})()
npm install
npm start
default-env.json
in a production-ready application as you can achieve the same result with a regular service binding.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
11 | |
11 | |
10 | |
10 | |
8 | |
7 | |
6 | |
6 | |
6 | |
5 |