Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
Showing results for 
Search instead for 
Did you mean: 
Hi All,

I am writing this blog to describe the simplest way to use SAP Conversational AI with Node.js application on SAP Cloud Platform Cloud Foundry.



Local PC

  • Ubuntu18.04.01 LTS on VMWare Workstation

  • cf CLI 6.43.0

  • node.js 11.10.1

  • npm 6.7.0

Cloud Foundry

  • Nodejs Buildpack version 1.6.40

  • CF Trial (Europe – Frankfurt)


  • space is created on Cloud Foundry environment

  • cf CLI is installed on Local PC(see the official page for the installation)

  • Node.js is installed on Local PC(see another article)


1. Node.js development

1.1. Setup Node.js on Local PC

Create a directory.
mkdir chat_test
cd chat_test

1.2. Setup npm

Initialize npm.  After  "npm init" command, I answered like this.
$ npm init

This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help json` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (chat_test) chat-test
version: (1.0.0)
entry point: (index.js) app.js
test command:
git repository:
license: (ISC)
About to write to /home/i348221/Apps/node/chat_test/package.json:

"name": "chat-test",
"version": "1.0.0",
"description": "",
"main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"author": "",
"license": "ISC"

Is this OK? (yes) yes

1.3. Install express and body-parser

Install express and body-parser via npm.
npm install --save express body-parser

1.4.  Change package.json

Change package.json file for startup registration on SAP Cloud Platform.  I changed "scripts" -> "start" part.
"name": "chat-test",
"version": "1.0.0",
"description": "",
"main": "app.js",
"scripts": {
"start": "node app.js"
"author": "",
"license": "ISC",
"dependencies": {
"body-parser": "^1.18.3",
"express": "^4.16.4"

Now the directory is like this.
$ ls -al
total 32
drwxr-xr-x 3 i348221 i348221 4096 Mar 7 19:24 .
drwxr-xr-x 6 i348221 i348221 4096 Mar 7 18:00 ..
drwxr-xr-x 51 i348221 i348221 4096 Mar 7 19:24 node_modules
-rw-r--r-- 1 i348221 i348221 283 Mar 7 19:24 package.json
-rw-r--r-- 1 i348221 i348221 13929 Mar 7 19:24 package-lock.json

1.5. Main program "app.js"

Create app.js in the same directory.
tourch app.js

Contents of "app.js".

I prepared for "get" and "post" method, though I don't use "get" method.  It is just test purpose.
// Import modules
const express = require('express')
const bodyParser = require('body-parser');

const app = express()

const port = process.env.PORT || 3000;;

// Get method
app.get('/', (req, res) => res.send('Hello World! for GET'))

// Post method'/', function(req, res) {
console.log('Start [POST] method to / ');

console.log(`Request from user: ${req.body.conversation.memory['user']}`)

// Response Body
replies: [
type: 'text',
content: `Hello ${req.body.conversation.memory['user']}`
conversation: {
memory: {
'result': 'OK',

// Listen
app.listen(port, () => console.log(`Example app listening on port ${port}!`))

1.6. Test Node.js application

For verifying the "app.js" on local PC, run "app.js".
$ node app.js
Example app listening on port 3000!

I used POSTMAN for the test.

The result of "get" method.

The one of "post" method.  Don't forget about request

Headers and Body.

The "post" Request Body. Most of data is unnecessary.
"action_id": "5149f96e-b2c5-4e30-96ec-c587ae978d52",
"conversation": {
"id": "test-1530310812548",
"memory": {
"user": "Homer"
"language": "en",
"skill": "foo",
"skill_occurences": 2
"nlp": {
"act": "assert",
"language": "en",
"processing_language": "en",
"sentiment": "neutral",
"source": "This is a sample message.",
"status": 200,
"timestamp": "2018-06-29T22:00:50.591367+00:00",
"type": null,
"uuid": "c1bc4e40-ca14-4ce2-bc18-700433b001d9",
"version": "2.12.0"

After sending a request, I can see logs via terminal.

I exported POSTMAN.

2. Deploy Node.js app to SAP CP

2.1. Create manifest.yaml

For deployment to SAP Cloud Foundry, manifest.yaml is necessary.
touch manifest.yaml

The file content is like this.
- name: chat-test
random-route: true
memory: 128M

2.2. Deploy the app to SAP CP Cloud Foundry

Login SAP CP Cloud Foundry via CF cli.
cf login

Now deploy the app!  Application name is from "manifest.yaml".
cf push

3. SAP Conversational AI

3.1. Create chatbot

I created a simple chatbot, which doesn't have any intents and skills.

I used "fallback" skill for the connection with Node.js.

This is the action of "fallback" skill and just send POST request without authentication.  Don't forget about Header "Content-Type" is "application/json".

3.2. Check the connection

Now check the connection.


I can see logs via CF cli.
cf logs chat-test --recent


Here is the logs.
2019-03-07T23:47:57.60-0800 [APP/PROC/WEB/0] OUT Start [POST] method to / 
2019-03-07T23:47:57.61-0800 [APP/PROC/WEB/0] OUT { nlp:
2019-03-07T23:47:57.61-0800 [APP/PROC/WEB/0] OUT { uuid: '1d8ca70e-f889-4ce4-a643-20b330ed7522',
2019-03-07T23:47:57.61-0800 [APP/PROC/WEB/0] OUT intents: [],
2019-03-07T23:47:57.61-0800 [APP/PROC/WEB/0] OUT entities: {},
2019-03-07T23:47:57.61-0800 [APP/PROC/WEB/0] OUT language: 'en',
2019-03-07T23:47:57.61-0800 [APP/PROC/WEB/0] OUT processing_language: 'en',
2019-03-07T23:47:57.61-0800 [APP/PROC/WEB/0] OUT version: '1902.2.0',
2019-03-07T23:47:57.61-0800 [APP/PROC/WEB/0] OUT timestamp: '2019-03-08T07:47:57.074401+00:00',
2019-03-07T23:47:57.61-0800 [APP/PROC/WEB/0] OUT status: 200,
2019-03-07T23:47:57.61-0800 [APP/PROC/WEB/0] OUT source: 'HI',
2019-03-07T23:47:57.61-0800 [APP/PROC/WEB/0] OUT act: 'assert',
2019-03-07T23:47:57.61-0800 [APP/PROC/WEB/0] OUT type: 'desc:desc',
2019-03-07T23:47:57.61-0800 [APP/PROC/WEB/0] OUT sentiment: 'vpositive' },
2019-03-07T23:47:57.61-0800 [APP/PROC/WEB/0] OUT action_id: '78538f72-0fe9-4d64-89a9-631d76862bc1',
2019-03-07T23:47:57.61-0800 [APP/PROC/WEB/0] OUT conversation:
2019-03-07T23:47:57.61-0800 [APP/PROC/WEB/0] OUT { id: 'test-1552031274266',
2019-03-07T23:47:57.61-0800 [APP/PROC/WEB/0] OUT conversation_id: 'test-1552031274266',
2019-03-07T23:47:57.61-0800 [APP/PROC/WEB/0] OUT warning: 'The conversation_id field will be depreciated on January 1st 2018! Switch to using the id field instead',
2019-03-07T23:47:57.61-0800 [APP/PROC/WEB/0] OUT language: 'en',
2019-03-07T23:47:57.61-0800 [APP/PROC/WEB/0] OUT memory: { user: 'Test' },
2019-03-07T23:47:57.61-0800 [APP/PROC/WEB/0] OUT skill_stack: [],
2019-03-07T23:47:57.61-0800 [APP/PROC/WEB/0] OUT skill: 'fallback',
2019-03-07T23:47:57.61-0800 [APP/PROC/WEB/0] OUT skill_occurences: 1,
2019-03-07T23:47:57.61-0800 [APP/PROC/WEB/0] OUT participant_data: {} } }
2019-03-07T23:47:57.61-0800 [APP/PROC/WEB/0] OUT Request from user: Test
2019-03-07T23:47:57.61-0800 [RTR/3] OUT - [2019-03-08T07:47:57.558+0000] "POST / HTTP/1.1" 200 647 94 "-" "axios/0.18.0" "-" "" x_forwarded_for:"-" x_forwarded_proto:"https" vcap_request_id:"6f2d89a0-5bdf-45c1-6250-9a7358b5f059" response_time:0.056351563 app_id:"610382d3-8749-44eb-b29e-d40787a15fbb" app_index:"0" x_correlationid:"-" x_b3_traceid:"acc413c482b12ac1" x_b3_spanid:"acc413c482b12ac1" x_b3_parentspanid:"-"
2019-03-07T23:47:57.61-0800 [RTR/3] OUT