Receive SMS Transaction Notifications for your TransferWise Account with Twilio and Python
Time to read: 7 minutes
TransferWise is a digital bank that can save us from dread expensive bank fees. I have an account and love the service, but I’m really concerned about bad actors defrauding my card or login credentials.
What if TransferWise would send proactive alerts on debit transactions? Then I could act quickly to lock it down and minimize losses in case anything bad happens.
Twilio to the rescue!
In this tutorial, we’ll build a real time bank account monitor with the Transferwise API and Twilio SMS API. The application will send SMS alerts to a phone number notifying about debit transactions.
Preparing the requirements
To follow this tutorial, you will need the following:
Python: we’ll use Python3.9 (latest stable), but the code should also run on Python3.6+. To download and install, follow instructions on the official website. Python runs on Windows, Linux/UNIX and MacOS.
TransferWise account: if you don’t already have one, registration is free.
A server to keep the account monitor running 24/7: a small-capacity server with low CPU power, and perhaps 1 or 2 GB RAM should handle the job. Networking (calls to external HTTP APIs) and a time-based job scheduler (i.e. CRON) will also be needed. The script has a very small compute resource footprint, so you may well take advantage of a current server with spare capacity lingering anywhere in the cloud.
Setting up a Python virtual environment
For this project, we’ll need third-party libraries that don’t come bundled with Python. A good practice to manage dependencies is using a virtual environment.
Create a folder for the project:
Now let’s create and activate a virtual environment:
If you are following this tutorial on a Windows computer, replace the source
line above with the following:
Setting up Twilio
Login to your Twilio Console and take note of your Account SID and Auth Token:
Make sure you have a phone number listed in Phone Numbers > Manage Numbers and that the number has messaging enabled. If you don’t have a number, click on the “Buy a number” button at the upper-right corner of the screen to get one.
Getting a TransferWise API token
You will need an API authentication token to connect into your TransferWise account and pull balance transactions. Follow the steps below (or check these detailed instructions):
Login your TransferWise account. In the upper-right corner, click on “Settings”:
Scroll down to the “API Tokens” section and click on “Add New Token”:
Since this project will only require read access to your TransferWise statements and following the principle of least privilege, it’s strongly recommended that you generate a read-only token and avoid damage in case your token is ever compromised:
Project dependencies
Open a requirements.txt
file with your preferred code/text editor and add the following lines:
We’ll use requests to interact with the TransferWise API. Twilio has its own Python library, which will make our lives a lot easier.
Now save and close the requirements file and install dependencies in the local virtual environment by entering the following command in your terminal:
Consuming the TransferWise API
Now entering the fun part, finally! There are three endpoints we need from the TransferWise API:
- Get profile ID: lists all your TransferWise accounts
- Get account information: get currency and account ID for each account
- Get account statement: latest transactions for each balance
Create a Python file named main.py
and open it in your text editor or IDE. Let’s begin by adding all the imports that we are going to need for this project:
In the following sections we’ll implement calls to the three endpoints listed above.
Get profile ID
The TransferWise Profile ID will be required in the subsequent API calls, so let’s get a hold onto it by creating a get_transferwise_profile_id
function in the main.py
file:
Notice we’re getting the TransferWise API Token from an environment variable, which you can set in your terminal with:
The above command should work on Linux/MacOS. On Windows, if you are using a command prompt window you must replace export
with set
. If you are using a PowerShell console, then use this command instead:
You might ask: why not just grab my profile ID once and hard code it? It’s sensible and you can certainly do that. The advantage of keeping the profile ID dynamic is in case you open other accounts (e.g. a new business). Besides, the API is pretty fast and one extra request every few minutes won’t hurt.
Save your main.py
file and then test the get_transferwise_profile_ids
function from your console with:
You should see an output like the one below (each “account” you have on TransferWise will have one ID in the list printed):
Get account information
The next step is getting the different currencies you trade in and the account IDs for each profile ID. If you’re like me, you’ll be using lots of them and we definitely want all greenies safe.
Run it in your console (replace “12345678” with an actual profile ID retrieved by the previous function):
You should see a list of dictionaries, each containing a profile_id
, account_id
and currency
keys. Each currency (e.g. "USD", "EUR") has its own independent transaction history and we’ll need to retrieve statements from them separately in the next step.
Get account statements
The last task with the TransferWise API is getting the actual statements we want to be alerted about.
There is one detail to take care of before we do that: how far back in time should we look into TransferWise statements? We will set this code to run on a recurring schedule. Say, every five minutes. Thus, looking into statements recorded in the last, well, five minutes (!) sounds reasonable.
But, not so fast... Relying solely on this “last X minutes” as the source of time interval is a somewhat naive approach. The external APIs our code relies on may fail. Our own server may go offline for some time. If any of these situations happen, our script is likely to fail alerting some transactions. For this reason, we need to keep track of the last time we checked our statements.
The following two functions will take care of storing and retrieving the latest_datetime
object in the local disk:
The following function will calculate the time interval we need in the TransferWise API request. If the datetime
object from get_latest_datetime
is not available (i.e. first execution of the script), it automatically falls back to the “last X minutes” option using an environment variable setting.
Note that UTC should be used as the timezone in all API calls, as indicated by the TransferWise documentation.
A function to format the Python datetime object into a string recognizable by the TransferWise API will also be handy:
Finally, we can now write the function to get account statements. This one gets slightly convoluted and we would be better off breaking it into multiple single-purpose functions. Nonetheless, I’m keeping everything together for the sake of simplicity in this tutorial:
Before you can test this function, set the SCHEDULE_EVERY_MINUTES
environment variable:
Remember that on Windows the environment variable is set with a different command, either set
if you use the command prompt, or $Env
if you use PowerShell.
To test the function in your console, use the following command (replace with your own account_id
, profile_id
and currency
argument values):
The response is going to be a list of debit transactions in the last time interval. Since you probably did not use your card in the last five minutes, you may want to temporarily set the SCHEDULE_EVERY_MINUTES
to a larger value so that you can see some transactions reported.
Sending alerts through Twilio
All right, now that we have all bank transactions in our hands, let’s send over an alert to our phones with the Twilio API.
First, instantiate the Twilio client:
Now the part that makes our phones ring:
The account_name
and transaction
variables used to format the body
of the SMS message come from the get_transferwise_account_statements
response payload.
Also notice we’re using a few additional environment variables:
TWILIO_ACCOUNT_SID
TWILIO_AUTH_TOKEN
TWILIO_SENDER_NUMBER
TWILIO_DESTINATION_NUMBER
To set them, use the same export
(Linux/MacOS), set
or $Env
(Windows) commands suggested above. For the sender and destination phone numbers, enter the complete phone number in E.164 format.
Test the SMS function from console with a sample message like the following one:
Finally, let’s write a main
function combining all other functions we wrote before:
To test the script, close the Python file and run it with:
Scheduling our Twilio monitor
We don’t know when someone will jump over the security fences around our TransferWise account and banking secrets, so it’s best to have this monitor running all day long in an automated fashion.
A popular tool for scheduling recurring jobs on Linux is CRON. Since most servers run on top of a Linux flavor, let’s ring our phones with CRON.
Make sure crontab is running with:
If it’s not, start the service with service cron start
. You may need to throw in a “sudo sandwich” for the command to work.
Attribution: XKCD (Creative Commons Attribution-NonCommercial 2.5)
Let’s open CRON for editing:
Schedule the script to run every five minutes (or whatever frequency suits you best) by adding the following line to the cron job list:
In case you were not into moving money in the last five minutes and you’d like to see some action, customize the contents of the latest-transferwise-twilio-datetime.txt
file. Set the datetime string to a few days or weeks ago (whenever you see the latest transactions in your TransferWise statements). The script should capture these in the next job run and send you an SMS.
If you happen to be running an OS X-powered server (or if you plan to keep your Macbook online 24/7), launchd is your friend. On Windows/Powershell, ScheduledTasks may well save your day.
And that is pretty much it!
We’ve written a simple script that retrieves debit transactions from TransferWise accounts and turns them into SMS alerts using the Twilio SMS API.
The main advantage we have on our side now is time. If a fraudster happens to debit money from our account in the future, we can act quickly to lock it down, notify the TransferWise security team and, in case of a card transaction, maybe even have the merchant nullifying it and returning our money.
I’m a backend software developer and a father of two amazing kids who won’t let me sleep so that he can enjoy spending nights connecting APIs around. Keep track of other projects fresh from dawn on my Github profile. My direct contact and other social links in byrro.dev.
Related Posts
Related Resources
Twilio Docs
From APIs to SDKs to sample apps
API reference documentation, SDKs, helper libraries, quickstarts, and tutorials for your language and platform.
Resource Center
The latest ebooks, industry reports, and webinars
Learn from customer engagement experts to improve your own communication.
Ahoy
Twilio's developer community hub
Best practices, code samples, and inspiration to build communications and digital engagement experiences.