카드 알림을 노션 가계부로 자동 기록하기 (1) — 왜 만들었고 어떻게 굴러가나
폰에 오는 카드·은행·페이 알림을 그대로 읽어 노션 가계부에 자동 기록하는 개인 프로젝트. 1편은 동기와 전체 구조, 그리고 유실 방지 설계.
📌 card2notion 시리즈 (1/3) — 폰 알림 → 노션 가계부 자동 기록. 이 편은 왜 만들었나 · 전체 구조 · 유실 방지 설계.
가계부를 손으로 쓰는 게 싫었다
돈을 쓸 때마다 폰에는 이미 알림이 온다. 카드 승인, 계좌 입출금, 카카오페이 정산… 근데 그걸 다시 손으로 가계부에 옮겨 적는 게 너무 귀찮았다. 며칠 밀리면 영수증 뒤지다가 포기.
그래서 만들었다. 폰 알림을 그대로 읽어 노션 가계부에 자동으로 한 줄씩 쌓는 시스템. 이름은 card2notion.
🔒 코드는 개인 저장소라 비공개다. 이 시리즈엔 핵심 조각만 발췌해 붙인다.
뱅크샐러드 놔두고 왜 직접 만들었나
사실 가계부 앱은 좋은 게 많다. 뱅크샐러드처럼 계좌·카드를 다 연결하면 알아서 긁어모아 분류까지 해주는 것도 있다. 나도 그거 쓰려고 깔았다.
근데 계좌 연동하고, 인증하고, 권한 이것저것 주다가… 귀찮아서 중간에 접었다. 결국 제대로 안 썼다.
웃긴 건, 직접 만드니까 오히려 안 접었다는 거다. 남이 만든 앱은 며칠 쓰다 안 보게 되는데, 내가 만든 건 자꾸 열어본다. 분류가 틀리면 고치고 싶고, 요약이 안 예쁘면 손보고 싶다. 애착이 생기니까 계속 쓴다.
가계부는 기능이 아무리 좋아도 계속 쓰게 되느냐가 전부다. 나한텐 “내가 만든 것”이 그 답이었다. 완벽하진 않아도 내 손에 맞으니까.
🛠️ 완성도보다 애착이 이긴다. 남의 완벽한 앱보다, 내가 만든 부족한 쪽을 결국 더 자주 열어보게 된다.
목표
- 카드/은행/페이 알림이 오면 → 노션 가계부 DB에 자동 기록
- 수입 / 지출 / 이체 / 정산 / 부채상환을 알아서 분류
- 월별 요약(순저축, 저축률, 카테고리별 지출)을 노션에서 바로 보기
- 서버 비용 0원. 집에 굴러다니는 PC로 자가호스팅.
준비물: 남는 PC, 안드로이드 스마트폰
- 아이폰은 애플 보안 특성 상 폰알림 파싱이 안된다ㅠㅠ
전체 구조
갤럭시 폰 알림
│ (Tasker가 알림 텍스트 캡처)
▼
Tasker → HTTP POST (알림 원문 + 앱 패키지명)
▼
FastAPI 웹훅 (집 PC · Docker · HTTPS)
│ 1. 노이즈/광고 필터
│ 2. 파싱 (금액·가맹점·유형)
│ 3. 자동 분류 (카테고리·성격)
▼
Notion 가계부 DB (한 줄 추가)
+
Notion Budget 페이지 (월간 요약 자동 갱신)
폰에서 Tasker가 알림을 잡아 우리 집 서버로 쏘고, 서버가 파싱·분류해서 노션에 적는다.
핵심 구현 1 — 파싱 전에 거른다
알림이라고 다 거래가 아니다. 광고도 오고 “이자 낼 날이에요” 같은 안내도 온다. 그래서 파싱 전에 단계별로 거른다. 제일 골치 아팠던 건 안내성 알림이었다. 안내 문구가 들어 있어도 “승인”·“완료”가 같이 있으면 실거래라 통과시켜야 한다.
REMINDER_MARKERS = ("예정", "안내", "납입일", "부족", "채워", "갚아야", "갚는 날")
COMPLETION_MARKERS = ("승인", "완료", "되었어요", "받았어요", "보냈어요")
# 안내 문구가 있어도 '승인/완료'가 같이 있으면 실거래 → 통과
if any(m in text for m in REMINDER_MARKERS) and not any(c in text for c in COMPLETION_MARKERS):
return {"status": "skipped", "reason": "reminder/notice"}
핵심 구현 2 — 유실은 절대 안 된다
돈 기록이라 한 건이라도 놓치면 안 된다. 그래서 노션 API가 실패해도 잃지 않게, 실패분은 큐에 쌓고 폰엔 “접수됨”으로 답한다. 그래야 폰이 재전송을 안 하고, 서버가 나중에 조용히 재시도한다.
try:
notion_client.add_transaction(item)
except Exception:
_queue_pending(item) # 실패분을 재시도 큐에 적재
_journal(item, "queued")
return {"status": "queued"} # 폰엔 '접수됨'으로 응답
여기에 3중 안전장치를 더 뒀다.
- journal — 받은 알림은 skip 사유까지 전부 기록. “이건 왜 안 들어왔지?“를 원문으로 추적.
- pending 큐 — 노션 실패분을 몇 분마다 재시도.
- 멱등 기록(seen) — 14일 윈도우. 같은 알림이 두 번 와도 중복 기록 안 함.
💡 돈 기록은 유실이 곧 신뢰 문제다. “실패하면 큐에 쌓고 폰엔 접수됨으로 답한다”가 이 프로젝트에서 제일 중요한 한 줄이었다. 이 journal이 나중에 파서 버그를 잡을 때도 그대로 생명줄이 됐다.
왜 이렇게 만들었나
왜 Tasker. 안드로이드는 알림 접근 권한만 주면 모든 앱의 알림 텍스트를 읽을 수 있다. 카드사 앱을 크롤링할 필요 없이, 이미 오는 알림을 재활용.
왜 자가호스팅. 개인 금융 데이터를 남의 클라우드에 안 올리고 싶었다. 집 PC + Docker면 충분. 컨테이너를 restart: unless-stopped로 띄워두면 컴퓨터를 껐다 켜도 도커만 올라오면 그대로 동작.
왜 노션. 이미 쓰고 있었고, DB·페이지·코드블록만으로 가계부 + 대시보드를 다 만들 수 있다. 앱을 따로 만들 이유가 없었다.
다음 편
구조 자체는 이렇게 단순한데, 진짜 지옥은 알림 텍스트 파싱이었다. 카드사마다, 은행마다, 페이마다 형식이 다 다르고, 같은 은행도 입금과 출금 문구가 다르다.
➡️ 2편 — 알림 텍스트 파싱의 지옥에서 계속.

댓글
익명 댓글입니다. 닉네임과 내용이 저장되며, 서로 존중하는 표현을 부탁드려요. 부적절하거나 광고성 댓글은 예고 없이 삭제될 수 있습니다.