Watson Assistant chatbot: file upload
IBM Watson Assistant has no built-in way to upload files in a chat. This post shows you how to build an integration for that in a Node.js web app.
Download the complete example here: https://github.com/spackows/file-upload-Watson-Assistant
Step 1: Build a file-upload widget
Build a file-upload widget in the web page where you’re hosting your chatbot.
Web page HTML:
<form id="upload_form">
<input id="upload_input"
name="uploaded_file"
type="file"
multiple="false"
onchange="uploadFile();">
</form>
Web page Javascript:
function uploadFile()
{
var form_obj = document.getElementById( "upload_form" );
var form_data = new FormData( form_obj );
$.ajax( { url: "./upload",
type: "POST",
data: form_data,
contentType: false,
cache: false,
processData: false,
async: true,
dataType : "json",
complete : function( result )
{
...
}
} );
}
Server Node.js:
var express = require( "express" );
var multer = require( "multer" );var storage = multer.diskStorage(
{
destination: function( request, file, callback )
{
// Put uploaded files in a directory on the server,
// called "uploads", before sending them on to COS
callback( null, './uploads/' );
},
filename: function( request, file, callback )
{
// Want unique file names, adding a timestamp is one way
callback( null, Date.now() + '_' + file.originalname );
}} );var upload = multer( { storage : storage } );var app = express();
app.post( "/upload", upload.single( "uploaded_file" ),
function( request, response )
{
var file_name = request.file.filename;
var file_path = request.file.path; ...} );
Step 2: Store uploaded files
When a file is uploaded by the new widget in your web page, save the file somewhere like IBM Cloud Object Storage (COS).
Server Node.js:
var fs = require( "fs" );
var cos = require( "ibm-cos-sdk" );var cos_client = new cos.S3( ... );var params = {
Bucket : <your-bucket-name>,
Key : file_name,
Body : fs.createReadStream( file_path )
};
cos_client.upload( params ).promise().then( function()
{
...} );
See: IBM Cloud Object Storage Node.js SDK
Step 3: Message the chatbot
After the uploaded file is stored in COS, have your web page send a message to the chatbot using Watson Assistant instance methods. The message should include information needed to identify the file (the key, for example.)
Web page Javascript:
var wa_instance;window.watsonAssistantChatOptions = {
integrationID: <your-integration-id>,
region: <your-region>,
serviceInstanceID: <your-service-instance-id>,
onLoad: function( instance )
{
wa_instance = instance;
instance.render();
}
};function messageChatbot( txt )
{
var send_obj = {
"input": {
"message_type" : "text",
"text" : txt
}
}; wa_instance.send( send_obj, {} ).catch( function( error )
{
console.error( "Sending message to chatbot failed" );
} );
}
Step 4: Process the file
When your chatbot receives the “file stored” message, the chatbot can extract the key from the message and then call a webhook that will get the file from storage and do whatever is needed.
Chatbot dialog:
- Use a pattern-based entity to recognize the “file stored” message
- Use a regular expression to extract the key from the message (to access the file in storage)
- Use a regular expression to extract the original file name (to explain to the user what’s going on)
- Display some status messages to the user
- Call a webhook to collect the file from storage and process it
This sample chatbot is available here: https://github.com/spackows/file-upload-Watson-Assistant/blob/main/sample-files/File-upload-skill-dialog.json
(When you create a skill in Watson Assistant, you can upload the sample JSON file.)
Conclusion
It might seem like extra work. But building an integration to handle file uploads gives you control over your chatbot users’ experience and how the file is handled.