iMessageWrapped
iMessageWrapped was inspired by Spotify's Wrapped feature which allows users to visualize and analyze their listening patterns over the previous year. I wanted to give the same view into texting patterns, analyzing the results of who/how/when/where people had texted.
The actual application is a flask server which runs locally (no streaming user messages over network 😅). Since Apple doesn't expose public APIs for interacting with message data, the server queries the local message and contact SQLite databases. The contact databases are a little tricky: a user may mantain multiple contact databases on the same machine (because, for instance they imported contacts from multiple devices). As a result, on initilizaiton, the server will loop through all available contact databases, generating a unique list of contacts.
Once connected to the DBs, the application runs queries for the who, what, where, and why sections. Some of my favorite queries were: average time of first text sent during the day, person contacted most after midnight, and top texts by contact. On the frontend, simple visualizations are rendered by passing the the results of these queries directly in a Jinja template. For more complex visualizations (such as texting by time of day or week), I used chart.js and leaflet, which call internal API routes to populate the visualizaitons.
Using nltk, I wrote and trained bigram and trigram models to extract the most frequently used phrases in text conversations. Unfortunately, these increased the distribution size of the application by nearly 200mb and I ultimately decided to scrap them and just include data around the most common usages for figures of speech.
iMessageWrapped was distributed with pyinstaller. Building and releasing this project was really really fun! I was just learning to code at the time and it was very validating to see how people responded (I made it to #1 on the projects section of Hacker News and even had someone Venmo me $5). Now that's PMF.