Embedding watsonx Assistant in Flutter web app

Jatindra Suthar
IBM Data Science in Practice
5 min readAug 26, 2024

Background

IBM’s Watsonx Assistant, a powerful AI-driven conversational agent, offers robust capabilities for building intelligent chatbots that can enhance user engagement and streamline customer service. On the other hand, Flutter, an open-source UI software development kit by Google, has gained significant traction for its ability to craft natively compiled applications for mobile, web, and desktop from a single codebase.

Recently, during one of the partner engagements, we came across the requirement where we had to integrate the watsonx Assistant into the Flutter web app. Also, the assistant should show only when the user is logged in to the web app. It should disappear when the user logs out.

https://youtu.be/oazdBm2aeu0

watsonx Assistant embedded in Flutter webapp

Prerequisites

  • watsonx Assistant instance
  • Flutter

Challenges

I recently encountered a need to integrate the Watsonx Assistant into a Flutter web app. There were a few more challenges:

  • The chatbot should be accessible only to logged-in users. It should disappear upon logout.
  • The chatbot should be a widget in the Flutter web app. It should open in the same screen, not a separate window.

Approach

To meet this need, we will use the approaches to integrate watsonx assistant and authentication in the web app and chatbot.

  • In the login screen, user will be asked to enter the login credentials.
  • Once the user is successfully logged in, the server will return the username and email address. In the pre:send event of assistant we can update variable called user_name of logged-in user.
  • Another approach to enable web chat security is passing JWT token in the assistant. This is altogether a different approach and implementation. Click here for more information on securing the watsonx Assistant.
  • As we need to open the assistant within the web page, we will use JavaScript to load the assistant. To show and hide the assistant widget, Dart language in Flutter provides flexibility to call JavaScript functions from Flutter’s screen file. This will work only for Flutter web apps and is not a recommended approach for iOS or Android apps.

Implementation

Assuming that you have already created flutter project. As we are developing a web application, you will find a folder named web in the project directory.

Web folder of Flutter project

Create a new JavaScript file under the web folder and name it wa_script.js . Copy the content of file from this GitHub link.

Here we have a function called loadWaInstance with parameters showAssistant and userName. This loadWaInstance will be called from the login screen’s dart file after user authentication.

The showAssistant parameter is a flag value that determines whether to show or hide the assistant, and userName is a parameter that holds the name of the logged-in user. This value of userName parameter will be sent to assistant to populate the assistant’s variable user_name.

The web page requires the code block in the wa_script.js to load the assistant.

window.watsonAssistantChatOptions = {
integrationID: "e7c442dd-15f3-4020-xxxx-xxxxxxxxx", // The ID of this integration.
region: "us-south", // The region your integration is hosted in.
serviceInstanceID: "33c5b784-0bec-xxxx-xxx-xxxxxx", // The ID of your service instance.
onLoad: function (instance) {
instance.render();
window.WebChatInstance = instance;
instance.on({ type: 'pre:send', handler: preSendHandler });

// https://cloud.ibm.com/docs/watson-assistant?topic=watson-assistant-web-chat-develop-set-context
function preSendHandler(event) {
if (event.data.input && event.data.input.text === '') {
event.data.context.skills['actions skill'] = event.data.context.skills['actions skill'] || {};
event.data.context.skills['actions skill'].skill_variables = event.data.context.skills['actions skill'].skill_variables || {};
event.data.context.skills['actions skill'].skill_variables.user_name = userName;
}
}
},
showLauncher: true, // Hide the web chat launcher, you will open the WebView from your mobile application
openChatByDefault: false, // When the web chat WebView is opened, the web chat will already be open and ready to go.
hideCloseButton: false // And the web chat will not show a close button, instead relying on the controls to close the WebView
};

You will need to update integrationID, region, and serviceInstanceID from your assistant. Click here for more information on embedding the assistant in a web page.

The function preSendHandler will run when the user sends a message to the chatbot. By writing instance.on({ type: ‘pre:send’, handler: preSendHandler }); we register the function preSendHandler on the assistant’s pre:send event.

Click here to know more about the events and methods exposed by watsonx Assistant. You can use these events and methods for any customisation.

Till here, we are good with the JavaScript part. The next step is to add wa_script.js JS file in index.html to use it in the web application.

Open index.html file under web folder, and add below line in <head> tag.

<!-- Watson assistant script -->
<script src="wa_script.js" defer></script>

Now we are all set from the JS side; the next step is to design a screen that contains a login button. Assume that clicking the login button calls a REST API to authenticate with static info. You can add input fields to get username and password information.

Copy the code from this link and replace the content of the main.dart file.

Run the project; on running, you should see the main screen as in the screenshot below.

Main Screen

In the main.dart file, the _login function will trigger when the user clicks on the Login button on the page.

This function will store users’ name and email in shared preference.

We need to load the assistant once the user has successfully logged in. To do so, below line of code is responsible to call JavaScript method from dart file to JS file.

js.context.callMethod("loadWaInstance", [userLoggedIn, 'Test User']);

To use js.context.callMethod, first you need to import dart:js in your main.dart file by adding the line below.

import 'dart:js' as js;

js.context.callMethod takes two arguments. They are: the name of the JS function, and an array of parameters for that function. We want to call loadWaInstance. It should show/hide the assistant and use the logged-in user’s name.

After the Login button is clicked, we assume the user has logged in. We then call loadWaInstance to show watsonx Assistant.

We click the Logout button, triggering the same function call. But this time we clear the session in shared preferences and set the False value in the flag to hide the assistant. In this, we also call the destroy function of watsonx Assistant.

js.context.callMethod("loadWaInstance", [false]);

In the actual scenario, you should take the user’s credentials in the Login function to make a REST API call for authentication.

Conclusion

This guide demonstrates how to integrate watsonx Assistant into a Flutter web app. watsonx Assistant offers great flexibility, allowing seamless integration across various channels and programming languages.

Full code can be downloaded from here.

--

--