如何使用Twilio,Python和Google表格(带有Free&nbspCode)制作可扩展的SMS聊天机器人

我们中的许多人正在帮助面临困境的企业,或者我们自己正在面对困境的企业。如果您在遇到麻烦的公司(或客户)中工作,则使用SMS聊天机器人可能是一种让您脱离常规解决方案列表并以完全不同的方式帮助他们成功的方法。如果您是寻找工作的营销人员,那么将其添加到您的技能列表中可能意味着您在许多通常的门关闭或打开新的门的同时,保持事情的顺利进行。

你会得到什么

在这篇文章中,我为您提供了说明和代码,它们不仅可以生成一个代码,还可以生成一系列可以由Google Sheets管理的基于文本的聊天机器人。

此处的示例设置为可与餐厅一起使用,但可适用于需要接收订单,根据库存/菜单检查订单并记下要履行的任何业务。

一旦建立了系统,就无需为新业务创建新的基于SMS的聊天机器人的编码。另外,该企业将能够通过简单地更新Google表格来管理关键详细信息(如来料订单和菜单),从而使所有这些功能比大多数其他选项更易于访问。

但是首先,一些背景。

一些背景

2017年9月,作为我在Distilled的第一个大型激情项目之一,我写了一篇Moz博客文章,告诉人们如何制作聊天机器人并给出一些示例代码

今年四月,我收到了一封来自亚历山大·西尔维斯特(Alexandre Silvestre)的电子邮件。亚历克斯(Alex)发起了“一项非营利性的工作,以帮助当地的小企业主渡过这些充满挑战的时代,挽救尽可能多的工作,并继续为我们的社区服务,同时帮助平缓曲线。”

这项工作始于专注于餐厅。亚历克斯找到了我的2017年职位(天哪,内容营销有效!),问我是否可以帮助他的团队构建聊天机器人。我们就该漫游器达成了一些基本要求:

  • 它必须完全在短信中工作(如果订单非常复杂,则必须能够直接与餐厅打个电话)。
  • 运行它必须尽可能接近免费。
  • 餐馆必须能够检查订单,更新菜单等,而无需设置特殊帐户。

我们达成一致的解决方案包括三个部分:

  • Twilio(收费):提供电话号码并处理大部分对话。
  • Google Cloud Functions(半免费):调用URL时,它将运行代码(包括更新餐厅的数据库)并返回响应。
  • Google表格(免费):我们的数据库平台。我们有一个工作表,其中列出了使用我们的聊天机器人的所有业务,并链接到每个业务的各个Google表格。

我将依次介绍这些组件,并告诉您如何使用它们。

如果您要返回本文,或者只需要一个领域的帮助,请随时跳到您感兴趣的特定部分:

价钱

这一切应该都便宜得多-我说的是每张订单四美分。

即使这样,也要始终确保所有定价警报都通过您主动监控的电子邮件地址发送。

当您刚开始执行此操作或进行了更改(例如添加新功能或新业务)时,请确保在接下来的几周内重新检查您的信用,以了解发生了什么。

特威里奥

本地Twilio电话号码的费用约为每月$ 1.00。发送和接收文本的费用约为0.0075美元,而Twilio Studio(我们用来做很多“对话”的费用)每次激活时的费用为0.01美元(每月前1000个免费)。

因此,假设您每月有2500个文本订单,而每个订单大约要处理5条文本消息,那么每月的总费用约为100美元。

Google表格

Google表格是免费的,而且很棒。Google表格万岁。

Google Cloud功能

Google在此处共享完整的定价详细信息,但要了解的重要事项是:

1.促销信用

您将获得长达一年的免费试用期,其中包括$ 300的促销信用,所以它将在花您的钱之前就花掉它。在一个月的测试结束时,我们已支出$ 0.00(包括促销赠金)。那是因为还有每月的免费津贴。

2.免费津贴和定价结构

除了免费信用外,Google每月都会提供免费津贴。如果我们假设每个订单大约需要激活我们的代码5次,并且每次运行代码最多需要五秒钟(这是一段时间,但有时Google Sheets速度很慢),那么我们每个月可能会收到多达40万个订单我们投入了促销信用。

特威里奥

Twilio是一个付费平台,可让您购买电话号码,并让该号码根据输入自动发送某些回复。

如果您不想阅读有关Twilio的更多信息,而只想要免费的Twilio聊天机器人流程,就在这里。

步骤1:购买Twilio电话号码

购买电话号码后,您可以收到该号码的文字,然后将在您的Twilio帐户中对其进行处理。您也可以通过该号码发送短信。

步骤2:找到您的电话号码

您可以通过单击左上角的Twilio菜单,然后单击“电话号码”来查看购买的电话号码列表。或者,您可以转到电话号码/传入

一旦看到列出的电话号码,请记下它。

步骤3:建立Studio流程

Studio是Twilio的拖放编辑器,可让您创建对话的结构。工作室“流程”只是您已建立的特定对话的名称。

再次单击Twilio菜单,然后单击“运行时”下的“ Studio”,即可进入Twilio Studio。

通过单击“创建流”来创建新流。

创建新流程时,您可以选择从头开始,也可以使用内置选项之一为您创建流程(尽管它们不会像我所使用的模板那样深入)在这里分享)。

如果要使用我和Alex构建的流的版本,请选择“从JSON导入”,然后单击“下一步”。然后,下载此文件并将内容复制到出现的框中。

确保它以一个大括号开头,以一个大括号结尾。出现的框将自动包含{},并且如果您在粘贴之前不删除它们,则会加倍,并且它不会接受您的输入。

如果一切顺利,将为您提供如下流程:

您可能会问:彩色意大利面的纠结到底是什么圣物?

那就是我们创建的Twilio Studio流程,不用担心,它基本上会分解为一系列多项选择题,每个问题的答案将决定您下一步要去哪里。

您可以在画布上看到的所有内容都是Twilio Studio小部件库中的小部件,并与“如果是,那么是”类型条件连接在一起。

Studio Flow流程

在我们进入过程中的特定块之前,下面是发生的情况的概述:

  1. 客户向我们的Twilio号码发送消息
  2. 根据发送的具体号码,我们查找与其关联的餐厅。然后,我们使用餐厅的名称和保存的菜单向顾客发送消息。
  3. 如果客户尝试下单,我们会致电餐厅
  4. 如果客户从我们的菜单中选择某种东西,我们会询问他们的名字,然后将其订单记录在该餐厅的表中,并告诉他们何时到达取货
  5. 当/当用户消息告诉我们他们在餐馆外面时,我们询问他们是否在步行/对他们的车辆的描述。我们将车辆描述记录在同一张餐厅表中。

让我们看看一些示例构建基块吧?

初始触发

初始触发器会在每个流程的开始出现,并根据是短信,电话还是代码正在访问来拆分传入的联系人。

“传入消息”表示该联系人是通过短信发送的。我们现在只需要担心这一点,所以让我们集中在左手边。

记录我们正在开始新互动的事实

接下来,我们使用“设置变量”块,您可以从小部件库中获取该块。

“设置变量”块使我们可以保存记录信息,以备日后参考。例如,我们首先设置交互的“阶段”。我们说阶段是“开始”,就像我们处于互动的开始一样。稍后,我们将在Studio和外部代码中检查stage的值是什么,以便我们知道什么时候做什么。

获取我们的菜单

我们假设如果有人向我们发送了消息,触发了聊天机器人,他们正在寻求订购,因此下一步就是确定适用的菜单。

现在,我们可以直接将菜单写到Studio中,并说只要有人向我们发送消息,我们就会以相同的选项列表进行响应。但这有几个问题。

首先,这意味着如果我们要为多个餐厅进行设置,则必须为每个餐厅创建一个新流程。 

更大的问题是餐馆经常更改菜单。如果我们希望这可以为许多不同的餐厅提供,那么我们就不想花费所有时间在餐厅用完所有食材时手动更新Twilio。

因此,我们真正需要的是餐厅能够列出自己的菜单。这就是Google表格的用武之地,但是我们稍后再讨论。在Twilio中,我们只需要能够询问外部信息并将该外部信息转发给用户。为此,我们使用Webhook小部件:

这个小部件向URL请求,获取响应,然后让我们在消息和流中使用响应的内容。

如果对URL的请求成功,则Twilio将自动继续执行成功步骤,否则我们可以将其设置为发送带有“失败”选项的“糟糕,出了点问题”响应。

在这种情况下,我们的Webhook将向Google Cloud函数URL发出请求(稍后会详细介绍)。我们发送的请求将包含一些有关用户以及我们需要代码做什么的信息。信息将采用JSON格式(与我上面共享的导入Twilio流的格式相同)。

我们的JSON将包含已发送消息的特定Twilio电话号码,我们将使用该号码来区分餐厅以及与我们联系的电话号码。它还将包含我们收到的文本消息的内容以及我们之前设置的“阶段”,因此代码可以知道用户在寻找什么。

然后,代码将做一些事情(稍后再介绍)并返回其自身的信息。然后,我们可以告诉Twilio在消息中使用部分响应。

发送消息以回应

接下来,我们可以使用收到的信息来构造并向用户发送消息。Twilio会记住您正在与之通话的号码,并将您的消息发送到该号码。

这是“发送并等待回复”窗口小部件,这意味着一旦发送了此消息,Twilio将假定对话仍在继续而不是在此结束。

在这种情况下,我们正在写欢迎信息。我们可以只写简单的内容,但是我们想使用从Webhook小部件获得的一些变量。我们将特定的Webhook小部件称为“ get_options”,因此我们可以通过编写以下内容来访问从中获取的内容:

{{widgets.get_options

响应以JSON返回,幸运的是Twilio会自动将其分解为我们。 

我们可以通过以下方式访问响应的各个部分:编写“已分析”,然后在响应中给我们提供该信息的标签。就这样,代码的响应看起来像这样:

{“名称”:restaurant_name,

“ dishes_string”:“您可以选择Margherita披萨,夏威夷比萨,素食比萨”

“附加”:“大,中,小”}

我们通过编写“ {{widgets.get_options.parsed.dishes_string}}”来获得可用菜单,然后在下面编写消息,该消息将发送给与机器人联系的人:

根据消息做出决定

我们不能假设每个人都将以完全相同的方式使用该机器人,因此我们需要能够根据特定条件更改我们的工作。“基于…拆分”小部件是我们如何选择某些条件并设置满足条件的方法。

在这种情况下,我们使用对上一条消息的响应内容,可以使用{{options_follow_up.inbound.Body}}访问该消息。“ Options_follow_up”是我们刚才谈到的“发送并等待”小部件的名称,“入站”表示响应,“正文”表示其中的文本。

然后我们设置一个条件。如果用户以“其他”,“否”,“帮助”等类似的方式进行响应,他们将被转移到另一条轨道上以打电话。如果他们回答未列出的任何内容,则可能是他们在尝试订购,因此我们接受他们的订购,并使用我们的代码进行检查:

拨打电话

如果用户说他们想要菜单外的东西,我们需要与餐厅打个电话。为此,我们首先致电用户:

然后,当他们接听时,将该呼叫连接到我们已经在工作表中查询过的餐厅号码:

步骤4:为此电话号码选择您的工作室流程

请按照第二步中的说明返回购买的电话号码的特定列表。然后滚动到底部,然后选择您创建的Studio Flow。

Google表格

该聊天机器人使用两个Google表格。

免费查阅表

查找表包含Twilio电话号码,已分配给他们的餐厅的列表以及保存该餐厅详细信息的Google表格的URL,以便我们知道在哪里查找。

您需要创建工作表的副本才能使用它。我在共享的表格中添加了一行,解释了每一列。当您知道自己在做什么时,可以将其删除。

免费示例餐厅表

特定于餐厅的工作表是我们在一系列标签中包含有关餐厅的所有信息的地方。您需要创建工作表的副本才能使用它。 

订单

订单标签主要由我们的代码使用。它将自动输入订单时间,客户名称,客户电话号码和订单详细信息。默认情况下,它将在“ PAID / READY?”中写FALSE。列,然后餐厅将需要更新该列。

在最后阶段,脚本会将TRUE添加到“ CUSTOMER HERE?” 列,并在“提取信息”列中提供汽车说明。

等待时间

这是一个非常简单的标签,因为它包含一个单元格,餐厅在该单元格中写入要在准备好订单之前需要多长时间。我们的代码将提取该内容并将其提供给Twilio,让客户知道他们将等待多长时间。

可用的菜肴和添加选项卡

餐馆列出了现在可用的菜肴以及对这些菜肴的简单修改,然后这些菜单在顾客联系餐馆时发送给顾客。当代码收到订单时,它还将根据发送的菜肴列表检查该订单,以查看客户是否选择了其中一种。

使用工作表标签的脚本

您根本不需要触摸它-这只是为了避免我们的代码意外覆盖自己。

想象一下这样一种情况,我们的代码获取一个订单,在订单表中找到第一个空行,并将该订单写在此处。但是,与此同时,其他人为同一家餐厅下了订单,我们代码的另一个实例也寻找第一个空行,选择了同一行,并且他们都在同一时间写入了该行。即使代码认为一切都很好,我们也会丢失至少一个订单。

为了避免这种情况,当我们的代码开始使用表格时,首先要做的是将“ Script using sheet”值更改为TRUE,并在开始使用表格时写下来。然后,完成后,将值更改回FALSE。

如果我们的脚本使用该工作表,并且看到“使用工作表的脚本”设置为TRUE,它将等待该值变为FALSE,然后记下该顺序。

如何使用床单?

餐厅表示例:

  1. 复制示例餐厅表。
  2. 填写您的测试餐厅的所有详细信息。
  3. 复制工作表的网址。

查找表:

  1. 制作一份查找表的副本(您只需创建一个)。
  2. 不要删除“提取的ID”列中的任何内容,而要替换其他所有内容。
  3. 在第一栏中输入您的Twilio号码。
  4. 将测试餐厅的网址粘贴到“业务表网址”列中。
  5. 在最后一栏中添加您公司的电话号码。

分享:

  1. 找到“服务帐户”电子邮件地址(我将在“云功能”部分中将您定向到该电子邮件地址)。
  2. 确保两个工作表都与具有编辑权限的电子邮件地址共享。

创建一个新餐厅:

  1. 任何时候您需要创建一个新餐厅时,只需复制餐厅表即可。
  2. 复制时,请确保勾选“与同一人共享”。
  3. 清除当前详细信息。
  4. 将新的Google表格URL粘贴到查找表的新行中。

代码运行时,它将打开查找表,使用Twilio电话号码查找该餐厅的特定表ID,转到该表,然后返回菜单。

Google Cloud功能

Google Cloud Functions是一种简单的自动在线运行代码的方法,而无需在特定位置设置服务器或安装一堆特殊程序来确保代码可传输。

如果您不想了解有关Google Cloud的更多信息,而只想运行代码,那么这里是免费的chatbot Python代码

代码在做什么?

我们的代码不会尝试处理任何实际的对话,它只是从Twilio获取请求-包括有关用户及其所处阶段的详细信息-并执行一些简单的功能。

阶段1:“开始”

该代码从Twilio接收一条消息,其中包括已激活的Twilio编号以及用户所在的阶段(开始)。基于它是“启动”阶段,该代码激活了启动功能。

它根据Twilio编号查找特定的餐厅表,然后返回该餐厅的菜单。

它还发送Twilio之类的信息,例如特定餐厅的编号,菜单的精简版本以及我们可以用来检查订单的其他内容。

第二阶段:“选择”

该代码接收用户(选择)所处的阶段以及他们的订购消息,餐厅的工作表ID和压缩菜单(之前已发送给Twilio),因此我们不必查找这些内容再次。

基于它是“选择”阶段,该代码将激活所选功能。它检查订单是否与我们的精简菜单匹配。如果没有,它将告诉Twilio该消息看起来不像命令。 

如果订单与我们的菜单匹配,它将在第一行空白处写下订单。它还会创建一个订单ID,该ID是时间和一部分用户电话号码的组合。

它会向Twilio发送一条消息,说明订单是否与我们的菜单匹配,如果订单与我们的菜单匹配,则订单号是什么。

第三阶段:“到达”

该代码接收用户到达(到达)的阶段并激活到达的功能。它还会接收到描述用户的车辆,餐厅特定的工作表ID和订单号的消息,这些消息先前已告知Twilio。

它查找餐厅表,并找到与其发送的订单相匹配的订单ID,然后更新该行以显示用户已经到达并描述他们的汽车。

Twilio处理所有上下文

您似乎很奇怪,每当代码找到一些信息(例如,要查找的工作表ID)时,它就会将该信息发送给Twilio,并在以后再次请求它。那是因为除了Twilio告诉我们的内容外,我们的代码根本不知道发生了什么。每次我们激活代码时,它的启动方式都完全相同,因此它无法知道哪个用户正在向Twilio发短信,他们处于什么阶段,甚至我们正在谈论的餐厅。

Twilio在交互过程中会记住这些东西,因此我们使用它来处理所有这些东西。我们的代码是一个非常简单的“执行程序”-一次不知道任何内容的时间超过五秒钟。

如何设置代码?

我没有时间描述如何深入使用Google Cloud Functions或如何使用Python进行编码,但是我在上面共享的代码中包含大量注释,可以解释发生了什么,我将与您谈谈通过此过程的特定步骤。

步骤1:设定

确保你:

步骤2:建立新功能

转到此处,然后单击“创建新功能”。如果您以前从未创建过项目,则可能需要先执行该操作,然后再为该项目命名。

步骤3:列出您的功能的详细信息

下面的屏幕快照为您提供了许多所需的详细信息。我建议您选择256MB的内存-应该足够了。如果发现问题(或者从一开始就更加谨慎),则将其增加到512MB。

确保选择HTTP作为触发器,并记下它提供的URL(如果您忘记了,可以随时通过转到函数的“ Trigger”选项卡找到URL)。

还要确保您选中允许未经身份验证的访问的选项(这样Twilio将能够启动该功能)。

选择“内联编辑器”,然后粘贴我给您的Gist代码(对此进行了大量评论,我建议您对其进行阅读,以确保您对它的工作感到满意)。

点击“ REQUIREMENTS.TXT”,然后粘贴您需要使用的以下库:

  • 烧瓶
  • 特威里奥
  • pytz

确保“要执行的功能”是SMS,然后单击“环境变量”下拉列表。

就像我在上面所做的那样,单击“ +添加变量”,在“名称”列中输入“ spreadsheet_id”,然后在“值”列中,粘贴您的查找表的ID。通过查看查找表的URL,然后复制最后两个斜杠之间的所有内容(下面用红色概述),可以获取ID。

点击“服务帐户”下拉菜单。它应该仅带有“ App Engine默认服务帐户”,并为您提供一个电子邮件地址(如下所示),这是您需要与所有Google表格共享的电子邮件地址。将其写下来,然后将其添加为查找表和餐厅特定表的编辑用户。

完成所有这些操作后,单击“部署”。

部署后,您应该回到云功能的主屏幕。左上角的绿色对勾表示您一切正常。

步骤4:开启Sheets API

您的代码首次尝试访问Google表格时,由于您需要打开帐户的Google表格API,因此可能无法访问。转到此处,使用左上角的下拉菜单选择您正在处理的项目,然后单击蓝色的大“启用”按钮。

步骤5:返回Twilio并为代码粘贴HTTP触发器

还记得我们创建函数时记下的触发器URL吗?返回您的Twilio Studio并找到左上角带有</>符号的所有块:

依次单击每个,然后将您的Google Cloud URL粘贴到屏幕右侧出现的REQUEST URL框中:

测试机器人

现在,您应该已经设置了Cloud Function。您还应该同时设置两个Google表格并与您的Cloud Function服务帐户共享。

下一步是测试机器人。首先给Twilio数字发短信“ order”一词,以使其正常运行。它应该以菜单进行响应,您的代码将从您的餐厅特定的Google表格中提取。请遵循将其发送到最后的步骤,并检查您的Google表格,以确保其正确更新。

如果由于某种原因它不起作用,可以在两个地方检查。通过单击右上角的小“ Debugger”符号,Twilio保留了所看到的所有错误的日志:

Google还会记录您的Cloud Function发生的所有情况。这包括非错误通知。您可以通过单击顶部的“查看日志”来查看所有这些信息:

结论:打破事物,玩得开心

所有这些都不是完美的,而且我敢肯定您可以添加和改进,但是这是一种构建可伸缩聊天机器人网络的方式,每个聊天机器人都专门针对不同的业务,并且由该业务部分管理最低成本。

试试看,破坏它,改进它,撕毁它,然后重新开始,让我知道您的想法!

 

后记:怪异的骇客

这一点只对有兴趣的人真正有用,但是由于我们故意在小范围内完成此操作,因此我们遇到了一些奇怪的问题-主要是关于尚未被激活的对我们的机器人的请求。

当Twilio在一段时间内第一次收到消息时,它会很快打开,并期望其他事情也会这样做。例如,当Twilio向我们的代码发出请求时,它假定代码花费的时间超过大约五秒钟,则该代码失败。这不是很不寻常-许多聊天平台要求最长五秒钟的周转时间。

即使使用较低的内存余量,Cloud Functions都可以运行得非常快,但是通过API访问Google表格似乎总是有点慢。实际上,如果一段时间未访问Google表格,则它的速度特别慢。

这意味着,如果最近没有人使用您的漫游器,则Google Sheets API花费的时间太长,无法在第一时间做出响应,而Twilio在我们的代码返回之前就放弃了,从而导致错误。

我们的脚本中有两部分旨在避免这种情况。

再试一次

第一次激活云功能时,我们不希望它实际更改任何内容,而只需要信息。因此,在Twilio中,我们首先创建一个名为“ retries”的变量并将其值设置为0。 

如果请求失败,则检查重试值是否为0。如果是,则将重试值设置为1,然后重试。如果第二次失败,我们不想永远这样做,因此我们会发送错误并在那里停止。

唤醒床单

第二次激活云功能时,我们确实希望它做某事。如果没有及时返回,我们就不能再做一次,因为我们最终将获得重复的订单,这对于餐厅来说是一个头疼的问题。

取而代之的是,在交换的较早部分中,我们对一张工作表进行了无意义的更改,以便在进行重要更改时可以随时进行准备。

在对话流程中,我们:

  1. 发送菜单
  2. 得到回应
  3. 询问用户名
  4. 写订单

在第四步之前,我们不需要对表单做任何事情,但是在得到用户的响应之后(在询问他们的姓名之前),我们将激活代码一次,以将无用的东西写入订单中。我们对Twilio说(无论是成功还是失败)继续进行互动,因为在那个时候我们是否及时返回都无关紧要。然后,希望在我们按订单编写时,Google表格已经可以实际使用了。

有局限性

Google表格不是理想的数据库-它运行缓慢,可能意味着我们错过了Twilio的超时。但是,这几个额外的步骤可帮助我们解决其中一些限制。

相关文章