The Problem
I was bad at dating apps. Not at dating itself, but at the apps. The core loop of a dating app is: look at a profile for two seconds, make a snap decision, repeat hundreds of times. It is tedious, it is time-consuming, and after twenty minutes of swiping your standards collapse into “has a face, swipe right.” Everyone knows the optimal strategy is to be selective. Nobody actually does it because the interface punishes selectivity with boredom.
I am a software engineer. I solve tedious repetitive problems by automating them. So I built an AI agent that swipes for me on Bumble.
And then I got a girlfriend.
How It Works
The system has four main pieces: an Android emulator running Bumble inside a Kubernetes pod, an Appium server controlling the emulator, a machine learning model deciding who to swipe right on, and a task queue coordinating everything.
The automation loop is simple. Capture a screenshot of the current profile. Run it through an image processing pipeline. Score the profile with the ML model. If the score is above the threshold, swipe right. If not, swipe left. Repeat.
The swipes are physical gestures. Appium uses the W3C Actions Protocol to simulate a finger dragging across the screen, exactly like a human would. From Bumble’s perspective, someone is sitting there swiping.
The ML Model
This is the part that matters. A random swiping bot is useless. A bot that swipes right on everyone is worse than useless because it tanks your ELO score on the app. The model needs to predict who I would actually be attracted to.
I fine-tuned EfficientNet-B7 for binary classification: attracted or not attracted. The training data came from me. I built a small React app that served me Bumble profile photos and I classified them one by one. Attracted, not attracted, delete. Hundreds of them. It was tedious, but it was the only way to get labeled data that reflected my actual preferences rather than some generic attractiveness metric.
The image pipeline is aggressive about filtering before the model even sees a photo. First it runs Faster R-CNN to detect bodies. Then MTCNN to detect faces. If there is no face, no body, or multiple people in the frame, it skips the profile entirely. The model only sees clean, single-person photos where a face is clearly visible.
Training uses PyTorch with mixed precision on the cropped face images. Input is 600 by 600 RGB, normalized with ImageNet statistics, output is a sigmoid score between 0 and 1. The threshold is configurable but defaults to 0.5. After twenty epochs with a batch size of 64, the model was accurate enough that its swipe decisions matched my own about as well as my decisions at 11 PM matched my decisions at 9 AM. Good enough.
The Automation
An Android emulator runs Bumble, Appium turns the decisions into swipe gestures, and a Python loop runs the model. I kept the emulator state persistent so I would not need to log in again after a restart. The rest of the infrastructure was operational plumbing, not the point of the project.
The Onboarding Problem
You cannot automate the Bumble login. Two-factor auth, phone verification, CAPTCHA — dating apps are aggressive about preventing exactly what I was building. The solution was to not even try.
During onboarding, the system spins up your emulator pod and gives you a VNC link. You connect to the emulator through your browser, open Bumble, and log in manually. Once you confirm you are logged in, the system marks you as ready and automation can start. Your session persists in the emulator’s storage, so you only do this once unless Bumble forces a re-login.
This was a deliberate design choice. Trying to automate login would have meant an arms race against Bumble’s security team. Manual login takes two minutes and sidesteps the problem entirely.
How I Got a Girlfriend
The bot did not get me a girlfriend. The bot got me matches. There is an important difference.
What the bot did was solve the selection problem. Instead of me spending forty minutes a day swiping through profiles with degrading attention, the model made consistent decisions based on the preferences I trained into it. It swiped selectively, which kept my profile’s ranking healthy. It swiped accurately, which meant the matches it generated were people I was actually interested in meeting.
The bot does not message anyone. It does not have conversations. It does not write openers or respond to prompts. Once a match happens, it is entirely on me. And that is the part that actually matters. The automation removed the worst part of dating apps — the mindless swiping — and left me with the part that requires being a real person.
I matched with my girlfriend on a right swipe the bot made. We talked, we met up, we kept meeting up. The bot picked her profile out of hundreds. I did everything after that.
Takeaway
Dating apps are designed to keep you swiping. The longer you swipe, the more ads you see, the more likely you are to pay for premium features. Selectivity is punished with fewer dopamine hits. The interface optimizes for engagement, not for finding someone.
Automating the swipe decision with a model trained on my own preferences flipped the dynamic. The app’s engagement tricks do not work on a bot. The bot is patient, consistent, and selective in exactly the way I cannot be after twenty minutes of looking at profiles. It turns out that being genuinely selective — not aspirationally selective, but computationally selective — produces better matches. And better matches lead to better dates. And one of those dates turned into a relationship.
I built a machine learning pipeline, a Kubernetes cluster, and a mobile automation framework to do what a patient person with good judgment could do with their thumb. But I am not that person at 11 PM on a Tuesday. The bot is.