跟着我们超赞的截图机器人,我有个好主意。我们为什么不写一个当航班价格变化时提供警报的机器人呢?你怎么想呢?现在,太酷了!
我不知道你的情况,但我总是觉得为我的航班确定一个好价格很棘手。当我提前预订时,我喜欢认为我得到了最好的交易,但情况并不总是这样。例如,我有过这样的例子,我不得不在旅行前几天预订,价格实际上比我几周前看起来的要好。
和其他市场一样,机票价格根据供求关系而波动。当在特定时期对一条路线有大量需求时,价格就会上涨。当没有太多需求时,航空公司会压低票价来填满飞机。记住,航空公司只有当飞机在空中座位满了的时候才赚钱。
最重要的是,很少有一次你坐上了半空的飞机,可以独自坐满整排飞机。航空公司设法尽可能多地打包飞机,尤其是像西南航空或瑞安航空这样的低成本航空公司。
下一个机器人背后的想法是,我们不想去像 Expedia 或 Skyscanner 这样的旅游网站查看机票价格。相反,我们希望我们卑微的机器人为我们工作。最终,机票和机票预订的决定权当然属于我们。
我们应该能够向机器人提供出发地、目的地和旅行日期,我们应该能够获得我们感兴趣的航班的当前价格,但是机器人应该能够随时通知我们这些航班的价格变化(直到我们不再有兴趣接收这些更新)。
听起来很有趣,这将是一个非常有用的工具供我们使用。
为了实现这一点,我们将使用 Azure Table 存储来保存机票信息和相关的航班详细信息。我们还将使用专门的飞行跟踪应用编程接口,并用 Visual Studio 2015 和 C# 编写代码。
我迫不及待地开始使用这个机器人,它会让我知道航班价格何时变化。现在,计算能力开始为我们服务,让我们开始吧。
2011 年,我们在谷歌的好朋友收购了一家令人惊叹的公司,这家公司是由麻省理工学院的计算机科学家在 20 世纪 90 年代中期成立的,旨在解决在不依赖昂贵的大型计算机的情况下准确找到机票的问题。这家公司是 ITA 软件,为谷歌航班和许多其他旅游网站提供动力。
他们的工作成果之一是被称为 QPX 的最先进的旅行引擎,它首先被旅行网站 Orbitz 使用。
QPX 快递应用编程接口是简化航班和机票搜索的 QPX 引擎的一个版本。它基于自助服务和现收现付的模式,让任何开发人员都非常容易获得关于航班和价格的近乎实时的数据。
这是我们的机器人将用来收集航班信息细节和各自价格的应用编程接口。
为了使用这个应用编程接口,我们将注册一个谷歌帐户,该帐户可以是任何 Gmail 或 G 套件(以前称为谷歌应用)帐户。如果你没有谷歌账号,请注册 Gmail 或 G Suite。
超级!让我们使用我们的谷歌帐户来设置 QPX Express 应用编程接口。
要使用 QPX Express API,我们需要在谷歌开发者控制台上创建公钥证书,并在那里注册我们的项目。
谷歌开发者控制台是开发者用来管理和查看其项目使用的谷歌应用编程接口的流量数据、身份验证和计费信息的网站。
在谷歌开发者控制台中,你可以找到你正在使用的应用的所有设置、凭证和元数据。
首先,让我们把浏览器指向这个网址。当您这样做的时候,如果您使用您的谷歌帐户登录,您将看到如图 4.0 所示的欢迎页面。
图 4.0:谷歌开发者控制台欢迎页面
您可能会发现顶部有一个注册免费试用按钮。你可以注册这项服务,这将让你在一定时间内(通常是两个月)获得免费积分,但你会被要求输入你的信用卡详细信息——谷歌这样做是为了验证你是一个真实的人,而不是一个机器人。
在这种情况下,我不会注册免费试用——相反,我会明确搜索 QPX Express API。我可以通过点击启用 API 来实现。当您这样做时,您将看到图 4.1 中的屏幕。
图 4.1:谷歌开发者控制台应用编程接口搜索
在搜索栏中,键入单词 QPX ,当您键入时,API 将出现在列表中。图 4.2 显示了它的外观。
图 4.2:搜索结果中的 QPX Express API
让我们点击 QPX 快速机票应用编程接口链接(显示的结果)来启用该应用编程接口。完成此操作后,您将看到图 4.3 中的屏幕。
图 4.3:谷歌开发者控制台中的 QPX Express API 主页面
点击启用启用应用编程接口。当我们这样做时,我们将看到图 4.4 中的屏幕。
图 4.4:启用了 QPX 快速应用编程接口
太棒了——我们现在启用了这个应用编程接口!接下来,我们需要创建我们的 API 凭据,所以让我们单击创建凭据。当我们这样做时,我们将看到图 4.5 中的屏幕。
图 4.5:添加 QPX Express API 凭据
从下拉列表中选择 QPX 快捷机票 API ,然后点击我需要什么凭据?
图 4.6:选择所需的凭证
单击该按钮后,您将获得 API 键,如图 4.7 所示。
图 4.7:自动创建的凭证
确保你复制了 API 键,然后点击完成。然后,我们可以看到我们生成的应用编程接口密钥。
图 4.8:应用编程接口密钥列表
稍后,您可以编辑应用编程接口密钥设置,以限制其访问方式。现在不急。
让我们接下来创建我们的 VS 项目,然后回到谷歌开发者控制台,进行任何必要的调整。
既然我们已经用谷歌开发者控制台覆盖了基础知识,我们就可以创建我们的 VS 项目了。让我们使用相同的模板,并调用我们的项目机票警报。
图 4.9:为我们的 VS 项目选择机器人模板
点击确定创建项目。创建项目后,在 Visual Studio 中打开解决方案资源管理器,选择项目中的引用部分,然后右键单击并选择管理 NuGet 包。
打开 NuGet 包管理器时,在搜索栏中输入 QPX 字样,即可找到 QPX Express API 客户端库。这是我们将在项目中使用的。我们现在就开始吧。
图 4.10:QPX 快速应用编程接口客户端库获取包
只需点击安装即可安装该库。这样做将把这个库使用的所有必需的依赖项和引用引入到我们的项目中。
我们现在可以从一些代码开始。正如您已经知道的,默认情况下,机器人应用模板创建机器人将使用的基本结构。
我将在控制器文件夹中为我们的 VS 项目添加一个新的类文件,并将其称为范例飞行数据. cs 。然后我将编写一些基本代码,连接到 QPX Express API,并能够获得特定航班的基本票价,目前是硬编码的。
代码清单 4.0
using Google.Apis.QPXExpress.v1;
using Google.Apis.QPXExpress.v1.Data;
using Google.Apis.Services;
using System.Linq;
using System.Collections.Generic;
namespace AirfareAlertBot.Controllers
{
public class ExampleFlightData
{
private const string cStrApiKey =
"Your QPX
Express API Key";
private const string cStrAppName = "AirfareAlertBot";
public static string[] GetFlightPrice()
{
List<string> p = new List<string>();
using (QPXExpressService service = new QPXExpressService(new
BaseClientService.Initializer()
{
ApiKey = cStrApiKey,
ApplicationName = cStrAppName
}))
{
TripsSearchRequest x = new
TripsSearchRequest();
x.Request = new TripOptionsRequest();
x.Request.Passengers = new PassengerCounts
{ AdultCount = 2 };
x.Request.Slice = new List<SliceInput>();
var s = new
SliceInput() { Origin = "JFK",
Destination = "BOS", Date = "2016-12-09" };
x.Request.Slice.Add(s);
x.Request.Solutions = 10;
var result =
service.Trips.Search(x).Execute();
foreach (var
trip in result.Trips.TripOption)
p.Add(trip.Pricing.
FirstOrDefault().BaseFareTotal.ToString());
}
return p.ToArray();
}
}
}
让我们快速分析一下这段代码。我们通过传递 QPX API 密钥和我们的 bot 应用的名称来创建一个QPXExpressService
实例,因为这允许我们使用 QPX Express 服务来验证我们的应用。
当我们被认证时,我们创建一个TripsSearchRequest
实例来检索我们感兴趣的航班的信息。
TripsSearchRequest
包含一个TripOptionsRequest
实例被分配到的Request
属性。
正如其名称所明确表示的,TripOptionsRequest
是一个对象,它允许我们指定我们有兴趣从 QPX Express API 中获取的行程细节。
来自TripOptionsRequest
对象的Passenger
属性被分配给PassengerCounts
类的一个实例,该实例用于指示将有多少乘客旅行。
TripOptionsRequest
实例的Slice
属性被分配给一个List<SliceInput>
对象。一个切片对应一个航班。一个SliceInput
对象用于指定出发地、目的地和旅行日期。
定义了请求的所有细节后,我们可以通过调用service.Trips.Search(x).Execute
方法来执行对 QPX Express API 的查询,该方法返回一个IList<TripOption>
对象,然后我们可以循环该对象来检索旅程的基本费用。
请注意 QPX Express API 是多么简洁、干净和简短。目前我们需要知道的就这些了。
确保用自己的 QPX Express API 键替换cStrApiKey
常量的值。
现在我们已经创建了一个基本的GetFlightPrice
方法,我们可以从 MessagesController.cs 调用它,如代码清单 4.1 所示。
代码清单 4.1:消息控制器调用 GetFlightPrice
using System;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Http;
using Microsoft.Bot.Connector;
using AirfareAlertBot.Controllers;
namespace AirfareAlertBot
{
[BotAuthentication]
public class MessagesController : ApiController
{
public async Task<HttpResponseMessage> Post([FromBody]Activity
activity)
{
if (activity.Type == ActivityTypes.Message)
{
ConnectorClient connector = new ConnectorClient(new
Uri(activity.ServiceUrl));
string[] p = ExampleFlightData.GetFlightPrice();
Activity reply = activity.
CreateReply($"Flight
price {p?[0]}");
await connector.Conversations.
ReplyToActivityAsync(reply);
}
else
{
HandleSystemMessage(activity);
}
var response = Request.CreateResponse(HttpStatusCode.OK);
return response;
}
private Activity HandleSystemMessage(Activity
message)
{
if (message.Type == ActivityTypes.DeleteUserData)
{ }
else if
(message.Type == ActivityTypes.ConversationUpdate)
{ }
else if
(message.Type == ActivityTypes.ContactRelationUpdate)
{ }
else if
(message.Type == ActivityTypes.Typing)
{ }
else if
(message.Type == ActivityTypes.Ping)
{ }
return null;
}
}
}
如果我们现在用 Bot Emulator 运行这段代码,我们将得到如图 4.11 所示的结果。
图 4.11:基本 QPX 快速应用编程接口示例代码的执行
太棒了。只需几行代码,我们就能够使用 QPX Express API 检索航班价格。
现在,让我们通过让我们的机器人处理对话来让它变得更加有趣和复杂。它将询问与旅行相关的问题,并引导与用户的对话,根据这些问题的答案,它将构建一个动态查询,传递给 QPX Express API,以检索该旅行最便宜的航班。
听起来很刺激,所以让我们让机器人更聪明。前面还有很多工作要做,代码库将变得越来越大,越来越复杂,但是它将使用 FormFlow 很好地构建,这将使我们相对容易地浏览。
为了让我们的机器人更聪明,让我们后退一步,根据我们刚刚写的例子来分析机器人应该做什么。
和我们之前的机器人一样,这个机器人也应该能够同时处理多个请求,而不会被困在任何一个特定的机器人中,所以它应该异步处理请求。
此外,处理特定请求所需的所有信息都应该提前收集(在我们尝试处理请求之前)。
用户也可以通过简单地输入单词退出来决定取消请求。收集的需求应该遵循一个定义好的结构,一系列基本问题一个接一个地呈现给用户。
当请求提交后,结果应该呈现给用户。如果用户选择跟随一个特定的航班(对于价格变化通知),如果价格有变化,机器人将自动向用户发送更新的航班信息(这将使用计时器间隔进行)。
用户应该能够选择不接收任何进一步的航班价格变化通知。我们通过键入单词取消跟随,然后是之前获取的航班详细信息的请求标识来实现。
本质上,所需的信息和请求的执行应该打包成一组原子指令。
考虑到这一点,机器人将需要向用户请求以下信息:出发地、目的地、旅行日期(出站和进站,如果适用)、乘客数量以及用户是否希望收到价格变化通知。
QPX Express API 使用 IATA 国际机场代码,这意味着为了识别出发地和目的地,我们将需要使用 JSON 数据,该数据将任何给定机场的通用名称及其所属城市与其相应的 IATA 代码进行映射。
如果在一个特定的出发地或目的地有多个机场,机器人应该能够向用户强调这一点,并询问他们更喜欢这些选项中的哪一个。
当起点和终点确定后,机器人将收集剩余的细节,如旅行日期、乘客数量以及旅行是单程还是往返。
把这些写下来听起来像是一件容易的事情,但实际上并不是。所以,让我们把问题分解成几个部分,一次做一个。这样做将使整个过程更容易实现和遵循。
因为机器人的代码库会非常大,所以让我们结束这一章,并在下一章专门探讨 AirfareAlertBot 代码中最重要的部分,例如会话状态管理、FormFlow 代码和扩展 MessagesController.cs。
在这简短的一章中,我们已经研究了机票警报包背后的概念,我们也已经简单地熟悉了 QPX Express 应用编程接口。我们现在甚至能够编写一些代码与之交互。
我们这样做是为了对我们将在下一章构建的东西有一个感觉,那就是成熟的机器人。我们将探索机器人框架的关键方面,并将全面关注会话状态管理、使用 FormFlow 的会话流、会话验证以及连接机器人的中心枢纽 MessagesController.cs。
听起来我们面前有相当大的挑战,所以让我们开始吧。