Tristen.

Building HangoutHabit: The Journey from College Nostalgia to Y Combinator Finalist

February 9, 2024 (10mo ago)

Building HangoutHabit: The Journey from College Nostalgia to Y Combinator Finalist

After college, keeping up with friends became a logistical challenge—schedules got busier, people moved to different cities, and social connections grew harder to maintain. To tackle this problem, I teamed up with two college friends and built HangoutHabit, a social platform designed to make organizing hangouts easier.

HangoutHabit is more than just a project; it's the result of a month of intense collaboration, iteration, and feedback. It brought us to the final round of Y Combinator interviews, where we even got to pitch the idea to Michael Seibel. Ultimately, we needed a more clearly defined niche, but the experience was a masterclass in the software development lifecycle (SDLC) and launching a product with scalability in mind.

Visit hangouthabit.com to see the project in action.

The Idea & Execution

The idea for HangoutHabit was simple: help people reconnect by automating the tedious back-and-forth of scheduling. We set out to create a tool that collected availability from group members, determined the best time for everyone to meet, and handled all the communication through SMS and email.

Over the span of a month, we built HangoutHabit from the ground up, starting with a Flask backend and an Angular frontend. With a solid tech stack in place, we focused on iterating quickly—constantly gathering feedback from friends and family, refining the app’s features, and ensuring that it was solving real problems.

Iteration and Feedback Loops

Our initial version of HangoutHabit was a simple tool for collecting availability and scheduling events, but as we gathered feedback, we realized that more automation and streamlined communication were critical. Each iteration improved the user experience, and with every new feature, we stress-tested the system to ensure scalability.

We took the project to Hacker News, where HangoutHabit saw a surge of nearly 1,000 users. This real-world test gave us valuable insights into how our infrastructure handled load, and it helped us identify areas that needed optimization before we could pitch it to Y Combinator.

Y Combinator Experience

Making it to the final round of Y Combinator interviews was an incredible milestone for us. We had the opportunity to pitch to Michael Seibel and receive feedback directly from one of the most successful startup accelerators in the world. Although we didn’t get in, largely due to needing a better-defined niche, the experience gave us a tremendous learning opportunity. We gained a deep understanding of product-market fit and the importance of honing in on a specific problem and audience.

System Architecture & Design

Building HangoutHabit required a robust yet flexible tech stack. The system architecture is designed around modern, scalable technologies:

  • Backend: Flask for the API layer and business logic.
  • Frontend: Angular for a dynamic and interactive user experience.
  • Database: PostgreSQL for reliable data storage.
  • APIs: Twilio and SendGrid for automated communication.
  • Containerization: Docker for consistent deployment across environments.

hangout habit landing page

Here’s a breakdown of the core system components and some interesting design implementations.

Backend Design: Flask and PostgreSQL

At its core, HangoutHabit's backend is built using Flask, which provides a lightweight framework to handle API requests efficiently. The PostgreSQL database handles persistent data storage, managing users, events, and availability schedules.

The backend follows an MVC (Model-View-Controller) architecture, where the models represent data structures such as users and events, controllers handle the request logic, and views generate the API responses consumed by the Angular frontend.

One of the most interesting backend design implementations is the use of scheduled background jobs to automate availability polling and event creation. By using APScheduler, HangoutHabit can initiate polls, send reminders, and notify users of the best time to hang out, all without manual intervention.

from apscheduler.schedulers.background import BackgroundScheduler
from tasks import deleteUnconfirmed, createEvents, sendResults

scheduler = BackgroundScheduler()

def hourlyTasks(app):
    with app.app_context():
        deleteUnconfirmed(time.time())
        createEvents(time.time())
        sendResults(time.time())

scheduler.add_job(hourlyTasks, 'cron', day_of_week='*', hour='*', minute='27')

This job scheduler ensures that reminders and event polls are consistently sent out based on user preferences.

Automating Event Scheduling & Notifications

HangoutHabit uses a combination of Twilio and SendGrid to automate communications. Twilio is responsible for sending SMS reminders, while SendGrid handles email notifications. Both APIs are seamlessly integrated into the platform’s backend, ensuring that users are reminded to participate in group activities at the right time.

Polling and Event Creation

One of the key features of HangoutHabit is its ability to automatically generate polls based on group member availability. When a poll is initiated, group members are asked to provide their availability. This data is then processed to determine the best possible time for the group to meet.

The event creation logic is housed in the backend and involves handling various edge cases, such as ensuring no conflicting polls are created and handling differing time zones among group members.

def createEvent(group, dt):
    group.nextPollSendTime = dt + datetime.timedelta(days=(7 * group.recurrenceInterval))
    db.session.commit()

    firstAvailabilityStartTime = (dt + datetime.timedelta(days=2)).replace(minute=0, second=0, microsecond=0)

    for event in group.events:
        if event.isPolling:
            return 'started'

    event = Event(id=generateId(6, Event), isPolling=True, firstAvailabilityStartTime=firstAvailabilityStartTime, groupId=group.id)
    db.session.add(event)
    db.session.commit()

    # Notify group members
    for person in group.people:
        if person.status == 'Active':
            send_event_notification(person, event)

This method creates a new event, schedules it based on group preferences, and notifies members via their preferred communication method.

The availability data is processed and visualized to help users see overlapping time slots. This visual representation makes it easy for users to understand when the majority of group members are available.

Group Creation & User Engagement

Creating and managing groups within HangoutHabit is simple and intuitive. When a user creates a group, they set a frequency for polls (e.g., weekly, biweekly) and generate a unique join link that can be shared via SMS or email. Group members use this link to join and start participating.

Once a group member joins, they are required to confirm their account via a confirmation link sent through Twilio or SendGrid. This ensures that the group remains active and populated only with verified users.

Frontend Design: Angular and Material UI

The frontend of HangoutHabit is built using Angular and Material UI. Angular provides a dynamic and responsive interface, while Material UI ensures that the design is both modern and accessible. The frontend handles complex interactions like event scheduling, poll submissions, and real-time data visualizations, while ensuring that the user experience remains smooth and intuitive.

Availability Viewer

One of the most important components of the frontend is the Availability Viewer, which allows group members to view the best times for their hangouts. This component pulls data from the backend and visualizes it using charts to help users understand the availability of their group at a glance.

this.availabilityService.getAvailabilityViewResponse(eventId, personId).subscribe((res) => {
  this.isLoading = false
  this.event = parseEvent(res.event)
  this.group = parseGroup(res.group)
  this.availabilities = res.availabilities.map(parseAvailability)
  this.createDatasets()
})

Availability Graphs

The availability viewer pulls data from the backend and creates datasets that are visualized using charts. These charts display group availability over time, allowing users to make informed decisions about the best time to meet.

Ongoing Communication & User Engagement

Keeping users engaged and informed is key to HangoutHabit’s success. To achieve this, the platform sends out regular reminders and notifications about upcoming events. These notifications are tailored to the user’s preferences, whether they prefer SMS or email communication.

Notifications are automatically triggered when an event is created or when results are available. This proactive communication ensures that users remain engaged without the need for manual follow-ups.

def sendResult(event):
    group = event.group
    availabilities = event.availabilities
    utcBestTime = findBestTime(event, availabilities)

    event.isPolling = False
    event.bestTime = utcBestTime
    db.session.commit()

    for person in group.people:
        if person.status == 'Active':
            localBestTime = localtime(utcBestTime, pytz.timezone(person.timezone))
            send_event_result(person, event, localBestTime)

Once an event is finalized, this method sends out the results to all group members, ensuring that everyone knows the best time to meet.

Scaling for Success

One of the greatest challenges during this project was ensuring that HangoutHabit could scale quickly to meet user demand. When we launched on Hacker News and saw nearly 1,000 users sign up, it was a true stress test for our system’s architecture.

By using Docker, we ensured that the application was deployable across different environments without issue. The containerization kept our development, testing, and production environments consistent, reducing deployment headaches and making it easier to scale the application.

Conclusion: An SDLC Stress Test

Building HangoutHabit was an incredible experience that tested every stage of the software development lifecycle (SDLC). From rapid prototyping to handling user feedback, scaling for hundreds of users, and pitching to Y Combinator, this project forced us to think about every aspect of software design.

While we ultimately didn’t get into Y Combinator, the experience was invaluable. It showed us how to build with scale in mind, iterate quickly based on real feedback, and deliver a robust, user-friendly product. HangoutHabit taught us the importance of finding a niche, and it gave us a solid foundation for future projects.