Welcome to Day 4 of 12 Days of DigitalOcean! Yesterday, we added Twilio SMS notifications to our Birthday Reminder Service, making it capable of sending text messages for today’s birthdays. 🎂
Today, we’ll take things to the next level by deploying our script to DigitalOcean Functions. This lets our service run in the cloud without the need for a dedicated server, making our app lightweight, scalable, and ready for automation.
With this setup, you’ll receive birthday reminders even when your computer is off or not connected to the internet—no need to run the script manually on your machine anymore. 🎉
Sometimes, all you need is a simple script that runs occasionally. Managing infrastructure for something like that can be an overkill. That’s where Functions comes in. It’s a serverless platform, meaning you can deploy code that runs only when needed, and you only pay for what you use. Perfect for our use case—checking birthdays and sending reminders daily.
By the end of today, you’ll know how to:
doctl
CLI tool.Before starting, make sure you have:
.env
file with your PostgreSQL database credentials and Twilio credentials
doctl
CLIIf you’ve already set up doctl on your machine, you can skip this step. For those who need to set it up, follow these instructions:
Before we begin, let’s quickly talk about doctl
. It’s DigitalOcean’s official command-line interface tool that allows you to manage your cloud resources right from your terminal. We’ll use it to create a namespace (a folder for our serverless functions), deploy our Python script, and test the function.
Setting it up is straightforward:
Install doctl
: Follow the installation guide for your operating system.
Authenticate doctl
: Connect it to your DigitalOcean account by running:
Verify the installation: Ensure everything is working by running:
If successful, this command will return details about your DigitalOcean account, like your email and account ID.
DigitalOcean Functions requires serverless support software, which you’ll need to install. This is a one-time setup, so once it’s installed, you won’t need to do it again for future projects.
Run the following command:
You can check the installation status with:
If you see an error like:
Don’t worry—that just means we haven’t created or connected to a namespace yet. We’ll handle that in the next step.
Namespaces are like folders for organizing serverless functions. Let’s create one for our Birthday Reminder Service:
Create a new namespace:
Connect to the namespace:
Verify the connection:
You should now see a confirmation that you’re connected to the namespace.
Pro Tip: To see a list of all available namespaces, use the following command:
This can be handy if you’re managing multiple projects or want to verify the namespace you just created.
DigitalOcean Functions expects a specific project structure for serverless deployments. You can kickstart this structure using doctl serverless init
, create it manually, or even clone a starter repo. To keep things simple, we’ll set it up using doctl serverless init
:
Run the following command to initialize the project:
This creates a local project directory named my-birthday-reminder-service
with the following default structure:
Navigate into the project directory:
Rename the folders to match our use case:
Create the necessary files:
This will hold your database and Twilio credentials. The file will be located at the root of the my-birthday-reminder-service
folder.
requirements.txt
file in the birthdays
folder:This file will list the Python dependencies needed for your function. It will be located under packages/reminders/birthdays
.
build.sh
file in the birthdays folder:The build.sh
script is necessary for deploying functions with external dependencies. The chmod
command ensures the script is executable on Mac/Linux systems.
Updated Structure: After completing these steps, your project structure should look like this:
Pro Tip: If you accidentally misname a folder, you can run the command again or manually rename it in your file explorer.
Now that the structure is in place, let’s populate it with the necessary files. Open the my-birthday-reminder-service directory in your favorite code editor
project.yml
The project.yml
file is a configuration file that defines your serverless project’s structure, environment variables, and functions.
This file sets up the reminders package and maps environment variables to DigitalOcean Functions. Each variable corresponds to the credentials needed for your database and Twilio integration.
Refer to Day 1: Setting Up a PostgreSQL Database for Birthday Reminders for the database credentials and Day 3: Checking Birthdays and Sending SMS Notifications for Twilio credentials to populate the following values:
Note: The .env
file is used to store sensitive credentials securely. Your project.yml
file will read these values and map them to the serverless environment during deployment, making them accessible to your function in the cloud.
Update requirements.txt
file with the following dependencies:
pg8000
: A pure-Python PostgreSQL client library.
python-dotenv
: Used to load environment variables from the .env
file.
twilio
: The Twilio Python library for sending SMS messages.
Add the following script to the build.sh
file:
This script ensures that all dependencies are packaged correctly with your function. The chmod +x
command from Step 4 ensures it is executable.
__main__.py
This is the main script for your Birthday Reminder Service. We’re essentially using the script we built in Day 3 for sending birthday notifications. However, to make it compatible with DigitalOcean Functions, we need to make a few small adjustments.
Update the __main__.py
file with the following content:
Here’s what we’ve changed:
Added a main(params)
function: DigitalOcean Functions expects an entry point function named main
, which takes a params
argument. This is where the function starts execution.
Moved the script logic inside the main
function:
The code from Day 3 has been wrapped inside the main
function to align with this requirement.
Everything else remains the same: The database connection logic, birthday checks, and SMS notification logic are unchanged.
With everything in place, deploy your project to DigitalOcean Functions:
To verify that your function was successfully deployed to the namespace:
reminders/birthdays
.Once your function is deployed, it’s time to test it. You can invoke the function manually to ensure it works as expected. There are two ways to do this:
If everything is set up correctly, your function will run in the cloud, checking for today’s birthdays and sending SMS notifications.
This method is especially helpful if you prefer a visual interface or want to check the logs in a clean, easy-to-read format.
When you invoke the function, it will check for birthdays matching today’s date. You’ll receive a text message with the details if there’s a match. To test the function effectively:
Here’s what you accomplished today:
doctl
and created a namespace for our project.Here are the previous tutorials from this series:
Up next: While this is a big step forward, we’re still running the function manually. In the next tutorial, you’ll automate this process so the Birthday Reminder Service runs automatically every day at a specific time. Imagine waking up to a text reminder without lifting a finger—let’s make that happen tomorrow! 🚀
Here is the next tutorial on Day 5: Automating Birthday Reminders with Daily Triggers.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!