使用Cloudflared Tunnel在本地开发Webhooks(附代码)

1,063 阅读9分钟

Webhooks是一种在事件发生时被外部服务通知的方式。不是你向该服务发送HTTP请求,而是该服务向你的公共网络服务发送HTTP请求。这样,你就可以在事件发生时对其进行实时响应。Webhooks也是与Twilio的产品整合的一种常见方式。例如,当你的Twilio电话号码收到一条短信或电话时,Twilio会向你的服务发送一个HTTP请求,并提供详细信息。然后,你的服务会响应指示,指出Twilio应该如何回应该事件。下面是这种交换的图示:

Diagram showing how SMS messages interact with Twilio and your application using webhooks

Webhooks的一个共同挑战是,它们只能调用互联网上公开的网络服务,但当你最初开发软件时,你通常是在自己的本地机器上进行,默认情况下是无法通过互联网到达的。那么,你如何在你的本地机器上开发和测试webhooks?答案是:隧道。在这篇文章中,你将学习如何使用 Cloudflare Tunnels 服务,使你的本地网络服务器在互联网上公开访问。然后,您将学习如何使用隧道服务来响应Twilio webhook,以回应一个电话。

本地隧道

你可以在你的本地机器和隧道服务之间创建一个隧道,将本地端口暴露在公共互联网上。有很多工具可以帮助你做到这一点,今天你要学习的是Cloudflare Tunnel或cloudflared(以前叫Argo Tunnel)。

前提条件

你将需要以下东西才能跟上:

  • 一台Linux、macOS或Windows机器
  • 你选择的开发堆栈(Node.js、PHP、.NET、Java、Python等)。
  • 可选的:一个使用Cloudflare DNS作为名称服务器的网站的Cloudflare账户
  • 可选的: 一个Twilio账户(如果你在这里注册,当你升级到付费账户时,你会收到10美元的Twilio积分!)。

设置一个本地网络服务器

你可以在任何时候对一个本地端口进行加密,但是如果你的机器上没有任何东西在监听这个端口,你就不会看到任何结果。在这一节中,你将设置一个本地Web服务器来提供静态文件。

通常,webhook的响应是以编程方式创建的,但为了这个演示的目的,你将使用静态文件。

打开你喜欢的外壳,创建一个文件夹,并导航到它:

mkdir MyStaticSite
cd MyStaticSite

MyStaticSite文件夹中创建一个新文件index.html,内容如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Hello World!</title>
</head>
<body>
    Hello World!
</body>
</html>

你需要运行一个静态Web服务器来服务这个HTML文件。每个开发栈都有许多静态服务器。在下面挑选你喜欢的堆栈,并按照说明为当前文件夹提供服务,网址是http://localhost:8080/。

Node.js:运行下面的命令来执行http-server NPM包并运行它:

npx http-server . --port 8080

PHP:你可以通过运行以下命令使用内置的PHP web服务器

php -S localhost:8080

**.NET:你可以通过运行以下命令来使用内置的PHP网络服务器。**你可以使用dotnet-serve工具来运行一个静态Web服务器。将该工具安装为一个全局的.NET工具:

dotnet tool install --global dotnet-serve

运行该工具为当前目录提供服务:

dotnet serve --port 8080

Python 2:

python -m SimpleHTTPServer 8080

Python 3:

python -m http.server 8080

如果你喜欢的编程语言没有列在上面,请查看这个静态Web服务器命令的列表

让静态服务器运行,为即将到来的命令打开一个新的外壳。

使用Cloudflare Tunnel对你的本地Web服务器进行加密

你可以使用 Cloudflare Tunnel 客户端,将你的本地端口接入公共互联网。

为此,你需要使用cloudflared CLI 工具。在此下载 cloudflared 命令行工具

开始对你的本地机器进行隧道连接的最快捷方式是运行这个命令:

cloudflared tunnel --url http://localhost:8080

这个命令将隧道*http://localhost:8080*到一个随机生成的*trycloudflare.com*子域。例如,当我运行这个命令时,公开可用的地址是*https://****colleagues-ga-eternal-recruitment****.trycloudflare.com*。

下面是输出结果应该是这样的:

Thank you for trying Cloudflare Tunnel. Doing so, without a Cloudflare account, is a quick way to experiment and try it out. However, be aware that these account-less Tunnels have no uptime guarantee. If you intend to use Tunnels in production you should use a pre-created named tunnel by following: https://developers.cloudflare.com/cloudflare-one/connections/connect-apps
Requesting new quick Tunnel on trycloudflare.com...
+--------------------------------------------------------------------------------------------+
|  Your quick Tunnel has been created! Visit it at (it may take some time to be reachable):  |
|  https://colleagues-ga-eternal-recruitment.trycloudflare.com                               |
+--------------------------------------------------------------------------------------------+
... Much more!

你可以在打印到控制台的方框内找到你随机生成的地址。使用网络浏览器进入该地址。你会看到,从你的本地网络服务器提供的 HTML 文件现在是在 Cloudflare 给你的地址上公开提供。

您可以使用这个公共地址,并将其配置为您的webhook地址,与您想集成的外部服务相连接。

为您的 Cloudflare 隧道使用一个持久的地址

当您停止隧道命令时,隧道将被销毁。当你再次运行隧道命令时,将创建一个具有新的随机URL的新隧道。这也意味着你必须在你的外部服务中持续更新webhook URL,这可能是一个麻烦。
其中一些隧道服务确实提供持久的URL,作为其付费计划的一部分。但通过Cloudflare Tunnels,如果你使用Cloudflare DNS,你可以免费拥有持久的URL。你可以在Cloudflare DNS中创建一个子域,并将其作为你的持久性隧道URL,而不是使用随机生成的URL。

如果你选择使用一个持久的URL,你需要:

  1. 创建一个Cloudflare帐户,并添加您的网站
  2. 验证你是否拥有你的域名
  3. 使用Cloudflare DNS作为您的域名服务器

如果您还没有为您的网站使用Cloudflare DNS,而且您也不想这样做,请随意跳过本节。你可以继续使用随机生成的地址进行下一节。

使用以下命令登录Cloudflare:

cloudflared tunnel login

这将打开Cloudflare的登录页面。登录后,选择你想用于隧道的域名:

A list of domain names you have in Cloudflare DNS. You are asked to click one to authorize to use the domain for tunneling.

当提示你是否要授权这个域名时,点击授权

切换回你的外壳,你应该在输出中看到 "你已成功登录"。

通过运行这个命令创建一个新的隧道:

cloudflared tunnel create myfirsttunnel

你创建了一个隧道,名称为myfirsttunnel 。你可以用下面的命令列出你所有的隧道:

cloudflared tunnel list

运行上面的命令,注意你的隧道的ID

现在,CLI工具已经创建了一个文件夹来存储其配置。在 Windows 上,它位于*%USERPROFILE%\.cloudflared*。在 Linux 和 macOS 上,你可以在~/.cloudflared 找到这个文件夹。在*.cloudflared* 文件夹中创建一个新文件myfirsttunnel.yaml并粘贴以下内容:

url: http://localhost:8080
tunnel: <Tunnel-UUID>
credentials-file: /root/.cloudflared/<Tunnel-UUID>.json

这个配置文件将配置本地隧道监听*http://localhost:8080。*
用你之前注意到的隧道ID 替换<Tunnel-UUID>

运行以下命令,指定你想用于公共隧道URL的子域:

cloudflared tunnel route dns myfirsttunnel mysubdomain

在这个命令中,myfirsttunnel 指定隧道的名称,mysubdomain 指定你想使用的子域。

现在一切都配置好了,你可以用这个命令运行你的隧道:

cloudflared tunnel run myfirsttunnel

你的新隧道URL应该是*:https://<你的子域>.<你的域名>.<你的tld>。例如,我的就是mysubdomain.swimburger.net。*

在浏览器中打开你的新隧道URL,以验证是否返回相同的HTML文件。

用Twilio webhooks使用你的隧道

你也可以使用这些隧道来响应Twilio webhooks。在这一节中,你将学习如何使用静态的XML文件来响应一个电话。

MyStaticSite文件夹中创建一个新文件call.xml

<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Say voice="alice">Twilio received these instructions from your local machine via Cloudflare Tunnel.</Say>
  <Pause length="1" />
  <Say voice="alice">Great job!</Say>
</Response>

这个XML文件使用TwiML,也被称为Twilio Markup Language。使用TwiML,你可以提供Twilio应该如何回应来电或短信的指示。上面的TwiML使用了两个TwiML语音动词:SayPauseSay 将文本转换为语音,而voice 属性指定了要使用的语音。Pause 将等待指定的时间,在这个例子中是一秒钟,然后转到下一个动词。

确保你的静态Web服务器仍在运行,并使用cloudflared ,运行Cloudflare隧道。
使用公开的隧道URL浏览到XML文件。[隧道-url]/call.xml

XML应该被返回到你的浏览器。 请注意这个URL。

如果你还没有Twilio账户,你可以获得一个免费的账户。(如果你在这里注册,当你升级到付费账户时,你会收到10美元的Twilio积分!)

接下来,你需要一个Twilio电话号码。去Twilio购买一个新的电话号码。电话号码的费用将被应用于你的免费促销信用。

使用左边的导航,导航到电话号码 > 管理 > 活动号码。点击你的Twilio电话号码,导航到其设置。

Twilio Console page listing active phone numbers in your Twilio account. Cursor is clicking on the single phone number in the list.

语音和传真部分找到A CALL COMES IN字段。将文本字段改为你的公共隧道URL,路径为*/call.xml*,并将HTTP动词改为HTTP GETTwilio phone number settings screen. The fields on the form configure the phone number webhook to send HTTP GET requests to https://mydomain.swimburger.net/call.xml

点击保存,提交表格。

为了验证呼叫是否按预期进行,用你的个人电话拨打你的Twilio电话号码。您应该听到 "Twilio通过Cloudflare Tunnel从您的本地机器收到这些指令。干得好!"。

使用一个静态文件足以证明本地隧道,但你也可以结合任何网络服务器技术使用相同的技术来处理和响应HTTP请求。

使用Cloudflared隧道在本地开发Webhooks

Webhooks是一种很好的方式,当一个事件发生时,可由外部服务通知。外部服务向你的公共网络服务发出HTTP请求,并在请求的主体中提供事件的细节。你可以使用本地隧道,通过Cloudflare Tunnels这样的隧道服务,使你的本地端口在互联网上可以访问。使用Cloudflare Tunnels,你可以将你的本地端口隧道到Cloudflare提供的一个随机公共URL。如果你使用Cloudflare DNS,你也可以免费配置一个持久的隧道URL。