使用 Bottle Web 应用程序拨打外拨电话

使用 Bottle Web 框架构建的 Python Web 应用程序可以发送和接收 SMS 文本消息。在本教程中,我们将超越短信,学习如何拨出电话。这些呼叫将读取一段文本,然后播放一个 MP3 文件,但随后可以轻松修改它们以在您的 Python 网络应用程序中创建会议线路和许多其他语音功能。

我们需要的工具

您应该安装 Python 2 或 3 来创建您的 Bottle 应用程序,尽管对于新应用程序建议使用 Python 3。我们还需要:

  • pip 和 virtualenv 来处理应用程序依赖性
  • 当我们的 Bottle 应用程序在我们的本地开发环境中运行时,用于本地主机隧道的 Ngrok
  • Bottle web 框架
  • 免费的 Twilio 帐户可以使用他们的电话呼叫 Web API
  • Twilio 的 Python 帮助程序库,它在 GitHub 上是开源的,可以从 PyPI 下载

如果您在继续本教程的其余部分之前需要帮助配置您的开发环境,请查看有关在 Ubuntu 16.04 LTS 上设置 Python 3、Bottle 和 Gunicorn 的指南。

您可以在 outbound 目录下的 python-bottle-phoneGitHub 存储库中获取本教程的所有开源代码。根据需要使用和复制代码 – 所有代码均在 MIT 许可下开源。

安装我们的应用程序依赖项

我们的 Bottle 应用程序需要一个帮助程序代码库,以便轻松拨打外拨电话。 Bottle 和 Twilio 帮助程序库可以从 PyPI 安装到虚拟环境中。打开您的终端并使用 virtualenv 命令创建一个新的 virtualenv:

virtualenv bottlephone

在 virtualenv 中使用 activate 脚本,这使得这个 virtualenv 成为活动的 Python 安装。请注意,您需要在每个要使用此 virtualenv 的终端窗口中执行此操作。

source bottlephone/bin/activate

激活虚拟环境后,命令提示符将更改为类似(bottlephone) $ 的内容。这是我使用 activate 脚本时我的环境的屏幕截图。

接下来使用 pip 命令将 Bottle 和 Twilio Python 包安装到您的虚拟环境中。

pip install bottle twilio==5.7.0

安装脚本完成后,我们将拥有构建应用程序所需的依赖项。是时候编写一些 Python 代码来拨出电话了。

Bottle 和 Twilio

我们简单的 Bottle 网络应用程序将具有三个路由:

  • / – 返回一个文本字符串让我们知道我们的 Bottle 应用程序正在运行
  • /twiml – 响应TwiML(XML 的一个简单子集)指示 Twilio 当有人从我们的 Bottle 网络应用程序接听电话时该怎么做
  • /dial-phone/<outbound_phone_number>,其中“outbound_phone_number”是一个电话格式为“+12025551234”的号码 – 此路由使用 Twiliohelper 库向 Twilio Voice API 发送 POST 请求以拨打电话

我们现在可以构建 Bottle 应用程序的结构和第一个路由。使用以下内容创建一个名为 app.py 的新文件以启动我们的应用程序。

import os
import bottle
from bottle import route, run, post, Response
from twilio import twiml
from twilio.rest import TwilioRestClient


app = bottle.default_app()
# plug in account SID and auth token here if they are not already exposed as
# environment variables
twilio_client = TwilioRestClient()

TWILIO_NUMBER = os.environ.get('TWILIO_NUMBER', '+12025551234')
NGROK_BASE_URL = os.environ.get('NGROK_BASE_URL', 'https://c6c6d4e8.ngrok.io')


@route('/')
def index():
    """
    Returns a standard text response to show the app is up and running.
    """
    return Response("Bottle app running!")


if __name__ == '__main__':
    run(host='127.0.0.1', port=8000, debug=False, reloader=True)

确保您位于创建上述 app.py 文件的目录中。使用以下命令通过 Bottle 开发服务器运行应用程序。确保您的 virtualenv 仍然处于激活状态,以便我们的代码可以依赖 Bottle 代码库。

python app.py

我们应该看到一个成功的开发服务器像这样启动:

(bottlephone) matt@ubuntu:~/bottlephone$ python app.py 
Bottle v0.12.9 server starting up (using WSGIRefServer())...
Listening on http://127.0.0.1:8000/
Hit Ctrl-C to quit.

在我的 Ubuntu 环境中,开发服务器消息如下所示:

从命令行成功启动 Bottle 开发服务器。

让我们通过在网络浏览器中转到“localhost:8000”来测试应用程序。我们应该会收到一条简单的成功消息,表明该应用程序正在运行并响应请求。

Web 浏览器中显示 Bottle 应用程序正在运行的简单成功消息。

接下来我们需要获取一个电话号码,我们的 Bottle 应用可以使用它来拨打其他电话号码。

获取电话号码

我们的基本 Bottle Web 应用程序正在运行,但我们真正想做的是拨出电话 – 这将由 Twilio 处理。

在您的网络浏览器中转到 Twilio 网站并注册一个免费帐户。如果您已经拥有一个,也可以登录现有的 Twilio 帐户。

Twilio 注册屏幕。

Twilio 试用帐户允许您拨打和接听您自己经过验证的电话号码。要拨打和接听来自任何电话号码的电话,您需要升级您的帐户(点击顶部导航栏上的升级按钮即可)。试用帐户非常适合在您的应用程序上线之前进行初始开发,但升级帐户才是真正的力量所在。

登录到您的 Twilio 帐户后,转到管理电话号码屏幕。在此屏幕上,您可以购买一个或多个电话号码或单击帐户中的现有电话号码进行配置。

管理电话号码屏幕。

我们现在在电话号码配置页面上无需配置任何内容,因为我们正在为本教程拨打电话。现在我们有了电话号码,让我们将最后一段代码添加到我们的 Bottle 应用程序中,让这个应用程序正常运行。

打电话

我们需要向 Bottle 应用程序添加两条新路由,以便它可以拨出电话。使用下面的两个新函数 twiml_responseoutbound_call 修改现有的 app.py 文件。除了将这两个新函数添加到我们在上一节中编写的内容之外,此文件中的其他代码都不需要更改。

import os
import bottle
from bottle import route, run, post, Response
from twilio import twiml
from twilio.rest import TwilioRestClient


app = bottle.default_app()
# plug in account SID and auth token here if they are not already exposed as
# environment variables
twilio_client = TwilioRestClient()

# add your Twilio phone number here
TWILIO_NUMBER = os.environ.get('TWILIO_NUMBER', '+16093002984')
# plug in your Ngrok Forwarding URL - we'll set it up in a minute
NGROK_BASE_URL = os.environ.get('NGROK_BASE_URL', 'https://c6c6d4e8.ngrok.io')


@route('/')
def index():
    """
    Returns a standard text response to show the app is up and running.
    """
    return Response("Bottle app running!")


@post('/twiml')
def twiml_response():
    """
    Provides TwiML instructions in response to a Twilio POST webhook
    event so that Twilio knows how to handle the outbound phone call
    when someone picks up the phone.
    """
    response = twiml.Response()
    response.say("Sweet, this phone call is answered by your Bottle app!")
    response.play("https://api.twilio.com/cowbell.mp3", loop=10)
    return Response(str(response))


@route('/dial-phone/<outbound_phone_number>')
def outbound_call(outbound_phone_number):
    """
    Uses the Twilio Python helper library to send a POST request to
    Twilio telling it to dial an outbound phone call from our specific
    Twilio phone number (that phone number must be owned by our Twilio 
    account).
    """
    # the url must match the Ngrok Forwarding URL plus the route defined in
    # the previous function that responds with TwiML instructions
    twilio_client.calls.create(to=outbound_phone_number, 
                               from_=BLOG_POST_NUMBER,
                               url=NGROK_BASE_URL + '/twiml')
    return Response('phone call placed to ' + outbound_phone_number + '!')


if __name__ == '__main__':
    run(host='127.0.0.1', port=8000, debug=False, reloader=True)

如果您在本地环境中进行开发,我们当前的设置只有一个问题:Twilio 将无法访问该 /twiml 路由。我们需要将我们的应用程序部署到可访问的服务器,或者只使用像 Ngrok 这样的本地主机隧道工具。 Ngrok 提供了一个连接到您机器上运行的端口的外部 URL。下载并安装适用于您的操作系统的 Ngrok 应用程序。

我们在本地运行 Ngrok 并公开在端口 8000 上运行的 Bottle 应用程序。在 Ngrok 可执行文件所在的目录中运行此命令。

./ngrok http 8000

Ngrok 将启动并为我们提供一个转发 URL,包括 HTTP 和 HTTPS 版本。

Ngrok 已启动并运行以用作本地主机隧道。

我们可以使用转发 URL 来指示 Twilio 在有人接听电话时如何处理外拨电话。将 Ngrok 转发 URL 插入到 app.py 文件中,其中指定了 NGROK_BASE_URL

将 ngrok 转发 URL 粘贴到 Twilio webhook 配置文本框中。

如果 Ngrok 对您有用,请务必阅读这篇在测试 webhook 时使用 Ngrok 的 6 个绝妙理由帖子,以了解有关该工具的更多信息。

是时候测试我们的应用了,让我们快速试用一下。

打电话

确保您的 Bottle 开发服务器仍在运行,或者在您的 virtualenv 仍处于激活状态的 shell 中使用 python app.py 命令重新运行它。

在浏览器中打开应用程序,这次测试电话呼叫功能。转到“localhost:8000/dial-phone/my-phone-number”,其中“my-phone-number”是“+12025551234”格式的号码。例如,这是我拨打 +12023351278 时发生的情况:

使用 Bottle 拨出电话。

这是呼入电话!

在 iPhone 上接听来电。

当我们接听电话时,我们还看到 /twiml 路由通过 Ngrok 被调用。

https://www.fullstackpython.com/twiml 路由正在通过 Ngrok 调用。

只需在我们的 Bottle 应用程序和 Twilio 中使用两条路线,我们就能够拨打出站电话。不错!

下一步是什么?

太棒了,我们现在可以从我们的 Bottle 网络应用程序向任何电话号码拨打出站电话。接下来,您可能想尝试其中一个教程来为您的应用程序添加更多功能:

  • 升级您的 Bottle 应用以发送和回复短信
  • 创建一个电话呼叫 Slack 机器人
  • 对通过你的应用

有问题吗?通过 Twitter@fullstackpython 或@mattmakai 与我联系。我也在 GitHub asmattmakai 上。

看到这篇文章有什么问题了吗?在 GitHub 上创建此页面的源代码并提交拉取请求。

赞(0) 打赏

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏