
Dear all,
I implemented this AI chatbot functionality in SAPUI5 apps with SAP CAP backend and AI core API.
I thought of sharing my knowledge with you all. I took references from multiple blogs to complete this functionality, I will list all those blogs in the references section below and thank you for all the authors of those blogs.
Steps involved to implement this functionality,
Name: URL: <AI_API_URL>/v2 # Eg. https://api.ai....ml.hana.ondemand.com/v2 <- Note the suffix /v2 is very important here
Authentication: OAuth2ClientCredentials
Client ID: <CLIENT_ID> -> you can get it from SAP AI core instance service key
Client Secret: <CLIENT_SECRET> -> you can get it from AI core instance service key
Token Service Url: <TOKEN_URL>/oauth/token -> append this to Token URL
## Additional Properties
HTML5.DynamicDestination: true
URL.headers.AI-Resource-Group: default -> Just add key and value in properties even you do not have drop down values.
URL.headers.Content-Type: application/json -> Just add key and value in properties even you do not have drop down values.
2. Configure this destination in SAP CAP backend service and UI level:
Backend Cap service -> package.json
"cds": {
"requires": {
"AI_ASSISTANT": {
"kind": "rest",
"[hybrid]": {
"credentials": {
"destination": "AI_ASSISTANT", -> Destination name here
"path": "/inference/deployments/<deployment ID here>"
}
},
"[production]": {
"credentials": {
"destination": "AI_ASSISTANT",
"path": "/inference/deployments/<deployment ID here>"
}
}
}
},
}
Note: You can get Deployment Id from AI launchpad.
UI5 app level- > xs-app.json
Add a new route,
{
"source": "^/api/(.*)$",
"target": "/inference/deployments/<deployment ID here>/$1",
"authenticationType": "xsuaa",
"destination": "AI_ASSISTANT"
}
3. Define action in the CAP service and call the destination to read data from SAP AI API:
We will define action in CAP backend service to call the AI API through destination.
db/schema.cds:
type AIChatBotResponse {
text : String;
}
srv/service.cds:
service DemoService {
action getAIResponse(query : String) returns AIChatBotResponse;
}
srv/service.js file:
this.on("getAIResponse", async (request: Request) => {
const { query } = request.data;
const aiDestination = await cds.connect.to("AI_ASSISTANT");
const aiChatBotResponse = await aiDestination.send('POST','/v2/predict', { query: query })
//return aiChatBotResponse;
return { text: aiChatBotResponse.response };
})
Note: import above defined type from schema.cds into service definition cds file.
4. Use this action from CAP service in UI5 app and integrate CAP service API and UI5 app:
For UI part you can take dialog and display chat dialog on click of a AI chat bot button.
XML View/fragment code:
<core:FragmentDefinition
xmlns="sap.m"
xmlns:core="sap.ui.core"
xmlns:f="sap.f"
xmlns:form="sap.ui.layout.form"
xmlns:u="sap.ui.unified"
xmlns:layout="sap.ui.layout"
>
<Dialog
showHeader="false"
verticalScrolling="false"
contentHeight="60%"
contentWidth="40%"
draggable="true"
resizable="true"
>
<Page >
<VBox width="100%" height="auto">
<IllustratedMessage id="id_illuMsg"
title="{i18n>aiChatBotTitle}"
class="sapUiLargeMarginTop"
description="{i18n>aiChatbotAskMe}"
illustrationType="tnt-FaceID"
illustrationSize="Auto">
<additionalContent>
<Button text="{i18n>aiChatbotBtnText}" press="onPressHide"/>
</additionalContent>
</IllustratedMessage>
<ScrollContainer id="id_SC" visible="false"
width="100%"
height="auto"
vertical="true">
<List id="id_List" items="{path:'chatbot>/list'}"
noDataText="{i18n>aiChatBotNoChat}">
<items>
<FeedListItem text="{chatbot>text}"
icon="{= ${chatbot>type} === 'query' ?
'sap-icon://customer' : 'sap-icon://da-2' }">
</FeedListItem>
</items>
</List>
</ScrollContainer>
<VBox id="id_box" visible="false" width="100%">
<Input width="100%"
placeholder="{i18n>AiChatbotInputPlaceholder}"
submit="onSubmitQuery"/>
</VBox>
</VBox>
</Page>
<endButton>
<Button
text="{i18n>close}"
type="Default"
press="onAIChatbotClose"
/>
</endButton>
</Dialog>
</core:FragmentDefinition>
Component.js:
This is for adding Illustration types in chatbot dilaog. We should register them in the Illustration pool.
https://ui5.sap.com/#/api/sap.m.IllustratedMessage
init: async function () {
// call the base component's init function
UIComponent.prototype.init.apply(this, arguments);
// enable routing
this.getRouter().initialize();
// set the device model
this.setModel(models.createDeviceModel(), "device");
// code for AI chatBot to register illustartions/icons in the chat dialog
var oTntSet = {
setFamily: "tnt",
setURI: sap.ui.require.toUrl("sap/tnt/themes/base/illustrations")
};
// register tnt illustration set
IllustrationPool.registerIllustrationSet(oTntSet, false);
},
UI code controller js/ts file:
onPressAIAssistant: function () {
let oView = this.getView();
if (!this._oAIDialog) {
this._oAIDialog = Fragment.load({
id: oView.getId(),
name: "yournamesapce.fragment.AIChatbot",
controller: this
}).then(function (oDialog) {
oView.addDependent(oDialog);
return oDialog;
}.bind(this));
}
this._oAIDialog.then(function (oDialog) {
oDialog.open();
}.bind(this));
},
onPressHide: function(oEvent) {
let oView = this.getView();
let oBtn = oEvent.getSource();
oView.byId("id_SC").setVisible(true);
oView.byId("id_box").setVisible(true);
oBtn.setVisible(false);
},
onSubmitQuery: function (oEvent) {
let oInput = oEvent.getSource();
let sQuery = oInput.getValue();
oInput.setValue("");
// Add User query to the model
this.aList = this.ChatbotJSONModel.getProperty("/list");
if (!this.aList) {
this.aList = [];
}
let oJsonObj = {
text: sQuery,
type: "query",
};
this.aList.push(oJsonObj);
this.ChatbotJSONModel.setProperty("/list", this.aList);
this.aList = this.ChatbotJSONModel.getProperty("/list");
let oPayLoad = {};
oPayLoad.query = sQuery
let oDataModel = this.getView()?.getModel();
const that = this;
return new Promise((resolve, reject) => {
oDataModel.callFunction("/getAIResponse", {
method: "POST",
urlParameters: oPayLoad,
success: function (oDataReceived) {
if (oDataReceived) {
if (oDataReceived && oDataReceived.getAIResponse) {
let aiResponse = oDataReceived.getAIResponse;
let oJsonObj = {
text: aiResponse.text,
type: "response",
};
that.aList.push(oJsonObj);
that.ChatbotJSONModel.setProperty("/list", that.aList);
resolve(aiResponse);
}
}
},
error: function (oErrorReceived) {
reject(oErrorReceived);
}
});
});
}
UI screenshot:
Best Regards,
Venkatesh.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
8 | |
5 | |
5 | |
4 | |
3 | |
3 | |
3 | |
3 | |
3 | |
2 |