How to pass customData dynamically to the platform from Kore Web-SDK

Problem:
How to modify customData dynamically and pass it on to Kore bot form Web-SDK.

Out of scope:
The solution is just an example of clarifying the concept of how to modify customData object on a need basis/based on an event. Based on the developer’s use case, the solution will need to be extended.

Solution:
It may appear as per our documentation that the customData can not be dynamically modified but that is not true. It is just an object which can be altered based on the needs from Web-SDK.
Usually, it is mentioned in kore-config.js along with botOptions.botInfo.

botOptions.botInfo = { name: "Test",
							"_id": "st-xxxxxxxxxxxxxxxx-0904a0cde8a1",
							"customData": {
								"myinitialLanguageInKoreConfig": "English"
							}
						}; // bot name is case sensitive

But let us first identify where the customData actually gets set and sent to Kore bot.
In /UI/chatWindow.js file, here is where the customData gets passed.

if(msgObject && msgObject.customdata){
                    messageToBot["message"].customdata=msgObject.customdata;
                }

Once we have identified that, we will need to introduce a similar way to retain this but send a dynamically set customData as well based on our needs. So first, let us define our need.

Let us say that there is a text field on the index.html page where the bot is hosted, and we would like to pass on whatever text in mentioned in that text field to customData when we click a button.

For that let us introduce two input elements in index.html within the body after the chat button div. We will look into the function mentioned for the button in a while.

<input type = "text" id = "custDataDemoTextBox" placeholder="Type something here"></input>
<button type="button" id = "custDataDemoButton" onclick="putCustomData()">Click Me to change custom Data</button>

This is how it will look.

Now let us see how to send the dynamic customData. Let us introduce a variable in kore-main.js which will be used to send the dynamic customData while sending a message to the bot.
The below code will set a global object which will be modified on a need basis and passed on as customData.

var myCustomData = { "customInitialLanguage": "MyCustomDataLanguage"};//this is the global object - it will need to be chaged as per the page changes.

chatConfig.botOptions.botInfo.customDataFn = function(){
            return myCustomData;
        }

Let us introduce a function to override this variable whenever we write something in the textbox and click on the button we created on index.html. It is imperative that it is the same function that is mapped to the click event of the button.

        window.putCustomData=function(){
            var textBoxValue = $('#custDataDemoTextBox').val();
            if(textBoxValue){
                myCustomData.customInitialLanguage = textBoxValue;
            } else {
                myCustomData.customInitialLanguage = "DefaultMyOwnCustomLanguageUpdated";
            }
            
        }

We first need a little modification in the init function where the botInfo is being set.

Just append the customDataFn in the botInfo object.

me.config.botOptions.botInfo = { chatBot: me._botInfo.name, taskBotId: me._botInfo._id, customData: me._botInfo.customData, metaTags: me._botInfo.metaTags, tenanturl: me._botInfo.tenanturl, customDataFn: me._botInfo.customDataFn};

Now, provided customDataFn is not returning null, we will use the customDataFn to fetch the global variable myCustomData and pass it on as custom data overriding the existing function in chatWindow.js

Please note that this will NOT override the customData set in kore-config.js. It will only add another customData variable at a different path

                //Add this for overriding the customData with dynamic custom Data
                if(me.config.botOptions.botInfo.customDataFn){
                    var customData = me.config.botOptions.botInfo.customDataFn();
                    messageToBot["message"].customdata=customData;
                }

Output and testing the solution
kore-config has custom data set as

{"myinitialLanguageInKoreConfig": "English"}

kore-main.js is set to override the above to

{ "customInitialLanguage": "MyCustomDataLanguage"}

OR to the value of the text field if it is populated and when the button is clicked (if it is not populated, a default value is set).

  1. Just talk to the bot and invoke an intent to display the JSON of context.session.BotUserSession.lastMessage payload.


    Note that both customData defined in kore-config.js and the variable set in kore-main.js are both available under different paths.
    image

  2. Now do not write anything in the textbox and click on the button. Then invoke the intent which would display context.session.BotUserSession.lastMessage payload.


    Note that the customData from the kore-config.js and the variable set in window.putCustomData=function() in kore-main.js (when content of text box is empty) are both available in the context under different paths
    image

  3. Now write something in the textbox and click on the button. Then invoke the intent which would display context.session.BotUserSession.lastMessage payload.


    Note that the customData from the kore-config.js and the variable set in window.putCustomData=function() in kore-main.js are both available in the context under different paths

Please note, to avoid any confusion, if you wish to change the dynamic custom data key, you may change it in the function as shown below:

               //Add this for adding the dynamic custom Data              
                if(me.config.botOptions.botInfo.customDataFn){
                    var customData = me.config.botOptions.botInfo.customDataFn();
                    messageToBot["message"].dynamicCustomData=customData;
                }


image

There is one more scenario in which a developer may not want to pass customData dynamically with each message and may be interested in capturing any value as customData “before” opening the chat window.

Basically, the solution lies in changing/passing in the customData in chatConfig before calling koreBot.show(chatConfig); in kore-main.js
Let us just introduce one text box on the index.html page.

<input type = "text" id = "custDataDemoTextBox" placeholder="Type something here"></input>

We will not have any other button here to update the customData during the chat. While loading the index.html page, we will set this text box with the current timestamp and we will use it in customData while opening the chatWindow. Let us see how to do that:


Line #38 is setting the text box with the time-stamp.
Line #43 is injecting botOptions.botInfo.customData with the same time-stamp which was set as the value of the text box. The reason we are setting it in the text box is for the readers to compare if the same value is reflected in customData.

{
     "customInitialData": 
                    "MyCustomData " + $('#custDataDemoTextBox').val()
}

NOTE - NO changes in chatwindow.js are necessary to achieve this.

Output:

  1. Loading the page:
  2. Click on talk to bot and invoke the utterance to print the JSON-ified JSON of context.session.BotUserSession.lastMessage payload.

Credits: @rajasekhar.balla

@swagata.sengupta thank you for this amazing detailed article.
The solution works fine in local system , but when I try to generate the binary files to integrate it with an application in new environment. In my json response, custom data doesn’t populate for any path. Even the default value doesn’t come. The same code works in local and I see custom data,(default value or the value which I set).
I printed the whole bot user session for you reference.

Please help.

@k.yadav
A couple of questions here:

  1. Do you mean to say after the minification/grunt you are not able to capture custom data?
  2. If yes, is the page where you have integrated the bot populating the right custom data?

Can you share how exactly have you implemented the code to capture the custom data and what exactly is it capturing?

Hi Swagat,
Please find my response to your questions below:

  1. Yes, after minification (generating binaries) using grunt command I am not able to capture custom data in the integrated environment. is it something related to the npm install?
    to run SDK locally, I do npm install inside SDKAPP main folder so that I can run node startServer.js.
    however, when I have to generate binaries for the integration, I do npm install within the UI folder and then do grunt.
    Do I have to do npm install on SDKAPP and UI folder both ?

I would like to share the code as well, can I have your email id ?

Regards,
Khushboo Yadav

  1. Yes , I added console logs under the putcustomdata function in kore main.js to populate the custom data.
    I see that coming in console .

@k.yadav
For grunt to work properly, you will need to do npm install in UI folder.
SDKApp is an example library for two reasons - 1. it provides a dev level local example of JWT service. 2. It helps serve the index.html page. npm install at this level will only help wih these two.

So, when you minify the web-SDK, and assuming you are using the proper JWT URL and the page hosting the bot will be served from some server, this SDKApp has practically no role.

Ideally, npm install should not not have anything to do with your ability to pass custom data. It all depends on “what” are you passing as custom data and whether “that” is available on the environment’s page or not.

If you want to share the code, you may share with koresupport@kore.com

In the koreMain.js file , the putCustomData function has an else code, so that if incase no customdata is passed the default will be returned. however, the problem here is, it works fine in my local, once it is integrated , the bot’s basic functionality (designed flow) works fine but no custom data is populated. Even though, I see the value being passed to it through the console logs.

So, connection wise, everything works as per the design.

I started printing the complete bot session to analyze.
print(JSON.stringify(context.session.BotUserSession));

I will share the code to koresupport. kindly check and help.

Thanks,
Khushboo Yadav

@k.yadav
Did you send something to koresupport@kore.com? I did not see anything that the team received.

Yes . I sent on Wednesday last week.
will forward the mail again to the kore support team.

@k.yadav
To conclude, it was observed by our solutions team that you were using Webhook v2 from webSDK and not a websocket-based connection.

Currently passing custom data is not available in the existing SDK for webhook but you can pass custom data by adding a custom data object inside
send message payload.
There is a payload object inside the sendMessageViaWebHook function in the chatwindow.js file. Add a customData object in the payload.
Here is sample customData object

"customData": {
"name": "John",
"Age": 30
}

thank you for the valuable information.

is there a way to achieve same thing through Bot URL?

something like
https://bots.kore.ai/webclient/botid?variable1=1234

@michael_for_ever78
Unfortunately no. The web client url you are referring to offers little customisation options and is mainly intended for quick testing of the web channel. Full fledged customisation is only possible through the webSDK.