In this article, I will be exploring the semantics behind an automated Chat bot agent in an ASP.NET website that is hosted on the web app itself and does not depend on any external API services.
Introduction
These days, automation has found itself a place in every trend of Business and Development. And one such automation deals with automated online conversational entities. The idea behind this article is to deploy a Chat Bot in an ASP.NET website (via a Widget) that is not connected to any online bot API services and is directly hosted within the web app itself.
Getting Started
So without further adieu, let's get started.
Let's create an ASP.NET website that will contain the chat bot widget. For this, let us follow the steps below:
- Open Visual Studio (I am on VS 2019 Community Edition).
- Select the ASP.NET Web Application (.NET Framework) template.
- Hit
Next
and give the project a name. I have chosen to name the project BotWebsite
.
- And for this project, we'll select Empty
for an empty web application project.
Next, we'll add a Web Form to the project. This Web Form will be our default web page to which we'll later add our chat bot widget.
To add a Web Form, right click the Project name under Solution Explorer and select Add->New Item..->Web Form and name the file Default.aspx.
Now that we've added the Web Form. We'll import the required NuGet package, click on Tools->NuGet Package Manager->Package Manager Console and type:
PM> Install-Package Syn.Bot.Channels
This will add a reference to the Syn.Bot.Channels
library that we will be making extensive use of in this tutorial. The library we've just imported will provide us with the following crucial elements for our Automated Chat bot.
- JavaScript for deployment and HTML elements that will automatically be inserted into the web page.
- An emulated REST API URL for interacting with our Chat bot.
- A
WidgetChannel
class to customize the core (cosmetic) attributes of our chat bot. - A hassle-free means of connecting the internal bot's NLP system to the externally Chat Bot widget.
Creating the Chatbot Service URL
Every time a Chat Request is sent to our Chat bot widget, the message will be passed as parameters to a URL that will point to a Web Form in our Project. The Web Form (containing the backed Bot system) will then process the message part and return a bot response with the proper headers.
The same URL will also serve the purpose of sending the required JavaScripts, CSS and HTML elements to the browser whenever the Default.aspx page is loaded.
- Right click on your Project name under the Solution Explorer.
- and click Add->New Item..->Web Form.
- Name the file BotService.aspx.
- Right click this newly created Web Form file and select View Code.
- Replace the code within this file with the following:
using System;
using System.Web;
using System.Web.UI;
using Syn.Bot.Channels.Testing;
using Syn.Bot.Channels.Widget;
using Syn.Bot.Oscova;
namespace BotWebsite
{
public partial class BotService : Page
{
private static WidgetChannel WidgetChannel { get; }
private static OscovaBot Bot { get; }
static BotService()
{
Bot = new OscovaBot();
WidgetChannel = new WidgetChannel(Bot);
Bot.Dialogs.Add(new ChannelTestDialog(Bot));
Bot.Trainer.StartTraining();
var websiteUrl =
HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority);
WidgetChannel.ServiceUrl = websiteUrl + "/BotService.aspx";
WidgetChannel.ResourceUrl = websiteUrl + "/BotResources";
WidgetChannel.WidgetTitle = "Our Smart Bot!";
WidgetChannel.LaunchButtonText = "Ask";
WidgetChannel.InputPlaceHolder = "Ask your query here...";
}
protected void Page_Load(object sender, EventArgs e)
{
WidgetChannel.Process(Request, Response);
}
}
}
Time to demystify the above code.
We start by using the static constructor for the BotService
page object. Inside the static constructor, we create and initialize a new OscovaBot
instance. The static constructor is opted to ensure that our WidgetChannel
object will be initialized only once per session.
ServiceUrl
- Main URL that the Bot Widget will use to interact with the underlying Bot system ResourceUrl
- Location to the directory where we'll keep the required image resource files WidgetTitle
- Title of the chat bot widget InputPlaceHolder
- Default watermark-text that is displayed within the Input box LaunchButtonText
- Text that is displayed when the Bot widget is visible on the website
protected void Page_Load(object sender, EventArgs e)
{
WidgetChannel.Process(Request, Response);
}
This is where the magic happens. Every time the BotService.aspx
page is about to load the page, Request
and Response
objects are passed to the WidgetChannel
as arguments.
The agent then processes the Request
and returns a Response
with a proper header. These responses include (but are not limited to):
- JavaScripts
- Cascading Style Sheets
- HTML elements
The following line however, adds a pre-built Channel testing dialog that has the following in-built test commands ready:
- Ping - Bot responds Pong
- Text Message - Bot responds with a random text value
- Quick Reply Message - Bot responds with a set of options the user can select from
- Image Url Message - Bot responds with an image
- Basic Card Message - Bot responds with a card that has a title, description and image
Bot.Dialogs.Add(new ChannelTestDialog(Bot));
Adding Relevant Images
The chat widget that will be displayed on our web page uses certain images and apparently, we'll have to import a few image files into our Project.
- For this, create a new folder by right clicking on the Project name under the Solution Explorer.
- and select Add->New Folder.
- Name the folder "BotResources". In this folder, we'll now add a number of image files required by the Chat Panel.
Next:
- Download the Resource Files I've made available with this article and extract them to any desired folder in your machine.
- In Visual Studio, right click the BotResources
folder, we've just created, and choose Add->Existing Item.. - Select all the files you've extracted
The BotResource
folder now has all the required image files.
The Final Touch
Now that our project is ready, there's this one last thing that we'll have to do to fire up our chatbot.
- Double click the Default.aspx and replace the code with the following:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs"
Inherits="BotWebsite.Default" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>My Website with a Bot</title>
</head>
<body style="background-color: #1d1f21">
<form id="form1" runat="server">
<div>
</div>
<script type="text/javascript">
(function () {
var scriptElement = document.createElement('script');
scriptElement.type = 'text/javascript';
scriptElement.async = false;
scriptElement.src = '/BotService.aspx?Get=Script';
(document.getElementsByTagName('head')[0] ||
document.getElementsByTagName('body')[0]).appendChild(scriptElement);
})();
</script>
</form>
</body>
</html>
The above code pretty much explains it all.
The JavaScript calls the ServiceUrl
and passes "Script
" as a value for the Get
parameter. The Web Form BotService.aspx upon receiving the aforementioned parameter will return the JavaScript to the browser that will automatically add a Style Sheet along with the HTML elements that make up the cosmetics of your Chat bot widget.
Running the Project
Interestingly, we are done with our coding, copying, extracting and what not. We'll go ahead and run the project. To do so, press F5 and you should see the Chat Bot Widget.
If for some reason, you don't see the widget, then refresh the page.
Screenshot
Congratulations! You are ready to test the bot.
To test the bot, try saying ping or quick reply message and you should receive a response.
Adding a Custom Knowledge Base to your Bot
So we've finally hit the million dollar question.
As the NuGet package we've imported into our Project is centered around Workspace Bot project. We'll have to make use of Oryzer Studio for development of the Knowledge Base and later export the project into our project's BotResources folder.
For this, I've painstakingly put together a separate article on Creating an On-Premise Offline Bot in C# using Oscova.
You'll have to go through the article and create a simple knowledge base for the Bot using Oryzer Studio. Once you've created your Knowledge Base, there's one nifty little trick you'll have to do.
Every knowledge base project file you export using Oryzer Studio gets suffixed with the .west extension.
Since access to unknown extensions is forbidden by default in an ASP.NET environment, you can either add that extension to your ASP.NET environment (via IIS) or you'll have to rename the extension to .txt or json.
To do so (while saving your Knowledge Base), enclose the name of your Package (with the .txt or json extention) within double quotes and click Save.
Once you've exported the Workspace project, right click the BotResource folder (in Visual Studio) Add->Existing Item.. and select the exported file. Then using our example code, you can change the first 2 lines in the static constructor to:
Bot = new OscovaBot();
Bot.ImportWorkspace("Path to File");
Points of Interest
While trying to disect the cosmetics behind the Chat Widget, in an attempt to check if any external resources were being used by the Virtual Chat Agent, I learnt that the Chat Bot Widget uses pure JavaScript and has multiple placeholder values within double {{}} curly brackets. You can also extract the internal script by calling WidgetChannel.ExportResources("Directory-Path-Here");
You may want to tinker around the code for customization.
The knowledge base I've used in this article is a pre-built testing dialog. It just lets the developer test how certain types of responses are displayed within the chat panel.
On a side note, I ain't an ASP.NET pro and I firmly believe that there's gotta be a better approach than using a Web Form as the service URL. WCF would probably be a better way to go about? Either way, I'd rather stick with a simpler approach instead of introducing a complex WCF service that might not work as expected for many readers.
History
- 31st January, 2015: Initial release
- 26th August, 2020: Major update
- Previous dependencies removed as they became obsolete
- Updated the entire article to latest library
- Newer screenshots