使用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中收到这样的信息。
你也会在你的仪表板上看到一个Message Received
,像这样的回应。
让我们在一个新的文件夹中为你的项目创建一个虚拟环境。
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表的关键属性,即信息接收者的id
和name
。KeySchema
由主键组成。
接下来,让我们导航到.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()
的方法,其中有一个名为/recipient
的POST
路线。
这个方法接受用户数据:用户的姓名、年、月和出生日期。然后,这些细节被保存到数据库中。在保存完这些细节后,应用程序将返回一个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"
}
我们应该得到一个响应,如下图所示。
然后,你的收件人将收到发送的WhatsApp信息。
结论
在本教程中,我们已经能够用API创建一个Chalice应用程序。我们使用Twilio WhatsApp API来发送消息。我们还用Postman测试了该API。
现在,你可以在无服务器技术和AWS基础设施上建立更多的东西。