I tweet every time I spend money
For the past few months, I’ve been tweeting every time I spend money. You can check it out at @ch_ylukem1.
It started with an Uber ride:
UBER — $23.03
— ch (@ch_ylukem) October 17, 2019
I took December 2019 off to travel Asia and visit family in Europe. The account became a fun place to catalog my travels.
A hotel I stayed at in Tokyo:
HOTEL ON BOOKING COM — 24,024.00 JPY
— ch (@ch_ylukem) December 5, 2019
Getting around Bangkok:
GRABTAXI (THAILAN... — $1.65
— ch (@ch_ylukem) December 7, 2019
My favorite coffee shop in Oslo:
TIM WENDELBOE — $13.42
— ch (@ch_ylukem) December 27, 2019
Rolling my own Mint.com
To make this work, the first thing I had to do was enable email notifications at every bank’s website. Banks slightly bury this functionality, but just look for “Alerts” somewhere in the settings and you’ll find it.
Citibank and Chase support this flawlessly; they let you configure email-based transactions for everything above $0.01. I had a harder time with my Barclays card2. American Express almost gets there, but only will send you an email if the charge is above $10.00. Good enough, I guess.
Once I started getting these transaction emails in my email, I wrote a Lambda function that scrapes the merchant name and amount from the email’s HTML using cheerio. It’s not the prettiest thing, but for each bank I wrote a function that returns a string.
The email that Citibank sends
const citibank = jq => {
const merchant = jq("td")
.filter((i, el) => jq(el).text() === "Merchant")
.next()
.text();
const amount = jq("span")
.filter((i, el) => jq(el).text() === "Amount:")
.closest("tr")
.text()
.replace("Amount:", "")
.trim();
return `${merchant} — ${amount}`;
};
After that, I configured Amazon’s SES email hosting at my domain. SES can trigger a Lambda function with each incoming email.
Here’s all of it together:
- A Gmail filter forwards each transaction alert email to my AWS SES account
- AWS SES saves the email to an S3 bucket and triggers a Lambda function
- The Lambda function scrapes the merchant name and amount from the email and sends the tweet
Why do this?
Some time ago, I remember reading online that the easiest way to get one’s own financial data in real time isn’t to try to scrape it from the bank’s website, but to instead use email.
Later, I got the idea to start publishing my transactions from seeing @SbarroChica on twitter. I really liked seeing credit card transactions interspersed with tweets about her day.
This also isn’t the first time I’ve experimented with publishing my own data; I used to operate an API that published my age, what music I’m listening to, and my sleep history.
It’s been fun seeing friends of mine interact with this, in predictable ways and otherwise. Almost immediately, people started reacting to transactions:
they give you meals even if the flight is like 45 min
— Jarred Sumner (@jarredsumner) December 3, 2019
they also have a terrible airline safety record
this is a lot of hichew
— Alex Sexton (@SlexAxton) December 18, 2019
gotta stock up on dat tp
— Hallie Lomax (@hrlomax) March 20, 2020
What’s the worst that can happen?
An unintended consequence has been that people have been using this information to more accurately split the bill; in cases where I’ve told people “don’t worry about dinner”, they do in fact “worry about it”, and dutifully I get a Venmo with half of the cost of dinner, since the amount is published publicly.
Naturally, this account got a lot more boring once shelter-in-place began. Taxi rides and restaurant transactions got replaced with online orders for tea and Instant Pots. The account even had a month long outage that I barely noticed until a former coworker tweeted about it.
I intend to run this as experiment indefinitely. It might end one day, but like I said when I first posted about this, I’m excited to see how it goes wrong.
The name is an homage to my former employer, Stripe. Charge IDs in their system always start with
ch_
.↩I used to have an Uber Visa Card issued by Barclays. Barclays would send transaction alert emails that didn’t have the name of the merchant in the email. Since I only used this card to buy coffee, I instead wrote a scraper for the Square receipts the coffee shop would send with each coffee.↩