Checking Your Daily Spending via SMS with Python, Plaid and Twilio
Time to read: 5 minutes
Your bank may let you set up SMS alerts for various triggers. It might even give you the option of receiving periodic spending summaries via SMS (mine doesn’t though!). But what about a daily SMS summary of your spending across all your accounts? This summary is harder to come by, but thankfully you can roll your own by combining Plaid, an easy to use financial services API and Twilio SMS with a bit of Python 3. Let’s get going!
Setting Up
We’ll begin creating our app by lining up some of the basic building blocks. Here’s all the code in one place for those following at home and want to save some typing.
Start by nabbing a sandbox account from Plaid and putting your credentials into PLAID_CLIENT_ID
, PLAID_SECRET
, PLAID_PUBLIC_KEY
environment variables. While you’re at it, ask for access the development API (it’ll take a few days to get approved). For now, though, create an environment variable named
PLAID_ENV and set it to ‘sandbox’. This will give us some sample data to work with.
Next, clone the quickstart for Plaid, install from requirements.txt
using the pip install -r requirements.txt
command then edit the server.py
code to include those environment variables.
Run server.py
with the python server.py
command (unfortunately this part of the example code only works with Python 2 😦) and open http://127.0.0.1:5000 in your browser.
Click “open link”, then log into Chase with the test credentials (“user_good” and “pass_good” as of 5/26/2017) and the application will print an access token to your terminal window.
Grab the token and put it into a CHASE_ACCESS_TOKEN
environment variable. Repeat this for Bank of America and put that access token into BOFA_ACCESS_TOKEN
:
Grab your Twilio credentials from the Console (sign up for a free account if you don’t already have one), a Twilio phone number and your own phone number, then add those as environment variables.
Finally, install a couple of project dependencies:
With the basic building blocks in place we can start coding our app.
Obtaining Transactions
A quick way to start working with Plaid is to grab some account transactions and explore the result. Make a new file called get_some_transactions.py
. In that file create a plaid.Client
instance and a new function named get_some_transactions
which accepts an access token and the start and end dates of the range of transactions you want to get. Inside the function, call the Plaid client’s Transactions.get
function with those parameters. The following code will accomplish these steps.
With that code in place we can start exploring what information Plaid returns. In the same script, call get_some_transactions
by adding the following two lines to the end of the file. These pass in the Chase access token and a wide date range.
Run the script using the python get_some_transactions.py
command.
When run this code outputs there are 338 total transactions between those dates
. How many transactions were returned from our Plaid API call?
Apparently, get some_transactions
returned 100 transactions. Why only 100? It seems that’s the default value for count
, an optional parameter for Transactions.get
, as seen here in the Plaid API documentation.
What sort of data are in a transaction?
This code outputs dict_keys(['account_id', 'account_owner', 'amount', 'category', 'category_id', 'date', 'location', 'name', 'payment_meta', 'pending', 'pending_transaction_id', 'transaction_id', 'transaction_type'])
. For our purposes, amount
seems to be all we need, but what about category
? We’re not building a full-fledged budget bot, but are there any transactions that would muddy the waters of our spending summary?
This code gives us {'Food and Drink', 'Travel', 'Transfer', 'Airlines and Aviation Services', 'Payment', 'Credit Card', 'Coffee Shop', 'Fast Food', 'Restaurants', 'Deposit'}
. This will be useful to create a choosier get_some_transactions
function. For example, “Transfer” transactions I would argue don’t belong in our daily summaries, since they don’t qualify as spending. Before we refactor, though, let’s see what sort of accounts we’re dealing with, and whether there are any we should exclude.
Leaving out the less relevant fields, this execution results in:
There’s some low-hanging fruit here too: with any luck, we won’t be spending out of our savings or investment accounts — at worst, we’d be doing transfers — so let’s get refactoring!
Getting the Right Transactions
We know we want to exclude transactions with a category of “Transfer”. “Credit Card”, “Payment” and “Deposit” aren’t going to be useful in gleaning spending activity either, so we’ll refactor our get_some_transactions function to skip transactions with those categories. As stated earlier, we also want to skip accounts with a subtype of “savings” or “cd”.
While we’re at it, let’s also make sure to get all available transactions by using pagination, not just those default first 100, and hone in on just the transactions
item, not any others. Modify get_some_transactions.py
with the following code (which can also be found in get_some_transactions.py on GitHub).
Execute the code and it says that there are 265 transactions. Are any of them negative?
Several are, in fact, negative:
Okay, that seems legit- airfare refund, I guess. All the transactions with negative amounts are similar to this, so let’s keep them in.
Pulling It All Together
Now let’s get all the transactions from yesterday, making sure to pull them from both accounts. Create a new file named get_yesterdays.py
and add this code:
As of 5/26/2017, the most recent transactions available in these sandbox accounts are from 5/16/17: Hence, the hardcoded yesterday value above.
Let’s send an SMS to ourselves with the total spent yesterday! Create another new file named send_summary.py
and add this code to it:
Run the code using the python get_send_summary.py
command and voila!
Wrapping It Up
We’ve now created an app that aggregates all spending across disparate credit and bank accounts, then pushes that total spend to our phone. Here’s all the code in one place. To deploy it, you could create a cron job somewhere to run it every day at a certain time, and never again have to deal with separate alerts/summaries from each spending account.
But that’s just the tip of the iceberg of what you could build with this spending data. I don’t know about you, but having built this proof of concept makes me want a bot that tracks my spending, pinging me to categorize items it can’t categorize itself. Spreadsheets are a blast and all, but do I need the unpaid part-time job of maintaining one? Ditto for the existing web apps.
A simpler extension of this app would be to set it up for your grandma and see if you can build a meaningful voice interaction into it.
Put your ideas and questions in the comments below!
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.