Day 19 of the Anvil Advent Calendar
Build a web app every day until Christmas, with nothing but Python!
Christmas SMS countdown
We’re already watching the calendar, thanks to advent day 3, and yesterday’s app. But, what if we could get a text message every day to let us know how close we are to Christmas? Wouldn’t that be lovely? No? Well, I’ve done it anyway.
Read on to learn how, or you can open the source code for yourself:
Request data from the API
We already created an API endpoint for the days to Christmas on day 8:
https://christmas-days.anvil.app/_/api/get_days
I’ll use this API to get the days to Christmas.
Create a new Anvil app and add a Server Module. Add a get_days
function to your Server Module:
import anvil.http
def get_days():
# Get data from the API
response = anvil.http.request("https://christmas-days.anvil.app/_/api/get_days",json=True)
days_until_christmas = response['Days to Christmas']
return days_until_christmas
Create the UI
We want our users to be able to sign up to receive their Christmas countdown by SMS.
We’ll create a simple UI using a TextBox and a Button to capture and Submit user inputs.
Our basic UI looks like this:
Note: This guide includes screenshots of the Classic Editor. Since we created this guide, we've released the new Anvil Editor, which is more powerful and easier to use.
All the code in this guide will work, but the Anvil Editor will look a little different to the screenshots you see here!
Store user phone numbers
We want to store our registered users’ numbers in a database so we can send them an SMS every day. We’ll use Anvil’s Data Tables to do this, and the setup looks like this:
Let’s add a server function to store numbers in this table:
@anvil.server.callable
def store_number(number):
app_tables.numbers.add_row(phone_no=number)
Go back to your UI and double click on the Button. Modify your button_1_click()
method to look like this:
def button_1_click(self, **event_args):
# Get the phone number from the TextBox
number = self.number_box.text
# Call the `store_number` server function
anvil.server.call('store_number', number)
We’ll call this function from the client when the ‘Register’ button is clicked.
Send a text message
We’ll use the Vonage API to send our text messages. You’ll need to create a Vonage account to get your api_key
and api_secret
. Once you have these, use Anvil’s App Secrets to store these, encrypted, in your app:
Next, create a server function called send_text()
which will send our texts. We’ll decorate it as @anvil.server.background_task
:
@anvil.server.background_task
def send_text():
api_key = anvil.secrets.get_secret('api_key')
api_secret = anvil.secrets.get_secret('api_secret')
# Call our `get_days()` server function to get days from the api
days_to_christmas = get_days()
# Get our phone numbers from the Data Table
numbers = app_tables.numbers.search()
for n in numbers:
response = anvil.http.request("https://rest.nexmo.com/sms/json", method="POST", json=True,
data={
'api_key':api_key,
'api_secret':api_secret,
'to':n['phone_no'],
'from':'Anvil',
'text':f"There are {days_to_christmas} days until Christmas! \U0001F31F \ud83c\udf84 \ud83c\udf85",
'type':'unicode'
}
)
Create a countdown
We want to send a Christmas SMS once a day to everyone who’s registered for our countdown. We’ll use Scheduled Tasks to do this.
Select Scheduled Tasks from the Gear Menu, and set the send_text()
function to run once a day:
Click the green tick to save your task.
Let the countdown commence!
That’s all there is to it. Anyone who registers will now get a Christmassy countdown every day!
View the source code:
Give the Gift of Python
Share this post: