Skip to content

와이프를 위한 강사 수입 관리 시스템 만들기

와이프를 위한 강사 수입 관리 시스템 만들기




TL;DR

  • 문제: 온라인 교육 플랫폼의 대시보드가 빈약해서 일일 수입 파악이 어려웠음
  • 해결: Gmail + Google Calendar API를 연동하여 수입 자동 계산 시스템 구축
  • 효과: 매일 밤 자동으로 수입 요약 메일 발송, 통화별 환율 변환까지 지원
  • 기술: Spring Boot, Gmail IMAP, Google Calendar API, Supabase, GCP Cloud Run
  • 한계: 특정 플랫폼의 메일 형식에 의존적, 형식 변경 시 파싱 로직 수정 필요




글 머리말

아내가 외국인을 대상으로 한국어를 가르치는 온라인 강사로 활동하고 있습니다.

어느 날 저녁, 아내가 불만을 토로했습니다.

“이 플랫폼 대시보드가 너무 불편해. 오늘 수업이 몇 개였는지, 수입이 얼마인지 한눈에 안 보여.”

사실 그 플랫폼은 수업 예약이나 취소 알림 메일은 잘 보내주는데, 정작 일일 수입 현황을 보여주는 대시보드는 빈약했습니다. 여러 통화로 결제가 들어오기도 해서 환율 계산까지 해야 하는 상황이었고요.

그날 밤 침대에 누워서 생각했습니다. “Gmail에 메일은 다 오는데, 이걸 자동으로 긁어서 정리해주면 되지 않을까?”

그래서 만들었습니다. 개발자에겐 불편함이 곧 사이드 프로젝트의 시작이니까요.





어떤 문제를 해결하려 했나

아내가 겪던 불편함을 정리하면 이렇습니다.

  1. 흩어진 정보: 수업 예약 메일, 취소 보상 메일, 캘린더 일정이 각각 따로 존재
  2. 수동 계산: 하루에 수업이 5개면, 메일 5개를 일일이 열어서 금액을 더해야 함
  3. 환율 변환: USD, EUR 등 다양한 통화로 결제가 들어오는데 KRW로 환산이 필요
  4. 플랫폼 수수료: 플랫폼이 18% 수수료를 가져가는데, 순수익 계산이 번거로움

매일 저녁 휴대폰 메모장에 금액을 적어가며 계산하는 아내를 보면서, 이건 자동화하면 되겠다 싶었습니다.





설계 논의

기술 선택

여러 선택지를 고민했습니다.

방식장점단점선택
스프레드시트 + Apps Script간단함확장성 낮음, 디버깅 어려움-
Python 스크립트빠른 개발서버 운영 필요, 익숙하지 않음-
Spring Boot익숙함, 확장 가능오버엔지니어링?

솔직히 Python으로 하면 더 빨랐을 수도 있습니다. 하지만 저는 Java/Spring이 훨씬 익숙하고, 나중에 기능 추가할 일이 생기면 Spring이 더 편할 것 같았습니다.

그리고 사이드 프로젝트라도 내가 편한 기술로 하는 게 지속 가능성이 높다는 걸 경험상 알고 있거든요.


시스템 구조

graph TB
    subgraph 데이터수집["데이터 수집"]
        Gmail["Gmail IMAP"]
        Calendar["Google Calendar"]
    end
    
    subgraph 처리["데이터 처리"]
        Parser["메일 파서"]
        Matcher["일정 매칭"]
        FX["환율 조회"]
    end
    
    subgraph 저장["저장소"]
        Supabase["Supabase<br/>(PostgreSQL)"]
    end
    
    subgraph 출력["결과"]
        Email["수입 요약 메일"]
    end
    
    Gmail --> Parser
    Parser --> Supabase
    Supabase --> Matcher
    Calendar --> Matcher
    FX --> Matcher
    Matcher --> Email
    
    style Gmail fill:#e8f5e9
    style Calendar fill:#e3f2fd
    style Supabase fill:#fff3e0
    style Email fill:#fce4ec

흐름을 간단히 설명하면:

  1. Gmail에서 예약/취소 보상 메일을 읽어서 파싱
  2. Supabase에 학생별 단가 정보 저장 (캐시)
  3. Google Calendar에서 당일 수업 일정 조회
  4. 학생별 단가와 일정을 매칭하여 수입 계산
  5. 환율 적용 후 KRW 총합 계산
  6. 결과를 이메일로 발송




핵심 구현

Gmail 메일 파싱

플랫폼에서 보내는 예약 메일에는 학생 이름, 수업료, 통화 정보가 포함되어 있습니다. 정규식으로 이 정보를 추출했습니다.

public ParsedMail parseBookingMail(Message message) {
    String body = getTextFromMessage(message);
    
    // 학생 이름 추출: "Lesson with [이름]"
    Matcher nameMatcher = Pattern.compile("Lesson with (.+)")
        .matcher(body);
    
    // 금액 추출: "$15.00" 또는 "€12.50"
    Matcher amountMatcher = Pattern.compile("([€$])(\\d+\\.\\d{2})")
        .matcher(body);
    
    // 수업 날짜 추출
    Matcher dateMatcher = Pattern.compile("on (\\w+ \\d+, \\d{4})")
        .matcher(body);
    
    // ... 파싱 로직
    return new ParsedMail(studentName, amount, currency, lessonDate);
}

사실 이 부분이 가장 취약합니다. 플랫폼이 메일 형식을 바꾸면 파싱이 깨지거든요. 하지만 지금까지 2년 넘게 형식이 바뀐 적은 없어서 일단은 괜찮습니다.


Google Calendar 연동

당일 수업 일정을 조회하는 부분입니다. 서비스 계정을 사용해서 Calendar API를 호출합니다.

public List<Event> getTodayLessons() {
    DateTime startOfDay = new DateTime(
        LocalDate.now().atStartOfDay(zoneId).toInstant().toEpochMilli());
    DateTime endOfDay = new DateTime(
        LocalDate.now().plusDays(1).atStartOfDay(zoneId).toInstant().toEpochMilli());
    
    Events events = calendar.events().list(calendarId)
        .setTimeMin(startOfDay)
        .setTimeMax(endOfDay)
        .setSingleEvents(true)
        .execute();
    
    return events.getItems().stream()
        .filter(e -> e.getSummary().endsWith(" - Preply lesson"))  // 플랫폼 접미사로 필터
        .toList();
}

캘린더 이벤트 제목에서 학생 이름을 추출하고, Gmail에서 파싱한 단가 정보와 매칭합니다.


Supabase 캐싱

매번 Gmail IMAP을 호출하면 느리고, API 호출 제한에 걸릴 수도 있습니다. 그래서 한 번 파싱한 메일 정보는 Supabase에 저장해둡니다.

create table preply_mail (
  student_full_name text not null,
  lesson_date date not null,
  amount numeric not null,
  currency text,
  received_at timestamptz not null,
  kind text check (kind in ('booking','cancellation_compensation')),
  primary key (student_full_name, lesson_date)
);

(학생이름, 수업날짜)를 복합키로 설정했습니다. 같은 학생이 여러 날짜에 수업을 가질 수 있으니까요.





실제 사용 결과

매일 밤 받는 수입 요약 메일

매일 오후 11시에 이런 메일이 자동으로 발송됩니다.

📊 2025-12-14 수입 현황

[수업 내역]
1. John (미국) - $25.00 × 82% = $20.50
2. Marie (프랑스) - €22.00 × 82% = €18.04
3. Tanaka (일본) - $25.00 × 82% = $20.50

[통화별 합계]
- USD: $41.00 (₩56,780)
- EUR: €18.04 (₩26,012)

[총 순수익]
₩82,792

아내 반응이 좋았습니다.

“오, 이거 편한데? 매일 이렇게 오는 거야?”


아내의 반응

솔직히 개발하면서 “이거 과하게 만드는 건가?” 싶기도 했습니다. 스프레드시트로 대충 해도 될 것을 Spring Boot로 만들고, Supabase까지 붙이고, GCP Cloud Run에 배포까지 했으니까요.

그런데 아내가 매일 저녁 수입 요약 메일을 보면서 “오늘은 얼마 벌었네~” 하고 기분 좋게 말하는 걸 보니, 만들길 잘했다 싶습니다.

개발자의 시간을 들여서 가족의 불편함을 해결하는 것. 이게 사이드 프로젝트의 가장 큰 보람 아닐까요.





운영 환경

  • 배포: GCP Cloud Run (서버리스, 사용한 만큼만 과금)
  • 스케줄러: Cloud Scheduler
    • 매일 09:00 KST: 최근 7일 메일 갱신
    • 매일 23:05 KST: 수입 요약 메일 발송
    • 주 1회: 6개월치 전체 메일 갱신
  • 비용: 월 $1~2 정도 (Cloud Run 무료 티어 범위)




비슷한 프로젝트를 고민한다면

체크리스트

  • 자동화할 데이터 소스가 API로 접근 가능한가? (Gmail, Calendar 등)
  • 파싱할 메일/데이터의 형식이 일정한가?
  • 한 번 만들면 오래 쓸 기능인가? (일시적 필요가 아닌지)
  • 내가 편한 기술 스택으로 만들 수 있는가?
  • 운영 비용이 감당 가능한가?

이런 분들께 도움이 될 수 있습니다

  • 온라인 플랫폼에서 프리랜서로 활동하는 가족이 있는 개발자
  • Gmail API + Google Calendar API 연동 경험이 필요한 분
  • 사이드 프로젝트로 가족의 불편함을 해결하고 싶은 분




결론

사실 이 프로젝트는 기술적으로 대단한 건 없습니다. Gmail IMAP 읽고, Calendar API 호출하고, 정규식으로 파싱하는 게 전부니까요.

하지만 저에게는 의미가 있었습니다. 매일 휴대폰 메모장에 적어가며 계산하던 아내가 이제는 메일 한 통으로 하루 수입을 확인합니다. 작은 불편함이었지만, 해결해주니 좋더라고요.

개발자로서 업무 중에 만드는 시스템도 중요하지만, 가끔은 내 주변 사람의 작은 불편함을 해결해주는 것도 좋은 경험입니다. 오히려 이런 프로젝트가 더 오래 기억에 남더라고요.

다음에는 기회가 되면 이 시스템에 월간 리포트 기능을 추가해볼까 합니다. 그래프도 예쁘게 넣어서요.





참고 :

Gmail API 공식 문서: https://developers.google.com/gmail/api
Google Calendar API 문서: https://developers.google.com/calendar/api
Supabase 공식 문서: https://supabase.com/docs




읽어주셔서 감사합니다.🖐


Ramsbaby
Written byRamsbaby
이 블로그는 직접 개발/운영하는 블로그이므로 당신을 불쾌하게 만드는 불필요한 광고가 없습니다.

#My Github#소개 페이지#Blog OpenSource Github#Blog OpenSource Demo Site