Inspiration
At Rutgers, staying involved is hard to keep track of. You join a few clubs, and each one announces its events somewhere different: Instagram, Discord, its own website. On top of classes, it's easy to miss things, especially as a freshman when everything seems to happen at once. Today the only way to keep up is to check every club's Instagram and Discord one by one, and some students don't even use Instagram, even though it's the only place many clubs post.
What it does
ClubsRU puts every Rutgers club event in one calendar, collected automatically.
- Discover clubs: browse popular Rutgers organizations, filter by category and campus, or describe your interests and let Gemini recommend clubs that fit you.
- Follow the ones you like.
- Events are collected for you: a Discord bot reads each club's announcements channel, a watcher sends clubs' Instagram posts (captions and flyer images) to Gemini, and club websites are checked whenever they change.
- One calendar of every event from the clubs you follow, with filters for free food 🍕 and campus.
- Google Calendar sync: one subscription link puts your clubs' events in Google Calendar (or Apple / Outlook), and it keeps updating on its own.
How we built it
- Google Gemini is the core. It reads messy posts like "GBM this Wed 7:30 in Hill 114, pizza!!" and flyer images, and returns clean events (title, date, time, location, campus, free food) using structured output with Pydantic schemas. We give it the post's date so it can resolve "this Thurs" or "10/5", and a list of Rutgers buildings so it knows which campus each is on. It also handles multi-day events and ignores posts that aren't events. Gemini also powers club recommendations.
- Python + Flask website, SQLite database, discord.py bot, a watcher for Instagram and club websites, FullCalendar for the calendar view, and iCalendar (.ics) feeds for Google Calendar sync through a Cloudflare Tunnel.
- We built a test set of 12 real club flyers from Instagram, with an answer key, to check Gemini's accuracy, including messy ones with tiny text, abbreviations like "LIVI MPR", missing times and a whole month's calendar on one image.
Challenges we ran into
- Gemini's free tier allows only about 20 requests a day per model, so we added a fake mode for development, rotation across several API keys and automatic fallback to other Gemini models.
- Instagram doesn't allow scraping, so we designed it the legitimate way: clubs connect once through Instagram's official API, and for the demo a folder per club stands in for its feed.
- Google Calendar can't reach localhost, so we expose the site through a Cloudflare Tunnel for subscription links.
- Making sure each post is read only once, and that the same event posted on both Instagram and Discord is merged instead of duplicated.
Accomplishments that we're proud of
- Gemini correctly reads real, messy club flyers into calendar events with no manual typing.
- One subscription link keeps a student's own Google Calendar updated with every club they follow.
- A dataset of 37 real Rutgers clubs with their Instagram, Discord, campus and getINVOLVED links.
What we learned
How to get reliable structured data out of an LLM, work within API rate limits, build a Discord bot, and generate calendar feeds that Google Calendar can subscribe to.
What's next for ClubsRU
- Make it so it doesn't depend on an external computer running the Python for it to work
- Add every Rutgers organization, not just our starter set.
- Event reminders, conflict warnings with your class schedule, and a mobile-friendly version.
Built With
- cloudflare
- discord.py
- flask
- fullcalendar
- gemini
- icalendar
- javascript
- python
- sqlite
Log in or sign up for Devpost to join the conversation.