# Money Forward + Vertex AI ๊ตฌํ˜„ ์š”์•ฝ ## ๐Ÿ“… ํ”„๋กœ์ ํŠธ ์ •๋ณด - **๋‚ ์งœ**: 2025-11-30 - **ํ”„๋กœ์ ํŠธ**: Money Forward Business API + Vertex AI ์žฌ๋ฌด ๋ถ„์„ ๋„๊ตฌ - **๊ธฐ์ˆ  ์Šคํƒ**: TypeScript, pnpm, axios, Vertex AI (Gemini 1.5 Flash) ## ๐ŸŽฏ ๊ตฌํ˜„ ์™„๋ฃŒ ์‚ฌํ•ญ ### 1. OAuth 2.0 ์ธ์ฆ (v4) โœ… **์„ฑ๊ณตํ•œ ๊ตฌํ˜„**: - Money Forward Business API OAuth 2.0 ์ธ์ฆ - CLIENT_SECRET_BASIC ์ธ์ฆ ๋ฐฉ์‹ - Authorization Code Grant ํ”Œ๋กœ์šฐ - Access Token ์ž๋™ ๊ฐฑ์‹  - ํ† ํฐ ํŒŒ์ผ ์ €์žฅ (`.tokens/mf-tokens.json`) **ํ•ต์‹ฌ URL**: - Authorization: `https://api.biz.moneyforward.com/authorize` - Token: `https://api.biz.moneyforward.com/token` - Scope: `mfc/admin/tenant.read` **๋ฐœ๊ธ‰๋œ ํ† ํฐ**: ```json { "access_token": "vpKqn9E_9B6yk3ykDDTbp7Gp1ii5da1JfCUI2hPozvc", "refresh_token": "zPaqXGDYDo-NYT3OWEKNNCxtL34H7M4q2zIhNpD-ulE", "token_type": "Bearer", "expires_in": 3600 } ``` ### 2. Money Forward API ํด๋ผ์ด์–ธํŠธ (v5) โœ… **์กฐํšŒ ๊ฐ€๋Šฅํ•œ ๋ฐ์ดํ„ฐ**: - Tenant ์ •๋ณด: `GET /v2/tenant` - tenant_code: "1911-2783" - tenant_name: "ๆ ชๅผไผš็คพPlanitAI" โŒ **์ œํ•œ์‚ฌํ•ญ**: - ํ˜„์žฌ scope๋กœ๋Š” tenant ์ •๋ณด๋งŒ ์กฐํšŒ ๊ฐ€๋Šฅ - ๊ฑฐ๋ž˜ ๋‚ด์—ญ, ๊ณ„์ •, ํŒŒํŠธ๋„ˆ ๋ฐ์ดํ„ฐ๋Š” ์ถ”๊ฐ€ scope ํ•„์š” **๊ตฌํ˜„ ํŒŒ์ผ**: - `src/moneyforward/client.ts` - API ํด๋ผ์ด์–ธํŠธ - `src/cli-test-api.ts` - ํ…Œ์ŠคํŠธ CLI ### 3. Vertex AI ํด๋ผ์ด์–ธํŠธ (v6-v7) โœ… **๊ตฌํ˜„ ์™„๋ฃŒ**: - Gemini 1.5 Flash ๋ชจ๋ธ ์—ฐ๋™ - ์žฌ๋ฌด ๋ถ„์„ ํ”„๋กฌํ”„ํŠธ ์—”์ง„ - ๊ตฌ์กฐํ™”๋œ ์‘๋‹ต ํŒŒ์‹ฑ (์š”์•ฝ/์ธ์‚ฌ์ดํŠธ/๊ถŒ์žฅ์‚ฌํ•ญ) **๊ตฌํ˜„ ํŒŒ์ผ**: - `src/vertexai/client.ts` โธ๏ธ **Google Cloud ์„ค์ • ํ•„์š”**: - ํ”„๋กœ์ ํŠธ ID ์„ค์ • - Vertex AI API ํ™œ์„ฑํ™” - ์„œ๋น„์Šค ๊ณ„์ • ํ‚ค ์ƒ์„ฑ ### 4. ํ†ตํ•ฉ ์‹œ์Šคํ…œ (v8-v9) โœ… **๊ตฌํ˜„ ์™„๋ฃŒ**: - Money Forward + Vertex AI ์™„์ „ ํ†ตํ•ฉ - ์ปฌ๋Ÿฌํ’€ํ•œ CLI ์ธํ„ฐํŽ˜์ด์Šค (chalk) - ์—๋Ÿฌ ํ•ธ๋“ค๋ง **๋ฉ”์ธ ํŒŒ์ผ**: - `src/index.ts` ## ๐Ÿ”ง ์ฃผ์š” ํŠธ๋Ÿฌ๋ธ”์ŠˆํŒ… ### ๋ฌธ์ œ 1: ํด๋ผ์ด์–ธํŠธ ์ธ์ฆ ์‹คํŒจ **์—๋Ÿฌ**: "ใ‚ฏใƒฉใ‚คใ‚ขใƒณใƒˆ่ช่จผใฏๅคฑๆ•—ใ—ใพใ—ใŸ" **์›์ธ**: CLIENT_SECRET_POST๋ฅผ ์‚ฌ์šฉํ–ˆ์œผ๋‚˜ Business API๋Š” CLIENT_SECRET_BASIC ํ•„์š” **ํ•ด๊ฒฐ**: ```typescript // Authorization ํ—ค๋”์— Base64 ์ธ์ฝ”๋”ฉ๋œ credentials ์ „์†ก const credentials = Buffer.from(`${clientId}:${clientSecret}`).toString('base64'); headers: { 'Authorization': `Basic ${credentials}` } ``` ### ๋ฌธ์ œ 2: axios JSON ๋ณ€ํ™˜ **์›์ธ**: axios๊ฐ€ ๊ฐ์ฒด๋ฅผ ์ž๋™์œผ๋กœ JSON์œผ๋กœ ๋ณ€ํ™˜ **ํ•ด๊ฒฐ**: URLSearchParams ์‚ฌ์šฉ ```typescript const params = new URLSearchParams(); params.append('code', code); params.append('grant_type', 'authorization_code'); await axios.post(url, params); // form-urlencoded๋กœ ์ „์†ก ``` ### ๋ฌธ์ œ 3: Scope ๋ฌดํšจ **์—๋Ÿฌ**: "scopeใƒ‘ใƒฉใƒกใƒผใ‚ฟใŒ่จญๅฎšใ•ใ‚Œใฆใ„ใชใ„ใ‹็„กๅŠนใงใ™" **์›์ธ**: Personal API scope ํ˜•์‹ ์‚ฌ์šฉ **ํ•ด๊ฒฐ**: Business API scope ํ˜•์‹ (`mfc/admin/tenant.read`) ### ๋ฌธ์ œ 4: State ํŒŒ๋ผ๋ฏธํ„ฐ ๋ˆ„๋ฝ **์›์ธ**: Business API๋Š” state ํ•„์ˆ˜ **ํ•ด๊ฒฐ**: ```typescript const state = Math.random().toString(36).substring(2, 15); ``` ### ๋ฌธ์ œ 5: SSH ํฌํŠธ ํฌ์›Œ๋”ฉ **์›์ธ**: ์›๊ฒฉ ์„œ๋ฒ„์˜ OAuth callback์„ ๋กœ์ปฌ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ฒ˜๋ฆฌ ํ•„์š” **ํ•ด๊ฒฐ**: ```bash ssh -L 3000:localhost:3000 user@server.com ``` ## ๐Ÿ“Š API vs ์‹ค์ œ ๊ตฌํ˜„ ๋น„๊ต | ํ•ญ๋ชฉ | ์›๋ž˜ ๊ณ„ํš (ME API) | ์‹ค์ œ ๊ตฌํ˜„ (Business API) | |------|-------------------|------------------------| | Base URL | `moneyforward.com` | `api.biz.moneyforward.com` | | Authorization | `/oauth/authorize` | `/authorize` | | Token | `/oauth/v2/token` | `/token` | | Scope | `accounts transactions` | `mfc/admin/tenant.read` | | ์ธ์ฆ ๋ฐฉ์‹ | CLIENT_SECRET_POST | CLIENT_SECRET_BASIC | | State | ์„ ํƒ | **ํ•„์ˆ˜** | | ๋ฐ์ดํ„ฐ | ๊ฐœ์ธ ๊ฑฐ๋ž˜ ๋‚ด์—ญ | ์‚ฌ์—…์ฒด ์ •๋ณด | ## ๐Ÿš€ ์‹คํ–‰ ๋ช…๋ น์–ด ```bash # 1. OAuth ์ธ์ฆ pnpm run auth # 2. API ํ…Œ์ŠคํŠธ pnpm run test:api # 3. AI ๋ถ„์„ (Google Cloud ์„ค์ • ํ›„) pnpm run analyze ``` ## ๐Ÿ“ ์ฃผ์š” ํŒŒ์ผ ๊ตฌ์กฐ ``` src/ โ”œโ”€โ”€ moneyforward/ โ”‚ โ”œโ”€โ”€ auth.ts # OAuth ์ธ์ฆ ๋กœ์ง โ”‚ โ”œโ”€โ”€ client.ts # API ํด๋ผ์ด์–ธํŠธ โ”‚ โ””โ”€โ”€ oauth-server.ts # Callback ์„œ๋ฒ„ โ”œโ”€โ”€ vertexai/ โ”‚ โ””โ”€โ”€ client.ts # Vertex AI ํด๋ผ์ด์–ธํŠธ โ”œโ”€โ”€ types/ โ”‚ โ””โ”€โ”€ index.ts # TypeScript ํƒ€์ž… โ”œโ”€โ”€ cli-auth.ts # OAuth CLI โ”œโ”€โ”€ cli-test-api.ts # API ํ…Œ์ŠคํŠธ CLI โ””โ”€โ”€ index.ts # ํ†ตํ•ฉ ๋ฉ”์ธ ์Šคํฌ๋ฆฝํŠธ ``` ## ๐Ÿ”— ์ฐธ๊ณ  ๋ฌธ์„œ ### Money Forward Business API - App Portal: https://app-portal.moneyforward.com/apps/ - Developers Guide: https://developers.biz.moneyforward.com/ - GitHub (Expense API): https://github.com/moneyforward/expense-api-doc ### Vertex AI - Vertex AI ๋ฌธ์„œ: https://cloud.google.com/vertex-ai/docs - Gemini API: https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/gemini ### OAuth 2.0 - RFC 6749: https://datatracker.ietf.org/doc/html/rfc6749 - OAuth 2.0 ๊ฐ€์ด๋“œ: https://oauth.net/2/ ## ๐Ÿ“ˆ ๋‹ค์Œ ๋‹จ๊ณ„ ### ๋‹จ๊ธฐ (๊ธฐ๋Šฅ ํ™•์žฅ) 1. โœ… Tenant ์ •๋ณด ์กฐํšŒ 2. โธ๏ธ ์ถ”๊ฐ€ scope ์„ค์ • (deal:read, account_item:read ๋“ฑ) 3. โธ๏ธ ๊ฑฐ๋ž˜ ๋‚ด์—ญ ์กฐํšŒ ๊ตฌํ˜„ 4. โธ๏ธ ๋” ์ƒ์„ธํ•œ AI ๋ถ„์„ ํ”„๋กฌํ”„ํŠธ ### ์ค‘๊ธฐ (Google Cloud ์„ค์ •) 1. โธ๏ธ Google Cloud ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ 2. โธ๏ธ Vertex AI API ํ™œ์„ฑํ™” 3. โธ๏ธ ์„œ๋น„์Šค ๊ณ„์ • ํ‚ค ์ƒ์„ฑ 4. โธ๏ธ .env ํŒŒ์ผ ์—…๋ฐ์ดํŠธ ### ์žฅ๊ธฐ (ํ”„๋กœ๋•์…˜) 1. โธ๏ธ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํ† ํฐ ์ €์žฅ 2. โธ๏ธ ์›น ๋Œ€์‹œ๋ณด๋“œ ๊ตฌํ˜„ 3. โธ๏ธ ์ •๊ธฐ ๋ถ„์„ ์Šค์ผ€์ค„๋ง 4. โธ๏ธ ๋ฆฌํฌํŠธ ์ด๋ฉ”์ผ ๋ฐœ์†ก ## ๐Ÿ’ก ํ•ต์‹ฌ ํ•™์Šต ๋‚ด์šฉ ### Business API์˜ ํŠน์ง• 1. Personal API์™€ ์™„์ „ํžˆ ๋‹ค๋ฅธ URL ์ฒด๊ณ„ 2. Scope ํ˜•์‹์ด ๋‹ค๋ฆ„ (`mfc/` prefix) 3. CLIENT_SECRET_BASIC ์ธ์ฆ ํ•„์ˆ˜ 4. State ํŒŒ๋ผ๋ฏธํ„ฐ ํ•„์ˆ˜ 5. ์„œ๋น„์Šค๋ณ„๋กœ ๋‹ค๋ฅธ Base URL (Expense, Invoice ๋“ฑ) ### OAuth ๊ตฌํ˜„ ์‹œ ์ฃผ์˜์‚ฌํ•ญ 1. URLSearchParams๋กœ form-urlencoded ๋ณด์žฅ 2. Authorization ํ—ค๋”๋กœ Basic ์ธ์ฆ ์ „๋‹ฌ 3. State ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ CSRF ๋ฐฉ์ง€ 4. SSH ํฌํŠธ ํฌ์›Œ๋”ฉ์œผ๋กœ ๋กœ์ปฌ ํ…Œ์ŠคํŠธ ### Vertex AI ํ†ตํ•ฉ 1. ํ”„๋กฌํ”„ํŠธ ์—”์ง€๋‹ˆ์–ด๋ง์˜ ์ค‘์š”์„ฑ 2. ๊ตฌ์กฐํ™”๋œ ์‘๋‹ต ํŒŒ์‹ฑ 3. ์—๋Ÿฌ ํ•ธ๋“ค๋ง ๋ฐ ์žฌ์‹œ๋„ ๋กœ์ง ## โœ… ํ…Œ์ŠคํŠธ ๊ฒฐ๊ณผ ### OAuth ์ธ์ฆ - โœ… Authorization URL ์ƒ์„ฑ - โœ… ๋ธŒ๋ผ์šฐ์ € ์ธ์ฆ ํ”Œ๋กœ์šฐ - โœ… Authorization Code ์ˆ˜์‹  - โœ… Access Token ๋ฐœ๊ธ‰ - โœ… Refresh Token ์ €์žฅ - โœ… ์ž๋™ ํ† ํฐ ๊ฐฑ์‹  ### API ํ˜ธ์ถœ - โœ… Tenant ์ •๋ณด ์กฐํšŒ ์„ฑ๊ณต - โœ… Bearer Token ์ธ์ฆ ์ •์ƒ ์ž‘๋™ - โŒ ๋‹ค๋ฅธ ์—”๋“œํฌ์ธํŠธ (scope ์ œํ•œ) ### Vertex AI - โœ… ํด๋ผ์ด์–ธํŠธ ์ดˆ๊ธฐํ™” - โœ… ํ”„๋กฌํ”„ํŠธ ์ƒ์„ฑ - โธ๏ธ API ํ˜ธ์ถœ (Google Cloud ์„ค์ • ํ•„์š”) ## ๐Ÿ“ ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ```.env # Money Forward Business API MONEYFORWARD_CLIENT_ID=189577719042326 MONEYFORWARD_CLIENT_SECRET=QViocLCAx0m1oQvwCT9iuL8qbxIaQPTKwhhIjMgVIWMVG2x7SRmvY1rLZl49krTTztGluW_oQZ8HMmd5HfebIg MONEYFORWARD_REDIRECT_URI=http://localhost:3000/callback # Google Cloud Vertex AI (์„ค์ • ํ•„์š”) GOOGLE_CLOUD_PROJECT=์‹ค์ œ-ํ”„๋กœ์ ํŠธ-ID GOOGLE_APPLICATION_CREDENTIALS=./service-account-key.json VERTEX_AI_LOCATION=us-central1 VERTEX_AI_MODEL=gemini-1.5-flash ``` --- **์ž‘์„ฑ์ผ**: 2025-11-30 **์ž‘์„ฑ์ž**: Claude + User **ํ”„๋กœ์ ํŠธ ์ƒํƒœ**: OAuth ์ธ์ฆ ์™„๋ฃŒ, API ํด๋ผ์ด์–ธํŠธ ๊ตฌํ˜„ ์™„๋ฃŒ, Vertex AI ํ†ตํ•ฉ ์™„๋ฃŒ