news 2026/10/3 8:14:56

在 Google App Engine 灵活环境中集成 Twilio:Python 语音应答与 SMS 收发实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
在 Google App Engine 灵活环境中集成 Twilio:Python 语音应答与 SMS 收发实战指南
  • 示例工程

【免费下载链接】python-docs-samples

Code samples used on cloud.google.com

项目地址:https://gitcode.com/GitHub_Trending/py/python-docs-samples
点击查看免费下载

本文围绕开源仓库 python-docs-samples 中的 appengine/flexible/twilio 示例,系统讲解如何在 Google App Engine Flexible Environment(灵活环境)上用 Python 集成 Twilio,实现来电语音应答、主动发送短信与自动回复短信三条完整链路。读者学完后将掌握 Twilio 账号与号码配置、app.yaml环境变量注入、本地调试及gcloud部署的完整流程,并理解底层 Flask 路由与 TwiML 的交互原理。

示例概览:一个 Flask 应用如何同时处理语音与短信

该示例是一个典型的 App Engine Flexible Environment Web 应用,核心是一个基于 Flask 的 HTTP 服务(main.py),对外暴露三个路由,分别对应 Twilio 平台的三种交互场景:

路由方法功能Twilio 侧对应配置
/call/receivePOST应答来电并播放语音问候语号码的 Voice Request URL
/sms/sendGET主动向指定号码发送短信由应用自行触发,无需 Twilio 配置
/sms/receivePOST接收短信并自动回复一条问候号码的 SMS Request URL

整体工作流为:Twilio 平台在收到来电或短信时,向你在 Twilio 控制台中配置好的 URL 发起 HTTP 回调;应用收到请求后返回一段 TwiML(Twilio Markup Language)XML,告诉 Twilio 接下来该播放什么语音或回复什么短信。/sms/send则走反向流程,由应用主动调用 Twilio REST API 发起外发短信。

前置准备:Twilio 账号与号码配置

在运行或部署示例之前,需要完成三步准备工作(对应 README 的 Setup 章节):

  1. 创建 Twilio 账号。通过 Twilio 面向 Google Cloud 用户的注册入口创建账号,Google App Engine 用户可获得短信与入站消息的赠送额度,可用于降低初期测试成本。

  2. 购买并配置一个 Twilio 号码。在 Twilio 控制台创建号码后,需要为该号码设置两个回调 URL:

    • Voice Request URL 配置为https://your-app-id.appspot.com/call/receive
    • SMS Request URL 配置为https://your-app-id.appspot.com/sms/receive

    其中your-app-id是部署后 App Engine 应用的 ID(即项目的 appspot.com 域名前缀)。这两个 URL 必须与应用实际部署后的地址一致,否则 Twilio 无法正确回调。

  3. 将 Twilio 凭据写入应用配置。也就是下一步要讲的环境变量注入。

配置环境变量:app.yaml中注入 Twilio 凭据

示例的部署配置文件是 app.yaml。该文件同时定义了运行时环境与应用所需的三个环境变量:

runtime: python env: flex entrypoint: gunicorn -b :$PORT main:app runtime_config: python_version: 3 env_variables: TWILIO_ACCOUNT_SID: your-account-sid TWILIO_AUTH_TOKEN: your-auth-token TWILIO_NUMBER: your-twilio-number

三个环境变量的含义与取值来源如下:

  • TWILIO_ACCOUNT_SID:Twilio 账户标识,在 Twilio 控制台 Dashboard 可见,用于标识调用者身份;
  • TWILIO_AUTH_TOKEN:Twilio 账户认证令牌,与 Account SID 配对使用,用于 REST API 调用鉴权,属于敏感凭据;
  • TWILIO_NUMBER:你购买的 Twilio 号码(E.164 格式,如+1xxxxxxxxxx),作为发送短信时的from_号码。

配置中的占位符your-account-sid、your-auth-token、your-twilio-number需要在部署前替换为真实值。入口命令gunicorn -b :$PORT main:app说明应用在 App Engine 上由 Gunicorn WSGI 服务器托管,监听环境变量$PORT指定的端口。值得留意的是,该示例的app.yaml未显式设置manual_scaling与resources字段;对比仓库中 appengine/flexible/hello_world/app.yaml 可以看到,灵活的 App Engine 支持通过manual_scaling、cpu、memory_gb、disk_size_gb等字段控制实例数量与资源规格,在生产或成本敏感场景可按需补充。

在 main.py 中,这三个变量在模块加载时通过os.environ直接读取:

TWILIO_ACCOUNT_SID = os.environ["TWILIO_ACCOUNT_SID"] TWILIO_AUTH_TOKEN = os.environ["TWILIO_AUTH_TOKEN"] TWILIO_NUMBER = os.environ["TWILIO_NUMBER"]

这意味着应用启动时环境变量必须已就绪,否则会抛出KeyError导致启动失败。这一设计也提醒开发者:凭据应始终通过环境变量(或 Secret Manager 等更安全的机制)注入,绝不能硬编码进源码。

本地运行:导出环境变量并启动 Flask

该示例支持完全在本地运行和调试,无需真实来电或短信即可验证回调逻辑。步骤为(对应 README 的 Running locally 章节):

  1. 参照 顶层 README 完成环境准备:安装 Google Cloud SDK 与 gcloud 工具、执行gcloud init完成鉴权、克隆仓库,并按 Google Cloud Python 开发环境指引安装依赖。

  2. 安装示例依赖:

    pip install -r requirements.txt
  3. 导出三个环境变量后启动应用:

    export TWILIO_ACCOUNT_SID=[your-twilio-account-sid] export TWILIO_AUTH_TOKEN=[your-twilio-auth-token] export TWILIO_NUMBER=[your-twilio-number] python main.py

应用启动后会监听127.0.0.1:8080(见 main.py 的本地运行入口),并开启 debug 模式。此时可以用 curl 等工具模拟 Twilio 的回调来验证逻辑,例如:

curl -X POST http://localhost:8080/call/receive curl -X POST http://localhost:8080/sms/receive -d "From=5558675309&Body=Hello" curl "http://localhost:8080/sms/send?to=5558675309"

源码解析:三个端点的实现与 TwiML 交互

理解 main.py 的实现,是掌握整个示例原理的关键。三个端点分别对应 README 中配置的 Twilio 回调与主动发送逻辑。

应答来电:/call/receive

@app.route("/call/receive", methods=["POST"]) def receive_call(): """Answers a call and replies with a simple greeting.""" response = voice_response.VoiceResponse() response.say("Hello from Twilio!") return str(response), 200, {"Content-Type": "application/xml"}

该端点由 Twilio 在号码收到来电时以 POST 方式调用。代码使用twilio.twiml.voice_response.VoiceResponse构造 TwiML,并通过say()指示 Twilio 用 TTS 播放问候语 "Hello from Twilio!"。响应以application/xml内容类型返回,Twilio 解析后即执行语音播放。

主动发送短信:/sms/send

@app.route("/sms/send") def send_sms(): """Sends a simple SMS message.""" to = request.args.get("to") if not to: return ( 'Please provide the number to message in the "to" query string' " parameter." ), 400 client = rest.Client(TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN) rv = client.messages.create(to=to, from_=TWILIO_NUMBER, body="Hello from Twilio!") return str(rv)

这是唯一一个由应用主动发起(GET 请求)的端点:从查询参数to读取目标号码,缺少时返回 400 提示;随后用TWILIO_ACCOUNT_SID与TWILIO_AUTH_TOKEN创建 REST 客户端,调用client.messages.create()发送内容为 "Hello from Twilio!" 的短信,from_指定为TWILIO_NUMBER,最后将消息对象的字符串表示返回给调用方。

接收短信并回复:/sms/receive

@app.route("/sms/receive", methods=["POST"]) def receive_sms(): """Receives an SMS message and replies with a simple greeting.""" sender = request.values.get("From") body = request.values.get("Body") message = f"Hello, {sender}, you said: {body}" response = messaging_response.MessagingResponse() response.message(message) return str(response), 200, {"Content-Type": "application/xml"}

该端点由 Twilio 在号码收到短信时以 POST 方式回调。From与Body是 Twilio 回调时携带的表单字段,分别表示发送方号码与短信正文。应用构造包含对方号码和原文的回显消息,包装进messaging_response.MessagingResponse,以 XML 返回给 Twilio,由 Twilio 完成自动回复。

错误处理

main.py 还注册了500错误处理器,任何未捕获异常都会记录到日志并返回包含堆栈信息的错误页,便于在生产环境排查。

部署到 App Engine 灵活环境

本地验证通过后即可部署上线,流程与仓库中 App Engine 灵活环境样本的通用部署流程一致(详见 顶层 README):

  1. 在 Google Cloud Console 创建项目(App ID 与 Project ID 相同);

  2. 执行gcloud init完成工具初始化与项目选择;

  3. 在示例目录执行部署命令:

    gcloud app deploy
  4. 部署成功后应用即运行于your-app-id.appspot.com,随后回到 Twilio 控制台,将号码的 Voice Request URL 与 SMS Request URL 分别指向https://your-app-id.appspot.com/call/receive与https://your-app-id.appspot.com/sms/receive,即可接通真实来电与短信链路。

测试验证:用 pytest 与 responses 模拟回调

仓库为该示例提供了完整的单元测试 main_test.py,用monkeypatch注入假凭据、用responses库拦截 REST API 调用,从而在不触碰真实 Twilio 服务的前提下验证全部逻辑:

  • test_receive_call:POST/call/receive,断言响应 XML 中包含 "Hello from Twilio!" 语音文本;
  • test_send_sms:先验证不带to参数时返回 400;再通过responses.add()模拟 Twiliomessages.create的 API 响应,验证带to=5558675309时返回 200;
  • test_receive_sms:以表单数据模拟 Twilio 的回调(From与Body),断言返回的回复短信中包含原始正文。

测试依赖定义在 requirements-test.txt(pytest 与 responses),运行测试前需先安装:

pip install -r requirements-test.txt pytest

依赖与版本约束

requirements.txt 列出了本示例的运行时依赖:

Flask==3.1.3; python_version >= '3.9' Werkzeug==3.1.8; python_version >= '3.9' gunicorn==23.0.0 twilio==9.0.3
  • Flask / Werkzeug:Web 框架及其底层 WSGI 工具集,限定 Python 3.9 及以上版本;
  • gunicorn:生产级 WSGI 服务器,对应app.yaml中的entrypoint;
  • twilio:Twilio 官方 Python SDK,提供 REST 客户端与 TwiML 构造器(twilio.rest、twilio.twiml.voice_response、twilio.twiml.messaging_response)。

值得注意的是,noxfile_config.py 中该示例仅在 Python 3.10 上执行 CI 测试(其余版本被忽略),且未强制类型注解——这是该仓库对存量示例的统一测试策略,不影响本地任意受支持 Python 版本的运行。

小结

通过本示例可以看到,在 App Engine 灵活环境集成 Twilio 的核心在于三点:一是用app.yaml的env_variables安全注入账号凭据;二是用 Flask 路由 + TwiML 响应正确应答 Twilio 的语音/短信回调;三是利用 Twilio SDK 主动发起外发短信。结合仓库中的 main.py 与 main_test.py,读者可以快速将其扩展为更复杂的语音菜单、短信机器人或通知服务。示例的贡献与授权说明可分别参考仓库根目录的 CONTRIBUTING.md 与 LICENSE。

  • 示例工程

【免费下载链接】python-docs-samples

Code samples used on cloud.google.com

项目地址:https://gitcode.com/GitHub_Trending/py/python-docs-samples
点击查看免费下载
上一篇:终极指南:如何在macOS上快速搭建C++开发环境
下一篇:【亲测免费】 Vue-XiuXianGame 项目安装与使用教程

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/3 8:13:06

如何安全制作系统启动盘:Balena Etcher 镜像烧录全流程

如何安全制作系统启动盘:Balena Etcher 镜像烧录全流程 【免费下载链接】etcher Flash OS images to SD cards & USB drives, safely and easily. 项目地址: https://gitcode.com/GitHub_Trending/et/etcher 把系统镜像写进 SD 卡或 U 盘时,最…

作者头像 李华
网站建设 2026/10/3 8:08:40

力科Summit T3-8 PCIe协议分析仪实战:从LTSSM到TLP的调试指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华