Webhook & REST API Reference v0.0.7
FinLog 커스텀 동기화 API 가이드
FinLog은 중앙 서버가 없는 100% 온디바이스 가계부입니다.
내가 소유한 구글 시트, NAS, 홈서버로 금융 알림 내역을 실시간 수신하여 자유롭게 분석하고 영구 보관하세요.
Step 0
JSON 데이터 규격
포맷 및 필드 스키마
Track 1
구글 스프레드시트
서버 없이 엑셀 자동 누적
Track 2
개인 백엔드 서버
Express / FastAPI / Flask
Quick Test
cURL 검증 명령
1초 즉시 테스트
0
FinLog 송신 데이터 규격 (JSON Payload)
앱에서 지정한 웹훅/서버 URL로 발송되는 HTTP POST 요청 사양입니다.
Method: POST
Content-Type: application/json
Auth Header: Bearer <Token>
전송 JSON 바디 (Payload Example)
v0.0.7 schema
{
"app": "FinLog",
"version": "0.0.7",
"syncedAt": "2026-09-14T15:00:00.000Z",
"sheetName": "FinLog_Sheet",
"transactions": [
{
"id": "tx_1726300000_abc",
"sourceType": "NOTIFICATION", // "NOTIFICATION" | "SMS" | "MANUAL"
"sourceApp": "com.kakaobank.channel",
"bankName": "카카오뱅크",
"amount": 15000,
"type": "EXPENSE", // "EXPENSE"(지출) | "INCOME"(수입) | "TRANSFER"(이체)
"merchant": "스타벅스 강남점",
"category": "카페/간식",
"memo": "아메리카노 결제",
"balance": 245000, // 통장 잔액 (알림에 잔액이 포함된 경우)
"rawText": "[카카오뱅크] 체크카드 승인 15,000원 스타벅스 강남점",
"timestamp": "2026-09-14T15:00:00.000Z"
}
],
"detectionLogs": [
{
"id": "audit_1726300010_xyz",
"transactionId": "tx_1726300000_abc",
"timestamp": "2026-09-14T15:05:00.000Z",
"fieldName": "category",
"oldValue": "기타",
"newValue": "카페/간식",
"reason": "사용자 카테고리 수동 수정"
}
]
}
📋 필드 세부 명세서
| 필드명 | 타입 | 필수 | 설명 |
|---|---|---|---|
| app | string | 필수 | 앱 식별자 (고정값 "FinLog") |
| version | string | 필수 | 데이터를 보낸 FinLog 앱 버전 (예: "0.0.7") |
| syncedAt | string (ISO 8601) | 필수 | 동기화 전송 시각 UTC (예: "2026-09-14T15:00:00.000Z") |
| sheetName | string | 선택 | 구글 시트 연동 시 타겟 시트명 (기본: "FinLog_Sheet") |
| transactions | Array<object> | 필수 | 발생한 금융 거래 데이터 목록 배열 |
| detectionLogs | Array<object> | 선택 | 사용자가 가계부 내역을 수정하거나 변경한 내역 감사(Audit) 로그 |
transactions 배열 내부 객체 필드
| 필드명 | 타입 | 값 범위 / 예시 | 설명 |
|---|---|---|---|
| id | string | tx_1726300000_abc | 거래 고유 식별자 |
| sourceType | string | NOTIFICATION | SMS | MANUAL | 수집 경로 (푸시 알림 / 문자 / 직접 입력) |
| bankName | string | 카카오뱅크, 국민카드, 토스 등 | 금융기관 및 카드사 이름 |
| amount | number | 15000 | 거래 금액 (원화 기준 양수) |
| type | string | EXPENSE | INCOME | TRANSFER | 거래 구분 (지출 / 수입 / 이체) |
| merchant | string | 스타벅스 강남점 | 가맹점 상호명 또는 결제처 |
| category | string | 식비, 카페/간식, 교통, 쇼핑 등 | 자동 분류된 소비 카테고리 |
| balance | number? | 245000 (없으면 null) | 거래 후 통장 잔액 (알림에 잔액 표기 시) |
| rawText | string | [카카오뱅크] 체크카드 승인... | 기기에서 파싱한 원본 메시지 텍스트 |
| timestamp | string (ISO) | 2026-09-14T15:00:00.000Z | 결제 및 거래가 일어난 시각 |
1
트랙 1 · 가장 간편한 방법
구글 스프레드시트 (Apps Script Webhook)
별도의 백엔드 서버나 데이터베이스 구축 없이 구글 드라이브 엑셀 시트에 금융 내역을 실시간 행(Row)으로 자동 누적할 때 사용합니다.
💡 장점
100% 무료, 24시간 서버 유지보수 불필요, PC 구글 시트에서 엑셀 수식(SUM, 피벗테이블, 차트) 즉시 연동
🔗 연결 방식
구글 스프레드시트 > 확장 프로그램 > Apps Script > 웹 앱(Web App) 배포 URL을 FinLog에 입력
구글 Apps Script 배포 코드 (Code.gs)
// [구글 Apps Script 코드]
function doPost(e) {
try {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
// 1. 첫 행이 비어있으면 엑셀 헤더 자동 생성
if (sheet.getLastRow() === 0) {
sheet.appendRow(['기록일시', '금융기관', '구분', '금액', '가맹점/상호', '카테고리', '잔액', '메모', '원본메시지']);
sheet.getRange(1, 1, 1, 9)
.setBackground('#1e293b')
.setFontColor('#ffffff')
.setFontWeight('bold');
sheet.setFrozenRows(1);
}
// 2. FinLog 앱에서 보낸 데이터 파싱
var postData = JSON.parse(e.postData.contents);
var transactions = postData.transactions || [];
// 단일 전송 및 다건 전송 모두 수용
if (postData.transaction) transactions = [postData.transaction];
// 3. 시트에 한 줄씩 추가
transactions.forEach(function(tx) {
var typeText = tx.type === 'EXPENSE' ? '지출' : (tx.type === 'INCOME' ? '수입' : '이체');
sheet.appendRow([
tx.timestamp || new Date().toLocaleString(),
tx.bankName || '기타금융',
typeText,
tx.amount || 0,
tx.merchant || '',
tx.category || '기타',
tx.balance || '',
tx.memo || '',
tx.rawText || ''
]);
});
return ContentService.createTextOutput(JSON.stringify({ status: "success", count: transactions.length }))
.setMimeType(ContentService.MimeType.JSON);
} catch (err) {
return ContentService.createTextOutput(JSON.stringify({ status: "error", message: err.toString() }))
.setMimeType(ContentService.MimeType.JSON);
}
}
// 연결 테스트용 (Ping)
function doGet(e) {
return ContentService.createTextOutput(JSON.stringify({ status: "ok", service: "FinLog Google Sheets Webhook" }))
.setMimeType(ContentService.MimeType.JSON);
}
🛠️ 배포 및 연동 3단계 가이드
- 새 구글 스프레드시트 생성 후 상단 메뉴에서 확장 프로그램 > Apps Script 클릭
- 기존 코드를 지우고 위 코드를 붙여넣은 뒤 저장 (
Ctrl + S) - 우측 상단 배포 > 새 배포 선택:
- 유형: 웹 앱(Web App)
- 다음 사용자로 실행: 나(내 계정)
- 액세스 권한: 모든 사용자(Anyone) *필수
- 생성된
https://script.google.com/macros/s/.../execURL을 FinLog 앱 웹훅 주소에 붙여넣기
2
트랙 2 · 개인 홈서버 / NAS / 클라우드
백엔드 서버 구현 예제
Synology NAS(Docker), 오라클/AWS 클라우드 VPS, 개인 홈서버 등 선호하는 백엔드 환경에 맞추어 선택하여 구축할 수 있습니다.
포트: 8080 · Bearer Token 인증 및 JSONL 파일 누적 저장
server.js
// server.js
const express = require('express');
const cors = require('cors');
const fs = require('fs');
const app = express();
const PORT = 8080;
const AUTH_TOKEN = "my-secret-token"; // 앱의 [인증 토큰] 칸과 일치시킴
app.use(cors());
app.use(express.json());
// 1. Health Check (앱의 "연결 테스트 (Ping)" 버튼이 호출)
app.get('/api/v1/finlog/health', (req, res) => {
const auth = req.headers['authorization'];
if (AUTH_TOKEN && auth !== `Bearer ${AUTH_TOKEN}`) {
return res.status(401).json({ error: '인증 실패' });
}
res.json({ status: 'ok', serverTime: new Date().toISOString() });
});
// 2. 로그 수신 엔드포인트 (앱의 "지금 전체 로그 전송" 및 자동 동기화가 호출)
app.post('/api/v1/finlog/logs', (req, res) => {
const auth = req.headers['authorization'];
if (AUTH_TOKEN && auth !== `Bearer ${AUTH_TOKEN}`) {
return res.status(401).json({ error: '인증 실패' });
}
const { app: appName, version, transactions, detectionLogs, syncedAt } = req.body;
console.log(`[${syncedAt}] 거래 ${transactions?.length || 0}건, 수정로그 ${detectionLogs?.length || 0}건 수신`);
// 로컬 파일 (JSONL) 또는 MariaDB/PostgreSQL 등에 저장
const logLine = JSON.stringify(req.body) + '\n';
fs.appendFileSync('finlog_records.jsonl', logLine, 'utf8');
res.json({
success: true,
receivedTransactions: transactions?.length || 0,
receivedAuditLogs: detectionLogs?.length || 0
});
});
app.listen(PORT, '0.0.0.0', () => {
console.log(`FinLog Express 서버가 포트 ${PORT}에서 실행 중입니다.`);
});
npm init -y && npm install express cors && node server.js
3
개발자 로컬 테스트용
cURL 테스트 명령
서버를 실행한 뒤, FinLog 앱 없이 터미널(CMD / PowerShell / Bash)에서 서버가 올바르게 응답하는지 1초 만에 검증할 수 있습니다.
1) Health Check (Ping) 테스트
GET
curl -X GET http://localhost:8080/api/v1/finlog/health \
-H "Authorization: Bearer my-secret-token"
2) 가상 거래 데이터 전송 테스트
POST
curl -X POST http://localhost:8080/api/v1/finlog/logs \
-H "Content-Type: application/json" \
-H "Authorization: Bearer my-secret-token" \
-d '{
"app": "FinLog",
"version": "0.0.7",
"syncedAt": "2026-09-14T15:00:00Z",
"sheetName": "FinLog_Sheet",
"transactions": [
{
"id": "test_01",
"bankName": "테스트은행",
"type": "EXPENSE",
"amount": 10000,
"merchant": "테스트가맹점",
"category": "식비",
"timestamp": "2026-09-14T15:00:00Z",
"rawText": "테스트 결제 10,000원"
}
]
}'
💡
요약 및 권장 사항
FinLog 앱 내 [온라인 백업] 설정창에서 입력할 항목 매핑 가이드
권장 연동 방식 선택
- • 가장 간편한 방법: 별도 서버나 고정 IP가 없다면 트랙 1 (구글 스프레드시트)로 시작하는 것을 추천합니다.
- • 개인 NAS / 홈서버: Node.js 환경이면 Express, 파이썬 기반 데이터 분석(Pandas, AI 모델)을 원하시면 FastAPI를 추천합니다.
앱 설정 매핑 가이드
- 통신 프로토콜: http 또는 https
- 서버 주소: IP 또는 도메인 (예: 192.168.0.50 / mynas.me)
- 포트: 8080 (또는 설정한 포트)
- 엔드포인트: /api/v1/finlog/logs
- 인증 토큰: my-secret-token (서버 설정값과 일치)