如何使用AWS Chalice的无服务器Python应用程序发送WhatsApp消息

308 阅读7分钟

使用AWS Chalice的无服务器Python应用程序发送WhatsApp消息

[无服务器计算]使开发人员能够在不处理服务器的情况下构建软件和应用程序。它将服务器管理从开发者的职责中抽象出来。[AWS Chalice]是一个由AWS构建的轻量级、快速的无服务器框架。它是一个基于Python的框架。它利用了[亚马逊API网关]和[AWS Lambda]。

[WhatsApp]是一个免费的消息平台,全世界有超过20亿人在使用。[WhatsApp API]允许开发者为WhatsApp用户建立应用程序。

在这篇文章中,我们用DynamoDB数据库设置了一个Chalice应用程序。我们还将整合[Twilio WhatsApp消息],并从我们的应用程序发送消息。

前提条件

要跟上这篇文章,你应该有。

  • [Python]3.6或更高版本
  • venv或virtualenv
  • AWS账户
  • Twilio账户
  • 配置好的AWS凭证
  • 基本的Python经验

Venv通常与Python 3一起发货。但是你可以用下面的命令安装virtualenv。

pip install virtualenv

此外,如果你还没有AWS账户,请[注册]一个免费账户。

设置依赖性

为WhatsApp配置Twilio沙盒。

WhatsApp会在应用程序可以在生产中发送消息之前批准你的账户。但是,Twilio提供了WhatsApp沙盒来构建和测试应用程序。沙盒可以在[Twilio控制台的WhatsApp部分]找到。

进入沙盒[激活页面]。Twilio将提供一个两个字的加入代码和一个WhatsApp号码。使用智能手机上的WhatsApp,将加入代码发送到仪表板上的Twilio号码。这样,你将激活Twilio WhatsApp沙盒。

你应该在你的智能手机上的WhatsApp中收到这样的信息。

WhatsApp sandbox activation

你也会在你的仪表板上看到一个Message Received ,像这样的回应。

Message received notification on the dashboard

让我们在一个新的文件夹中为你的项目创建一个虚拟环境。

mkdir chalice-twilio-project
python -m venv env

然后,激活新的虚拟环境。

source env/bin/activate

让我们安装Chalice包、AWS CLI客户端、Boto3-AWS Python SDK和Twilio SDK。

pip install chalice awscli boto3 twilio

现在,我们可以使用new-project 关键字和chalice 命令来创建一个新的项目,名为welcome-app

chalice new-project welcome-app

Chalice将为我们生成以下文件。

welcome-app
├── app.py
├── .chalice
│   └── config.json
├── .gitignore
└── requirements.txt

上面生成的文件是。

  • app.py:持有应用程序的逻辑。
  • .chalice: 包含设置和数据库配置。
  • .gitignore: 包含Git将忽略的文件列表。
  • requirements.txt:包含了应用程序的依赖性。

现在,我们可以开始为应用程序进行数据库设置了。

设置数据库

数据库配置

我们将通过修改.chalice 文件夹中的config.json 文件来开始配置。我们将创建一个名为dev 的部署阶段。默认情况下,Chalice称其为dev, ,但你可以根据自己的意愿将其改为任何名称。

{
  "version": "2.0",
  "app_name": "welcome-app",
  "stages": {
    "dev": {
      "api_gateway_stage": "api",
      "autogen_policy": false
    }
  }
}

在上面的代码中,api_gateway_stage 是我们应用程序的URL前缀。autogen_policy 告诉Chalice为我们创建一个带有应用程序代码的IAM策略。

我们将为我们的应用程序使用DynamoDB数据库。这是一个NoSQL数据库系统,与AWS Chalice应用程序相配合,而且非常容易设置。

现在,我们将设置从数据库写入和读取的策略。让我们到.chalice 文件夹中,在那里创建一个policy-dev.json 文件。在policy-dev.json 文件内添加以下代码。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents"
      ],
      "Resource": "arn:aws:logs:*:*:*",
      "Effect": "Allow"
    },
    {
      "Action": [
        "dynamodb:PutItem",
        "dynamodb:DeleteItem",
        "dynamodb:UpdateItem",
        "dynamodb:GetItem",
        "dynamodb:Scan",
        "dynamodb:Query"
      ],
      "Resource": ["arn:aws:dynamodb:*:*:table/demo-table"],
      "Effect": "Allow"
    }
  ]
}

在上面的JSON文件中,我们允许我们的用户做日志组和日志事件。我们还定义了DynamoDB数据库中的读取、添加、更新、扫描、删除和查询操作的动作。此外,我们指定了数据库中的表的名称为demo-table

数据库的部署

AWS为我们提供了CloudFormation。它是一个工具,用于定义在AWS基础设施上托管的项目所需的资源。我们将在一个JSON/YAML模板中定义资源。因此,CloudFormation将利用该模板来建立一个带有依赖关系和资源的堆栈。

首先,我们将用我们的数据库处方创建一个模板。然后,CloudFormation可以用模板设置一个DynamoDB数据库。

因此,让我们在.chalice 文件夹中创建一个文件,名为dynamodb_cf_template.yaml 。在新文件中添加以下几行。

AWSTemplateFormatVersion: "2010-09-09"
Resources:
  chaliceTwilioDemo:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: demo-table
      AttributeDefinitions:
        - AttributeName: "id"
          AttributeType: "S"
        - AttributeName: "name"
          AttributeType: "S"
      KeySchema:
        - AttributeName: "id"
          KeyType: "HASH"
        - AttributeName: "name"
          KeyType: "RANGE"

      ProvisionedThroughput:
        ReadCapacityUnits: "5"
        WriteCapacityUnits: "5"

Outputs:
  TableName:
    Value: !Ref "chaliceDemo"
    Description: Name of the newly created DynamoDB table

在上述文件中,我们指出了我们的DynamoDB表的关键属性,即信息接收者的idnameKeySchema 由主键组成。

接下来,让我们导航到.chalice 文件夹,用下面的命令创建数据库。

aws cloudformation deploy --template-file dynamodb_cf_template.yaml --stack-name "my-stack"

我们已经使用前面定义的CloudFormation模板创建了我们的堆栈,名为my-stack

让我们检查一下设置。导航回到应用程序文件夹welcome-app ,使用chalice local 命令。

chalice local

我们应该得到一个像这样的输出。

Serving on http://127.0.0.1:8000

像下面这样的响应将在8000端口返回。

{hello:world}

发送WhatsApp信息

我们将从用户那里获取个人信息,并将这些信息存储在我们的数据库中。然后,我们将根据用户提供的细节向每个用户发送欢迎问候。

接受用户的详细资料

我们需要接受用户的一些细节。它们是姓名和出生日期。这样修改app.py 文件。

from chalice import Chalice, Response
import boto3
from boto3.dynamodb.conditions import Key

app = Chalice(app_name='welcome-app')


def get_app_db():
    dynamodb = boto3.resource("dynamodb")
    table = dynamodb.Table('demo-table')
    return table


@app.route('/recipient', methods=['POST'])
def add_recipient():
    data = app.current_request.json_body
    try:
        get_app_db().put_item(Item={
            'id': data['id'],
            "name": data['name'],
            "phone_number": data['phone_number']
        })
        return {'message': 'ok', 'status': 201, 'id': data['id'], 'name': data['name'], 'phone_number': data['phone_number']}
    except Exception as e:
        return {'message': str(e)}

在上面的代码中,我们做了必要的导入,我们在get_app_db() 方法中定义了我们的数据库。然后我们创建了一个名为add_recipient() 的方法,其中有一个名为/recipientPOST 路线。

这个方法接受用户数据:用户的姓名、年、月和出生日期。然后,这些细节被保存到数据库中。在保存完这些细节后,应用程序将返回一个201 响应。否则,它将返回一个错误。

用Twilio发送WhatsApp信息

现在,我们将使用Twilio客户端来发送消息。首先,从你的Twilio仪表板上获得你的账户SID和授权令牌。将它们设置为你的项目的环境变量。

现在,我们将修改app.py 文件,如下所示。

import os
from twilio.rest import Client

account_sid = os.environ['TWILIO_ACCOUNT_SID']
auth_token = os.environ['TWILIO_AUTH_TOKEN']
client = Client(account_sid, auth_token)

@app.route('/recipient', methods=['POST'])
def add_recipient():
    data = app.current_request.json_body
    try:
        get_app_db().put_item(Item={
            'id': data['id'],
            "name": data['name'],
            "phone_number": data['phone_number']
        })
        message = client.messages \
            .create(
                from_='whatsapp:+YOUR_TWILIO_NUMBER',
                body='Welcome to the crew, {}! Keep enjoying the vibe'.format(
                    data['name']),
                to='whatsapp:+{}'.format(
                    data['phone_number'])
            )
        return {'message': 'ok', 'status': 201, 'id': data['id'], 'name': data['name'], 'phone_number': data['phone_number']}
    except Exception as e:
        return {'message': str(e)}

在上面的代码中,我们做了必要的导入,并在app.py 文件中定义了Twilio凭证。然后,我们使用Twilio客户端创建一个消息,并将其发送到收件人的号码。用你的Twilio WhatsApp号码替换YOUR_TWILIO_NUMBER

app.py 文件中的完整代码是。

from chalice import Chalice, Response
import boto3
from boto3.dynamodb.conditions import Key
import os
from twilio.rest import Client


app = Chalice(app_name='welcome-app')


account_sid = os.environ['TWILIO_ACCOUNT_SID']
auth_token = os.environ['TWILIO_AUTH_TOKEN']
client = Client(account_sid, auth_token)


def get_app_db():
    dynamodb = boto3.resource("dynamodb")
    table = dynamodb.Table('demo-table')
    return table


@app.route('/recipient', methods=['POST'])
def add_recipient():
    data = app.current_request.json_body
    try:
        get_app_db().put_item(Item={
            'id': data['id'],
            "name": data['name'],
            "phone_number": data['phone_number']
        })
        message = client.messages \
            .create(
                from_='whatsapp:+YOUR_TWILIO_NUMBER',
                body='Welcome to the crew, {}! Keep enjoying the vibe'.format(
                    data['name']),
                to='whatsapp:+{}'.format(
                    data['phone_number'])
            )
        return {'message': 'ok', 'status': 201, 'id': data['id'], 'name': data['name'], 'phone_number': data['phone_number']}
    except Exception as e:
        return {'message': str(e)}

部署到AWS

我们将使用chalice deploy 命令来部署到AWS。

chalice deploy

我们应该在终端上得到以下响应。

Creating deployment package.
Creating IAM role: welcome-app-dev-api_handler
Creating lambda function: welcome-app-dev
Creating Rest API
Resources deployed:
  - Lambda ARN: arn:aws:lambda:us-west-2:xxxxxxxxxxxx:function:welcome-app-dev
  - Rest API URL: https://vvyngxvyag.execute-api.us-west-2.amazonaws.com/api/

我们已经得到了RESTful API URL,我们将用它来与Chalice API互动。

让我们试试Postman上的/recipient API端点。端点的URL将是这样的。

https://vvyngxvyag.execute-api.us-west-2.amazonaws.com/api/recipient

我们可以指定JSON格式的请求的body ,如下所示。

{
    "id": "1",
    "name": "Oyewole Hajarah",
    "phone_number": "2348141684988"
}

我们应该得到一个响应,如下图所示。

Postman response

然后,你的收件人将收到发送的WhatsApp信息。

Screenshot of the WhatsApp message sent

结论

在本教程中,我们已经能够用API创建一个Chalice应用程序。我们使用Twilio WhatsApp API来发送消息。我们还用Postman测试了该API。

现在,你可以在无服务器技术和AWS基础设施上建立更多的东西。