Simple WhatsApp bot infrastructure on AWS Lambda using CDK.
uv sync
To start developing locally:
docker compose up
Create the tables:
EVENTS_TABLE
MESSAGES_TABLE
# events table
aws dynamodb create-table \
--table-name 'EVENTS_TABLE' \
--attribute-definitions \
AttributeName=id,AttributeType=S \
AttributeName=key,AttributeType=S \
--key-schema \
AttributeName=id,KeyType=HASH \
AttributeName=key,KeyType=RANGE \
--provisioned-throughput \
ReadCapacityUnits=1,WriteCapacityUnits=1 \
--endpoint-url 'http://localhost:8001'
# messages table
aws dynamodb create-table \
--table-name 'MESSAGES_TABLE' \
--attribute-definitions \
AttributeName=from_,AttributeType=S \
AttributeName=timestamp,AttributeType=S \
--key-schema \
AttributeName=from_,KeyType=HASH \
AttributeName=timestamp,KeyType=RANGE \
--provisioned-throughput \
ReadCapacityUnits=1,WriteCapacityUnits=1 \
--endpoint-url 'http://localhost:8001'
Run the app:
uv run uvicorn handler:app --reload
If you don't want to read:
docker compose up --build
Deploy:
npx aws-cdk deploy --app 'uv run infra.py' --verbose
# or
make deploy
Destroy:
npx aws-cdk destroy --app 'uv run infra.py' --verbose
# or
make destroy
Redeploy:
npx aws-cdk destroy --app 'uv run infra.py' --verbose
# or
make reset
Architecture diagram of the infrastructure:
graph TD
User --[send message]--> WhatsApp
WhatsApp --[wbehooks]--> ApiGateway
ApiGateway --> Lambda
Lambda --[store chat messages]--> MessageTable
Lambda --[store raw events]--> EventTable
Lambda --[send message]--> WhatsApp
Sequence diagram of the message flow:
sequenceDiagram
User->>WhatsApp: send message
WhatsApp->>ApiGateway: POST /
ApiGateway->>Lambda: proxy
Lambda->>EventTable: store raw event
Lambda->>OpenAI: generate response
OpenAI->>Lambda: response
Lambda->>MessageTable: store chat message
Lambda->>WhatsApp: send message
WhatsApp->>User: message sent