watsonx Assistant: upload a file from the web chat interface

Ankit Katba
IBM Data Science in Practice
4 min readMar 5, 2024

--

This story was originally published at developer.ibm.com.

IBM watsonx Assistant is a well-known conversational AI for fast and friendly customer care. Developers/data scientists feel it challenging to provide the file upload facility within the web chat due to its unavailability as a direct feature in watsonx Assistant. In this article, we will explore a solution to enrich your web chat with file upload capabilities. Using this you can provide users with a more efficient and productive web chat experience in just a few simple steps. This feature can solve problems in many client use cases where it is required for users to attach files. Technologies used are watsonx Assistant, Javascript, and HTML.

Step 1: Register a custom response listener in web app

First, we need to register an event listener in javascript to handle the event triggered by an assistant to prompt the user to upload a file.

Web page javascript:

var g_wa_instance;
window.watsonAssistantChatOptions = {
integrationID: <your-wa-integration-id>,
region: <your-wa-region>,
serviceInstanceID: <your-service-instance-id>,
onLoad: function (instance) {
g_wa_instance = instance;

instance.on({
type: "customResponse",
handler: (event, instance) => {
if (
event.data.message.user_defined &&
event.data.message.user_defined.user_defined_type ===
"user-file-upload"
) {
fileUploadCustomResponseHandler(event, instance);
}
},
});

instance.render();
}
};

Step 2: Handler to create file upload button in web chat

Next, we will create two HTML components inside the web chat, button & input. When the button is clicked, a system file browser will open for the user to select a file to upload.

Web page javascript:

function fileUploadCustomResponseHandler(event, instance) {
const { element } = event.data;

element.innerHTML = `
<div>
<input type="file" id="uploadInput" style="display: none;">
<button id="uploadButton" class="WAC__button--primary WAC__button--primaryMd cds--btn cds--btn--primary"> Upload a File </button>
</div>`;

const uploadInput = element.querySelector("#uploadInput");
const button = element.querySelector("#uploadButton");
button.addEventListener("click", () => {
uploadInput.click();
});
uploadInput.addEventListener("change", (event) => {
const selectedFile = event.target.files[0];
if (selectedFile) {
// You can access the selected file using selectedFile variable
// console.log("Selected file:", selectedFile.name);
uploadFileFromAsst(selectedFile);
}
});
}

Step 3: Send file to the server

In this step, we will send the file via an API call to the server which will further manage the received file and respond with some successful message. The file can be validated on the server and then stored in any storage, such as IBM Cloud Object Storage, etc. as per your need.

Web page javascript:

function uploadFileFromAsst(selectedFile) {
if (selectedFile) {
const formData = new FormData();
formData.append("uploaded_file", selectedFile);

//Invoke server endpoint to upload file
const SERVER = <your-backend-server>
fetch(SERVER+"/upload", {
method: "POST",
body: formData,
})
.then((response) => {
if (response.ok) {
return response.json();
} else {
throw new Error("File upload failed.");
}
})
.then(async (data) => {
var msg = data["msg"] ? data["msg"] : "";
if (!msg) {
alert("File upload error. Please try after some time.");
return;
}
messageChatbot(msg, true);
})
.catch((error) => {
console.error("Error while file uploading: ", error);
});
} else {
console.error("No file selected.");
}
}

Utility function to send messages to watsonx Assistant chatbot:

function messageChatbot(txt, silent = false) {
const maxChars = 2040;
txt = txt.substring(0, maxChars);
var send_obj = { input: { message_type: "text", text: txt } };

g_wa_instance.send(send_obj, { silent }).catch(function (error) {
console.error("Sending message to chatbot failed");
});
}

Step 4: Create a step inside an action in watsonx Assistant

Lastly, create a watsonx Assistant action with a conversation step to trigger a custom event nameduser-file-upload which is listened to in Step 1 of this article.

In a watsonx Assistant action step, switch to JSON editor first and then add the following JSON and save:

{
"generic": [
{
"values": [
{
"text_expression": {
"concat": [
{
"scalar": "Kindly browse and upload a file"
}
]
}
}
],
"response_type": "text",
"selection_policy": "sequential",
"repeat_on_reprompt": false
},
{
"user_defined": {
"user_defined_type": "user-file-upload"
},
"response_type": "user_defined",
"repeat_on_reprompt": false
}
]
}

Next, set the customer response type for the step to “Free text”, so that one can make a conditional flow based on the response received.

Customer response type set to: Free text

That’s it!

What Next?

Now, it is clear from the above steps how we can enrich our web chat by adding HTML components with a few easy steps. Explore the use case demo using this feature on the dsce.ibm.com platform. Try out by embedding other components yourselves and you can refer to this watsonx Assistant demo site.

--

--