如何使用Serverless和Twilio来实现通信渠道的自动化

163 阅读6分钟

在过去的几年里,人们的沟通方式已经发生了变化。你最后一次因为遇到问题而拨打服务电话是什么时候?对我来说,这已经是几年前的事了,我最常使用的是聊天界面,当它们可用时。

这些新的界面通常在某种程度上是自动化的--很难说是人还是机器在回答你的问题。开发人员有能力建立超越我们所习惯的界面。Alexa、Whatsapp、电子邮件、短信--你可以将所有这些渠道自动化。

Twilio是一个通信API,使你能够根据你的需要定制体验。想做一个短信投票?没问题!需要在你的登陆页面上定制一个聊天机器人?当然可以!想把你所有的朋友都带入一个团体电话吗?易如反掌!

Webhooks--未来界面的基础

作为一个开发者,你可能不会建立基础设施来发送短信或打电话。你会使用SDK和API来做这件事。它的工作方式是,你可以使用Twilio的RESTful API来启动向外通信。电话、短信、WhatsApp信息都只需要一个HTTP调用。

另一种方式就有点棘手了。当你不控制接收这些事件的基础设施时,你如何对传入的信息或电话做出反应?Webhooks为此打下了基础。

如果有人发送消息、打电话或使用任何其他渠道,Webhook就会被发送到你定义的一个URL上。Webhook的响应控制了接下来会发生什么。

SMS, Twilio, App

在上面的例子中,你看到的是一个传入短信的流程。一个用户发送了一条短信,Twilio处理这个事件,并向你的应用程序发出HTTP请求,以了解下一步该做什么。

但你想建立一个完整的应用来响应HTTP请求吗?还是说一个无服务器函数可以完成这项工作?

无服务器框架现在支持部署Twilio函数

无服务器函数是响应HTTP调用的完美选择。Twilio Runtime今天为你提供了编写无服务器函数的方法。我们很高兴地宣布,你现在可以使用无服务器框架部署Twilio函数了。

SMS, Twilio, Serverless

如果你已经习惯于使用无服务器框架,就没有必要再去学习新的API。你可以继续使用无服务器框架来控制你的Twilio通信!

在两分钟内部署Twilio无服务器功能

从Serverless CLIv1.50.0 开始,你只需一个命令就能启动一个Twilio Runtime项目。在这篇文章中,你将学习如何做到这一点。

确保你在全球范围内安装了Serverless CLI,并使用Twilio Node.js模板运行serverless create

serverless create -t twilio-nodejs -p my-twilio-project

导航到新目录my-twilio-project ,并运行npm install 。在部署新的无服务器服务之前,你需要进行认证。前往Twilio控制台,复制你的账户凭证(账户SID和Auth token)。

将这两个认证值定义为环境变量,并使用serverless deploy 来部署新项目。

cd my-twilio-project
npm install
TWILIO_ACCOUNT_SID=AC... TWILIO_AUTH_TOKEN=a4... serverless deploy

命令输出应该如下:

Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: twilio-runtime: Creating Service
Serverless: twilio-runtime: Configuring "dev" environment
Serverless: twilio-runtime: Creating 1 Functions
Serverless: twilio-runtime: Uploading 1 Functions
Serverless: twilio-runtime: Creating 1 Assets
Serverless: twilio-runtime: Uploading 1 Assets
Serverless: twilio-runtime: Waiting for deployment.
Serverless: twilio-runtime: Waiting for deployment. Current status: building
Serverless: twilio-runtime: Waiting for deployment. Current status: building
Serverless: twilio-runtime: Waiting for deployment. Current status: building
Serverless: twilio-runtime: Waiting for deployment. Current status: building
Serverless: twilio-runtime: Setting environment variables
Serverless: twilio-runtime: Activating deployment
Serverless: twilio-runtime: Function available at: my-twilio-project-7724-dev.twil.io/hello/world
Serverless: twilio-runtime: Asset available at: my-twilio-project-7724-dev.twil.io/assets/foo/example.jpg

祝贺你!你刚刚部署了你的第一个Twilio Runtime服务,该服务能够使用Serverless CLI提供功能和资产。部署日志中显示的URL现在是公开可用的。

Twilio runtime page

这是怎么做到的?你又如何根据自己的需要调整Twilio函数呢?让我们一起来了解一下!

无服务器Twilio项目的文件结构

create 命令创建了你需要的所有文件--准备部署。它包括以下内容。

.rw-r--r--   .gitignore
.rw-r--r--   example.jpg
.rw-r--r--   handler.js
drwxr-xr-x   node_modules
.rw-r--r--   package-lock.json
.rw-r--r--   package.json
.rw-r--r--   serverless.yml

你看到熟悉的serverless.yml 配置文件,一个package.jsonpackage-lock.json ,以及一个函数 (handler.js) 和资产文件 (example.jpg)。

该项目在package.json 中只定义了一个npm依赖项。@twilio-labs/serverless-twilio-runtime。你已经安装了这个依赖,如果你现在看一下serverless.yml ,你会发现它把@twilio-labs/serverless-twilio-runtime 定义为一个插件。

# serverless.yml
plugins:
  - '@twilio-labs/serverless-twilio-runtime'

这个插件定义使得部署到Twilio Runtime成为可能。

不过,serverless.yml 拥有比插件定义更多的配置。它还配置了运行时,并提供了一种快速定义和部署无服务器功能和资产的方法。

一般配置

无服务器服务的主要配置发生在provider 属性中。在这种情况下,Twilio是提供者。

你有以下配置选项:

  • 认证(必填)
  • 依赖性
  • 部署环境的名称
  • 在你的函数中可以访问的环境变量

让我们逐一来看看这些选项。

用Twilio认证你的无服务器服务

要向Twilio Runtime部署函数,你必须定义你的accountSidauthToken 。你可以在你的serverless.yml 中硬编码这些值,但建议通过环境变量(${env:TWILIO_ACCOUNT_SID}${env:TWILIO_AUTH_TOKEN} )传递这些值。这样,你就不会冒险把你的合理凭证推送给 GitHub。

# serverless.yml
provider:
  name: twilio
  # Auth credentials which you'll find at twilio.com/console
  config:
    accountSid: ${env:TWILIO_ACCOUNT_SID}
    authToken: ${env:TWILIO_AUTH_TOKEN}

上述配置是TWILIO_ACCOUNT_SID=AC… TWILIO_AUTH_TOKEN=a8… serverless deploy 命令发挥作用的原因。serverless 命令拾取环境变量,并将其传递给Twilio Runtime插件。

定义所需的npm依赖项

如果你有使用无服务器框架的经验,你可能已经习惯了将依赖关系打包成一个捆绑包的过程。Twilio Runtime处理依赖关系的方式不同。

deploy 命令不需要将你所有的本地依赖项打包成一个单一的包来上传。Twilio Runtime允许你定义你的依赖关系,你只需要上传你的函数和资产文件。其余的就可以了!

看了一下serverless.yml ,你会发现bootstrap项目有一个依赖关系--asciiart-logo 。依赖关系的定义与package.json 依赖关系的定义相似。

# serverless.yml
provider:
  # Twilio runtime as your preferred provider
  name: twilio

  # Dependency definitions similar
  # to dependencies in a package.json
  # -> these dependencies will be available in the
  #    Twilio Node.js runtime
  dependencies:
    asciiart-logo: '*'

现在你可以在你的函数文件中包含const logo = require('asciiart-logo'); ,这个依赖关系就可以使用了。

定义你的环境

如果你严重依赖无服务器函数,你会发现自己很快就会面临复杂性的增加。为了应对这种复杂性,你可以安全地部署QA和暂存环境,在函数投入生产前对其进行测试。

environment 属性让你可以将不同的环境部署到Twilio Runtime。

provider:
  # Twilio runtime as your preferred provider
  name: twilio

  # Twilio runtime supports several domains
  # your functions and assets will be available under
  # -> defaulting to 'dev'
  environment: ${env:TWILIO_RUNTIME_ENV, 'dev'}

environment 属性也默认为dev ,你可以通过环境变量TWILIO_RUNTIME_ENV 来改变它。

一个部署的Twilio函数URL由服务名称、随机哈希值和定义的环境组成。端点URLmy-twilio-project-7724-dev.twil.io/hello/world 告诉你,你正在看一个包含在my-twilio-project 服务中的dev 环境的函数。

定义可访问的环境变量

当部署函数到Twilio Runtime时,你可能还需要一种方法来定义变量,这些变量将在函数上下文中可用。这些环境变量可以方便地存储其他服务的认证令牌,定义使用的端点或任何动态值。

environmentVars 属性让你定义这些值。当你的函数被执行时,它们将在context 属性中可用。

# serverless.yml
provider:
  # Twilio runtime as your preferred provider
  name: twilio

  # Environment variables passed to your functions
  # available via process.env
  environmentVars:
    MY_MESSAGE: 'This is cool stuff'

上述provider 属性是你需要的所有配置,以使你的函数部署符合你的用例!但函数定义在哪里?但是,函数的定义在哪里,怎么会有一个资产部署?

定义你的函数

你可以通过编辑你的serverless.yml 中的functions 属性来定义和配置函数。当你看到它时,已经有一个函数被定义了。

每个函数定义都必须导出一个handler ,如下所示。

exports.handler = function(context, event, callback) { /* … */ };

function 属性告诉Serverless使用handlers.js ,使其在/hello/world ,并使其可公开访问。

# serverless.yml
functions:
  hello-world:
    # Path to the JS handler function in the project (without file extension '.js')
    handler: handler
    # URL path of the function after deployment
    path: /hello/world
    # visibility of the function (can be "public" or "protected")
    access: public
定义你的资产

Twilio Runtime允许你通过assets 属性上传资产。然后你可以在你部署的函数中访问这些资产。如果你想播放一个音频文件,或者想用一个特定的图片来回应一个消息,那么资产和函数的组合就会变得很方便。

resources:
  assets:
    # Asset name
    example-image:
      # path to the asset in the project
      filePath: example.jpg
      # URL path to the asset after deployment
      path: /assets/foo/example.jpg
      # visibility of the asset
      access: public

有了这些功能和资产的定义,你就可以在几分钟内部署一个新的服务。🎉

其他包含的Serverless命令

无服务器Twilio集成支持另外两个命令 -invokeinfo

Invoke

invoke 是一个命令,你可以用它来调用已部署的函数,看看响应是否与你期望的一样。

TWILIO_ACCOUNT_SID=AC... TWILIO_AUTH_TOKEN=a4... serverless invoke -f hello-world

  ,--------------------------------------------------------------------------.
  |                                                                          |
  |    _____          _ _ _         ____              _   _                  |
  |   |_   _|_      _(_) (_) ___   |  _ \ _   _ _ __ | |_(_)_ __ ___   ___   |
  |     | | \ \ /\ / / | | |/ _ \  | |_) | | | | '_ \| __| | '_ ` _ \ / _ \  |
  |     | |  \ V  V /| | | | (_) | |  _ <| |_| | | | | |_| | | | | | |  __/  |
  |     |_|   \_/\_/ |_|_|_|\___/  |_| \_\\__,_|_| |_|\__|_|_| |_| |_|\___|  |
  |                                                                          |
  |                                                                          |
  |                                                           version 1.0.0  |
  |                                                                          |
  |                                                                          |
  `--------------------------------------------------------------------------'
信息

info 命令为你提供关于你部署的服务的信息。

TWILIO_ACCOUNT_SID=AC... TWILIO_AUTH_TOKEN=a4... serverless info

Service information
*******

Service: tutorial-try-out
Service Sid: ZSd5030028ddd5b0714f3981865c80b90d

Environment: dev
Environment unique name: dev-environment
Environment Sid: ZEf282491f28a513bb310f4f1c167a55d3
Environment domain name: tutorial-try-out-7724-dev.twil.io
Environment variables:
  MY_MESSAGE: THIS IS cool stuff

Assets:
  access: public
  creation date: 2019-09-03T09:51:08Z
  path: /assets/foo/example.jpg
  sid: ZN60c9751befba796c9190cd789f400568
  url: https://tutorial-try-out-7724-dev.twil.io/assets/foo/example.jpg

Functions:
  access: public
  creation date: 2019-09-03T09:51:07Z
  path: /hello/world
  sid: ZN06e8bd0c672045dbc1134de22ebe7fda
  url: https://tutorial-try-out-7724-dev.twil.io/hello/world

使用info 命令,你可以快速获得有关部署的功能、资产和服务配置的信息。

Twilio无服务器功能--为你的通信流量身打造的环境

第一次部署后,新的函数端点只返回一个带有ASCII艺术的字符串。如何才能改变它,以正确的方式响应传入短信的webhooks?

Twilio函数为你提供了一个全局Twilio 变量,其中包括一个twiml 对象来建立正确的响应。TwiML是Twilio的配置语言,用于控制通信流。进入handler.js 文件,放下ASCII艺术,并改变它,用一些TwiML来响应传入的HTTP呼叫。

如果你把函数URL定义为一个电话号码的webhook,送入的信息将得到 "Hello!"和定义的环境变量的组合作为响应。

// handler.js
exports.handler = function(context, event, callback) {
  let twiml = new Twilio.twiml.MessagingResponse();
  twiml.message(`Hello! ${context.MY_MESSAGE}`);

  callback(null, twiml);
};

重新运行deploy ,你就可以用Twilio处理传入的信息了。

TWILIO_ACCOUNT_SID=AC... TWILIO_AUTH_TOKEN=a4... serverless deploy

Twilio函数是为响应Twilio webhooks和快速粘合服务而建立的

Twilio XML

额外的资源

我们对Serverless的整合感到非常兴奋。它仍然很新,我们正在努力将更多的文档放到serverless.com上,并在CLI中加入更多的命令。你缺少什么功能?我们很希望能得到一些反馈!