Serverless Go project that utilizes Twilio to send a random cat fact to a list of subscribers once a day.
The project is structured as a single Go module with several packages. AWS Lambda are placed in a named directory under functions
. The project contains a single shared package named models
containing common models used in each Lambda. Domain specific logic for each lambda function is encapsulated within the main package of that function.
Each function is a self contained executable, representing an independently triggerable and scalable unit of work. The structure of each function is a flat main package. Flat structures are always a great default for smaller projects, and I tend to think of each lambda function as a small, isolated, deployable project. There are a few other structures that would work for a project of this scale, including a structure in which we break handlers into a shared handlers
package, and move entrypoint files into a cmd/
directory.
Each function is passed configuration through environment variables, and defines a single config struct that maps to these variables. I use https://github.com/caarlos0/env to simplify the logic of parsing environment variables.
.
├── functions/
│ ├── send-fact/
│ │ ├── config.go
│ │ ├── handler.go
│ │ └── main.go
│ └── twilio-callback/
│ ├── config.go
│ ├── main.go
│ ├── handler.go
│ └── ...
├── models/
│ ├── subscription.go
│ └── ...
├── go.mod
├── go.sum
├── Makefile
├── template.yaml
└── .gitignore
twilio-callback is an HTTP triggered Lambda function. The function URL is supplied to Twilio as a webhook. Requests will be sent to the function when a text message is sent to the CatFacts phone number. The function does parses the request, and determines if the user is subscribing, unsubscribing, needs help or the request cannot be understood. The function then takes the appropriate action (e.g. deleting a users phone number from the subscription table in Dynamo) before sending a response.
send-fact is a time triggered Lambda function that runs once a day. The function fetches a random fact from the catfact ninja api, loads a list of subscribers from DynamoDB and attempts to send each subscription the fact.