使用 Twilio、Flask 和 Python 构建 WhatsApp 抽认卡应用

2025 年 1 月 8 日 | 阅读 16 分钟

抽认卡是最行之有效的学习辅助工具之一,帮助从语言学习者到医学生的所有人实现记忆目标。得益于 Anki 或 Memrise 等程序提供的众多功能和灵活设置,数字抽认卡变得越来越有用。然而,在许多情况下,您可能无法使用其中一个功能更强大的程序,并且需要更便携的工具来学习。

例如,当您可以在手机上记笔记但无法加载功能齐全的 Web 应用程序时。或者您在飞机上,飞机阻止访问某些网站,但允许您在空中时记录数字以着陆。为了让您随时随地开始学习抽认卡,本指南将演示如何为 WhatsApp 或 SMS 创建一个简单的抽认卡机器人。下面是我们将要构建的示例

Build a WhatsApp Flashcard App with Twilio, Flask, and Python

本教程的要求

您需要以下项目才能学习本教程

  • Python 3.6 或更高版本。如果您的操作系统没有 Python 解释器,您可以访问 python.org 获取安装程序。
  • 我们将开发一个对传入的 WhatsApp 消息做出反应的 Web 应用程序。
  • 我们将把抽认卡存储在一个非常基本的数据库中。
  • 这个有用的工具会将您计算机上当前运行的 Flask 应用程序链接到 Twilio 可以连接的公共 URL。您的机器很可能隐藏在网络或防火墙后面,无法直接从 Internet 访问,因此这对于聊天机器人的开发版本至关重要。如果您尚未安装 ngrok,可以获取 Windows、Macintosh 或 Linux 版本的 ngrok。
  • 一部安装了 WhatsApp 并拥有可用电话号码的智能手机。如果您更喜欢常规短信而不是 WhatsApp,本指南也适用于两者。
  • 一个 Twilio 个人资料。如果您是新客户,请创建一个免费的 Twilio 帐户。查看免费 Twilio 帐户的功能和限制。

配置沙盒

请注意,如前所述,本课程适用于 SMS 和 WhatsApp。如果您想使用 WhatsApp,则必须阅读此部分。如果您想使用 SMS,请按照“创建 SMS 聊天机器人”教程中“配置 Twilio 的可编程 SMS”部分中的步骤进行操作。

Twilio 提供的 WhatsApp 沙盒使创建和测试您的应用程序变得简单。一旦 WhatsApp 批准您的应用程序,您可以请求您的 Twilio 电话号码的生产访问权限。

将手机连接到沙盒是下一步。在您的 Twilio 控制台上选择可编程 SMS 后,单击 WhatsApp。您可以在 WhatsApp 沙盒页面上查看您帐户的加入代码和沙盒号码。

Build a WhatsApp Flashcard App with Twilio, Flask, and Python

向您帐户关联的号码和提供的代码发送 WhatsApp 消息,以在您的智能手机上启用 Snapchat 沙盒。代码中的第一个词将是 join,然后是两个随机选择的词。根据 Twilio 的回复,您的手机号码应该在您发送消息后不久连接到沙盒,并且能够发送和接收消息。

请记住,对于您希望连接到沙盒的任何手机,请重复此过程。

虚拟环境创建

按照 Python 的最佳实践,我们将为我们的抽认卡机器人项目创建一个新目录,并在其中建立一个虚拟环境。然后将安装我们聊天机器人所需的 Python 包。

要在 Unix 或 Mac OS 系统上完成上述步骤,请启动终端并键入以下命令

命令提示符

如果您在 Windows 上遵循本指南,请在命令提示符窗口中输入以下语句

命令提示符

最后一条命令使用 Python 包安装程序 pip 安装了我们本项目所需的四个包,它们是

  • 为了构建 Web 应用程序,我们使用了 Flask 框架。
  • 我们使用 Twilio Python Helper 库来处理 Twilio API。
  • 为了连接到数据库,我们使用了 Flask-SQLAlchemy 库。
  • 为了管理数据库,我们使用了 Flask-Migrate 库。

供您参考,本教程发布时测试了上述包及其依赖项的以下版本

创建抽认卡机器人

万岁!您已经准备好了。在下一节中,看看我们的抽认卡机器人将要做什么。一个抽认卡最基本的是有正面和背面。客户可以通过查看正面来推断背面是什么。因为这是一个数字抽认卡,如果客户成功猜出答案,他们就会进入下一个抽认卡;否则,他们可以再试一次,直到成功。

这意味着我们的抽认卡机器人必须具备以下三个关键功能

  1. 启动客户后,我们必须能够区分不同客户的抽认卡(也称为电话号码)。
  2. 制作抽认卡:机器人最初需要更多抽认卡。
  3. 使用机器人复习抽认卡很有趣。

Twilio 和 Python

如果这是您第一次使用 Twilio 和 Python 构建机器人,那么 Miguel Grinberg 的《使用 Python、Flask 和 Twilio 创建 WhatsApp 聊天机器人》是一个很好的起点。它涵盖了理解 Flask、Twilio 和 webhook 如何协同工作所需的所有基本细节。本教程的其余部分扩展了其中涵盖的内容,假设读者完全理解这些材料。

抽认卡机器人配置

首先创建 config.py 文件并将其放在 flashcard-bot 文件夹中。这将保存我们的数据库设置。接下来,在 flashcard-bot 文件夹中添加一个名为“app”的新子文件夹,并在其中添加空的 Python 文件“__init__.py”、“models.py”和“routes.py”。

models.py 存储我们的客户和抽认卡数据库模型以及 __init__.py 中包含的基本应用程序设置。Twilio webhook 存储在 routes.py 中。

config.py 文件

将以下内容粘贴到配置文件中。这指示了我们 SQLite 数据库在 Flask 应用程序中的位置。请务必修改 SECRET KEY 值以使其独一无二!

apps/__init__.py 文件

现在让我们检查 __init__.py 文件。此文件包含执行我们的 Flask 应用程序所需的所有设置。重点关注 _update_db(obj) 函数。当客户进行更改时,我们会使用它来更新我们的信息,因此在开始开发 webhook 时,我们会大量使用它。

代码片段

此文件底部的一行 `from app import methods and models` 可能看起来很奇怪。我们将此行添加到底部,以防止在启动 Flask 服务器时出现循环依赖。在 Flask 可以正确加载完整文件之前,必须在 routes.py 和 models.py 文件中实例化应用程序和数据库对象。通过将这些文件的导入放在底部,我们可以确保所有相关对象都已实例化。

app/models.py 文件

在创建路由之前,我们必须首先设置我们的两个数据库表。我们使用两个基本模型

  1. 客户:跟踪客户的电话号码,链接到使用该号码创建的抽认卡,以及他们当前正在学习的抽认卡。
  2. 抽认卡:将每个抽认卡的 front_side 和 back_side 存储起来。

models.py 文件

请注意,我们最令人难忘的模型 Client 不仅保存电话号码和 Client 制作的备忘单,还保存正在查看的备忘单。由于客户和 Twilio 之间的实际交互不存储状态,因此我们存储此信息。因此,如果我突然注意到我的抽认卡机器人,Twilio 不会存储我上次不需要做的事情。它不知道我是在制作、复习还是复习抽认卡。因此,为了确定合法操作,我们需要在数据库中存储一些状态。

鉴于此,模型中有两种方法——`get_new_review11(s)` 和 `stop_reviewing(s)`——以及数据库中的列。这些是帮助改变客户状态的函数。请注意,我们已在此模型中主动使用了我们的辅助功能 `_update_db` 两次。

您可能还没有在其他使用 SQLAlchemy 定义其数据库模型的 Flask 教程中注意到一些事情。这些事情包括客户和抽认卡模型之间关系的设置方式。

代码片段

db.relationship 上的显式主连接属性是第一个 ()。我们使用它是因为客户和抽认卡之间存在许多连接,如果我们不使用它,就会收到 AmbiguousForeignKeysError。这是因为我们试图在客户数据库和抽认卡表之间建立两个连接:客户到所有他们的抽认卡,以及客户到正在检查的特定抽认卡。SQLAlchemy 只能通过在两个表之间明确指定的链接器来确定如何正确分配每个关系中的外键。因此,我们必须指定是什么将两个表连接起来以阐明我们的关系。其次,由于我们明确指定了两个关系中的一个,我们必须明确声明我们的第二个客户和抽认卡(当前评论)之间的关系。客户现在正在检查的抽认卡存储在此列中。我们特意建立了这种关系,以使用当前评论 ID 作为两个表之间的主键,以便模型知道它是哪个评论。

程序 routes.py 文件

我们的模型已经完成。因此是时候开发我们的抽认卡机器人的逻辑了。我们将逐一介绍三个主要的逻辑组件。

代码片段: 让我们在文档顶部导入我们的函数。

因为我们的机器人有很多分支,所以在开始逻辑之前,让我们概括最重要的部分:发送背面注释消息。使用 _send_message() 函数,将一组行与换行符连接起来,然后作为 Twilio 消息发送回背面给消费者。

代码片段

Twilio 使用 POST 请求到 webhook 将传入消息中继到我们的 Flask 服务器,正如我们将在下面的测试部分中看到的那样(很像通过 Web 浏览器提交表单)。这意味着我们希望应用于新收到的消息的逻辑必须包含在单个公开路由中。

客户的存在是我们验证的第一个状态。为此,我们查看是否已使用消息的电话号码创建了配置文件。因为我们只查找电话号码,所以这个机器人可以支持 WhatsApp 和普通短信。为了测试目的,我插入了一个回退号码 123。这可以在测试期间应用。

代码片段

之后,如果客户仍然需要一个帐户,我们会要求他们这样做。此外,在我们创建客户帐户之前,我们必须确定客户是否向我们提供了随机命令。我们希望确保我们正在处理有效客户,因此如果客户尚未启动或尝试再次启动,此部分将在执行任何其他命令之前结束。

代码片段

一旦建立了客户帐户,我们需要设计用于创建卡的界面。我们通过要求客户发出启动命令来实现此目的,该命令会修改客户的状态以允许创建卡。抽认卡的注释格式将是 front_side/back_side。例如,Hello 或 bonjour。在评估期间,客户会看到 bonjour 并被要求写下背面 hello。最后,发出停止指令以在制作抽认卡后清除客户的状态。

代码片段

当客户想要复习他们的抽认卡时,一切就水到渠成了。这采用了类似的策略,即改变客户的状态以使其进入“复习”模式。在复习逻辑之后,我们最后包含一个包罗万象的捕获,以防客户发出我们无法解释的命令。

代码片段

合并代码:完整的 app/routes.py 文件

测试抽认卡机器人

既然我们已经为我们的抽认卡机器人构建了路由和模型,是时候启动服务器、创建数据库并发送消息了!

设置数据库

我们使用本教程前面获得的 Flask-Migrate 包中的命令首先初始化数据库。设置包括三个阶段:构建我们的数据库,确定需要哪些额外的表或列,以及将新创建的更改导入到我们的数据库中。

由于这是第一次设置数据库,因此将按顺序执行这三个过程。在执行下一条指令之前,请确保您位于 flashcard-bot 文件夹中并且您的虚拟环境已激活。

代码片段

运行这些命令后,您将看到一个新的 migrations 文件夹和一个额外的应用程序。数据库 SQLite。构建上述 models.py 文件中指定的数据库模式所需的脚本位于 migrations/versions 文件夹中。您可以根据自己的特定要求扩展和修改此抽认卡机器人时,使用 migrate 和 upgrade 命令调整数据库的结构。

作为测试发送消息

现在制作一些抽认卡!在 flashcard-bot 文件夹中运行 Flask run 以启动机器人。数据库设置应该仍然激活了您的虚拟环境。

输出应该类似于此

该服务现在作为您机器上的私有服务在端口 5000 上执行,并将在此处等待入站连接。我们必须使用 ngrok 使此服务可以通过 Internet 访问。

要分配一个临时公共域,该域将 HTTP 请求转发到我们的本地端口 5000,请打开第二个终端窗口并执行命令 `ngrok http 5000`。如果 ngrok 程序位于您当前目录中,您可能需要在 Unix 或 Mac OS 计算机上使用 `./ngrok http 5000`。

ngrok 的输出

Build a WhatsApp Flashcard App with Twilio, Flask, and Python

应注意以“Forwarding”开头的行。这显示了 ngrok 用于将请求路由到我们服务的公共可访问 URL。现在我们必须指示 Twilio 使用此地址发送传入消息通知。

返回 Twilio 控制台,选择可编程短信,WhatsApp,然后选择沙盒。当消息到达时,将从 ngrok 输出中复制的 https:// URL 插入此区域。由于我们的聊天机器人可通过 /bot URL 访问,因此请将其放在根 ngrok URL 的末尾。确保选择 HTTP Post 作为请求方法。请记住通过单击页面底部的红色保存按钮来保存这些更改。

Build a WhatsApp Flashcard App with Twilio, Flask, and Python

如果您希望通过传统短信与机器人通信,请转到 Twilio 控制台,选择电话号码,然后选择所需的电话号码。从 ngrok 输出中复制 https:// URL,然后当您向下滚动到“消息”部分时,将其粘贴到“收到消息时”区域。请记住,聊天机器人可通过 /bot URL 访问;因此必须将 /bot 添加到根 ngrok URL。确保事务方法设置为 HTTP POST,并记住保存您的修改。

Build a WhatsApp Flashcard App with Twilio, Flask, and Python

使用连接到沙盒的智能手机,您现在可以开始向抽认卡机器人发送消息。如果需要记住它能做什么,请向抽认卡机器人发送帮助。大家学习愉快!

请记住,免费使用 ngrok 有一些限制。特别是,您不允许保留 ngrok URL 超过 8 小时,并且每次运行 ngrok 命令时都会为您提供一个新的域名。每当您重新启动 ngrok 时,您都必须在 Twilio 控制台中更新 URL。

如果您想在实践中使用您的新抽认卡机器人,请查看 SMS 聊天机器人博客文章。

结论

我们一起创建了一个简单但功能强大的抽认卡机器人。它为您带来了一些新的灵感,并帮助您认识到像 Twilio 这样的提供商只需几行代码就能发挥多么强大的作用。