65.9K
CodeProject 正在变化。 阅读更多。
Home

将自托管聊天机器人添加到 ASP.NET 网站

starIconstarIconstarIconstarIconstarIcon

5.00/5 (18投票s)

2020 年 8 月 26 日

CPOL

7分钟阅读

viewsIcon

121804

downloadIcon

10002

ASP.NET 网站中的自动化聊天机器人代理,不依赖任何外部 API 服务

引言

如今,自动化在商业和开发的各个趋势中都占有一席之地。其中一项自动化就是处理在线对话实体。本文的目的是在 ASP.NET 网站(通过小部件)中部署一个不连接到任何在线机器人 API 服务、而是直接托管在 Web 应用程序本身的聊天机器人。

入门

那么,话不多说,我们开始吧。

让我们创建一个包含聊天机器人小部件的 ASP.NET 网站。为此,我们按照以下步骤操作:

  • 打开 Visual Studio(我使用的是 VS 2019 社区版)。
  • 选择 **ASP.NET Web 应用程序 (.NET Framework)** 模板。

  • 点击“下一步”,然后为项目命名。我选择的项目名称为 `BotWebsite`。

  • 对于这个项目,我们将选择“**空**”以创建一个空的 Web 应用程序项目。

接下来,我们将向项目添加一个*Web 窗体*。此 Web 窗体将作为我们的默认网页,稍后我们将在此添加聊天机器人小部件。

要添加*Web 窗体*,请右键单击“解决方案资源管理器”下的项目名称,然后选择“添加->新建项..->Web 窗体”,并将文件命名为 `Default.aspx`。

现在我们已经添加了 Web 窗体。我们将导入所需的 NuGet 包,点击“工具->NuGet 包管理器->包管理器控制台”并输入:

PM> Install-Package Syn.Bot.Channels

这将为 `Syn.Bot.Channels` 库添加一个引用,我们将在本教程中大量使用它。我们刚刚导入的库将为我们的自动化聊天机器人提供以下关键元素:

  • 用于部署的 JavaScript 和 HTML 元素,它们将自动插入到网页中。
  • 一个模拟的 REST API URL,用于与我们的聊天机器人进行交互。
  • 一个 `WidgetChannel` 类,用于自定义聊天机器人核心(外观)属性。
  • 一种无忧无虑的方式,可以将内部机器人 NLP 系统连接到外部聊天机器人小部件。

创建聊天机器人服务 URL

每次将聊天请求发送到我们的聊天机器人小部件时,消息将作为参数传递到一个指向我们项目中的 Web 窗体的 URL。然后,Web 窗体(包含后端机器人系统)将处理消息部分,并返回带有正确标头的机器人响应。

每当加载 `Default.aspx` 页面时,相同的 URL 也将用于向浏览器发送所需的 JavaScript、CSS 和 HTML 元素。

  • 在解决方案资源管理器下右键单击你的项目名称。
  • 然后单击“添加->新建项..->Web 窗体”。
  • 将文件命名为 `BotService.aspx`。
  • 右键单击这个新创建的 Web 窗体文件并选择“查看代码”。
  • 将此文件中的代码替换为以下内容:
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);

            //Add the pre-built channel test dialog.
            Bot.Dialogs.Add(new ChannelTestDialog(Bot));

            //Start training.
            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);
        }
    }
}

现在来解析上面的代码。

我们首先使用 `BotService` 页面对象的静态构造函数。在静态构造函数中,我们创建一个新的 `OscovaBot` 实例并进行初始化。选择静态构造函数是为了确保我们的 `WidgetChannel` 对象在每个会话中只初始化一次。

  • `ServiceUrl` - 机器人小部件将用于与底层机器人系统交互的主要 URL
  • `ResourceUrl` - 我们将存放所需图像资源文件的目录位置
  • `WidgetTitle` - 聊天机器人小部件的标题
  • `InputPlaceHolder` - 在输入框中显示的默认水印文本
  • `LaunchButtonText` - 当机器人小部件在网站上可见时显示的文本
protected void Page_Load(object sender, EventArgs e)
{
    WidgetChannel.Process(Request, Response);
}

这就是奇迹发生的地方。每次 `BotService.aspx` 页面即将加载时,`Request` 和 `Response` 对象都会作为参数传递给 `WidgetChannel`。

然后,代理处理 `Request` 并返回带有正确标头的 `Response`。这些响应包括(但不限于):

  • JavaScript
  • 级联样式表
  • HTML 元素

然而,以下这行代码添加了一个预建的频道测试对话框,该对话框具有以下内置测试命令:

  • **Ping** - 机器人响应 Pong
  • **文本消息** - 机器人响应随机文本值
  • **快速回复消息** - 机器人响应一组用户可以选择的选项
  • **图像 URL 消息** - 机器人响应图像
  • **基本卡片消息** - 机器人响应包含标题、描述和图像的卡片
//Add the pre-built channel test dialog.
Bot.Dialogs.Add(new ChannelTestDialog(Bot));

添加相关图像

我们网页上显示的聊天小部件使用某些图像,显然,我们需要将一些图像文件导入到我们的项目中。

  • 为此,请在“解决方案资源管理器”下右键单击项目名称,创建一个新文件夹。
  • 然后选择“添加->新建文件夹”。
  • 将文件夹命名为“*BotResources*”。在此文件夹中,我们将添加聊天面板所需的若干图像文件。

下一篇

  • 下载本文提供的资源文件,并将它们解压缩到您计算机上的任意所需文件夹。
  • 在 Visual Studio 中,右键单击我们刚刚创建的 `BotResources` 文件夹,然后选择“添加->现有项..”。
  • 选择您已解压缩的所有文件。

`BotResource` 文件夹现在包含所有必需的图像文件。

最后的润色

现在我们的项目已经准备就绪,还有最后一件事要做才能启动我们的聊天机器人。

  • 双击 `Default.aspx` 并用以下内容替换代码:
<%@ 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>

上面的代码基本上解释了一切。

JavaScript 调用 `ServiceUrl` 并将“`Script`”作为 `Get` 参数的值。Web 窗体 `BotService.aspx` 在收到上述参数后,将向浏览器返回 JavaScript,该 JavaScript 将自动添加样式表以及构成聊天机器人小部件外观的 HTML 元素。

运行项目

有趣的是,我们的编码、复制、提取等工作已经完成。我们将继续运行项目。为此,请按 **F5**,您应该会看到聊天机器人小部件。

如果由于某种原因,您没有看到小部件,请**刷新**页面。

屏幕截图

恭喜!您已准备好测试机器人。

要测试机器人,请尝试说*“ping”*或*“quick reply message”*,您应该会收到响应。

为您的机器人添加自定义知识库

那么,我们终于达到了百万美元的问题。

由于我们导入到项目中的 NuGet 包围绕着 Workspace Bot 项目。我们将不得不使用*Oryzer Studio*来开发知识库,然后将项目导出到我们项目的*BotResources*文件夹中。

为此,我已 painstaking 地编写了一篇单独的文章:使用 Oscova 在 C# 中创建本地离线机器人

您需要阅读这篇文章,并使用 Oryzer Studio 为机器人创建一个简单的知识库。一旦您创建了知识库,您需要做一个巧妙的小技巧。

您使用 Oryzer Studio 导出的每个知识库项目文件都会以*`.west`*扩展名结尾。

由于 ASP.NET 环境默认不允许访问未知扩展名,您可以在 ASP.NET 环境中(通过 IIS)添加该扩展名,或者将扩展名重命名为*`.txt`*或*`.json`*。

要做到这一点(在保存知识库时),请在双引号中包含您的包名称(带*`.txt`*或*`.json`*扩展名),然后单击“保存”。

导出工作区项目后,在 Visual Studio 中右键单击 `BotResource` 文件夹,选择“添加->现有项..”,然后选择导出的文件。然后,使用我们的示例代码,您可以更改静态构造函数中的前 2 行:

Bot = new OscovaBot();
Bot.ImportWorkspace("Path to File");

关注点

在尝试解析聊天小部件背后的外观,以检查虚拟聊天代理是否使用了任何外部资源时,我了解到聊天机器人小部件使用纯 JavaScript,并且在双*`{{}}`*花括号中有多个占位符值。您也可以通过调用 `WidgetChannel.ExportResources("Directory-Path-Here");` 来提取内部脚本。您可能想修改代码以进行自定义。

本文中使用的知识库是一个预建的测试对话。它只是允许开发人员测试某些类型的响应如何在聊天面板中显示。

顺便说一句,我不是 ASP.NET 专家,而且我坚信使用 Web 窗体作为服务 URL 有更好的方法。**WCF** 可能是更好的选择?无论如何,我宁愿坚持一个更简单的方法,而不是引入一个复杂的 WCF 服务,这可能会让许多读者感到不适。

历史

  • 2015 年 1 月 31 日:初次发布
  • 2020 年 8 月 26 日:主要更新
    1. 删除了之前的依赖项,因为它们已过时
    2. 将整个文章更新为最新库
    3. 更新的屏幕截图
© . All rights reserved.