fix: Email Routing MIME 파싱 개선 + 레거시 코드 정리

- Email Routing에서 수신한 이메일 파싱 수정
  - Quoted-Printable UTF-8 디코딩 함수 추가
  - HTML <br/> 태그를 줄바꿈으로 변환
  - SMS 키워드 위치 기반 본문 추출

- 레거시 코드 삭제
  - /api/bank-notification 엔드포인트 제거 (Email Routing으로 대체)
  - BANK_API_SECRET 관련 코드 및 문서 제거
  - DEPOSIT_AGENT_ID 제거 (Assistants API → 코드 직접 처리)

- CLI 테스트 클라이언트 개선
  - .env 파일 자동 로드 지원
  - WEBHOOK_SECRET 환경변수 불필요

- 문서 업데이트
  - NAMECHEAP_API_KEY 설명 명확화 (래퍼 인증 키)
  - CLI 테스트 섹션 추가

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
kappa
2026-01-18 13:12:26 +09:00
parent edbd790538
commit 89f8ea19f1
8 changed files with 156 additions and 215 deletions

114
README.md
View File

@@ -2,6 +2,9 @@
> Cloudflare Workers + D1 + OpenAI를 활용한 사용자 프로필 기반 텔레그램 봇
**📖 이 문서**: 기능 소개, 배포 가이드, 사용법 (사용자/운영자용)
**🔧 [CLAUDE.md](./CLAUDE.md)**: 기술 상세, 코드 패턴, 트러블슈팅 (개발자용)
## 목차
1. [개요](#개요)
@@ -26,8 +29,7 @@
- **Context7 연동**: 프로그래밍 라이브러리 공식 문서 실시간 조회
- **동적 도구 로딩**: 메시지 키워드 기반으로 필요한 도구만 선택하여 토큰 절약
- **도메인 추천**: GPT가 창의적 도메인 생성 → 가용성 자동 확인 → 가격과 함께 제안
- **Deposit Agent**: OpenAI Assistants API 기반 예치금 관리 에이전트 연동
- **예치금 시스템**: 은행 입금 자동 감지 + 사용자 신고 매칭으로 자동 충전
- **예치금 시스템**: 코드 직접 처리, 은행 입금 자동 감지 + 사용자 신고 매칭으로 자동 충전
- **Email Worker**: SMS → 메일 → 자동 파싱으로 입금 알림 처리
- **무한 컨텍스트**: 슬라이딩 윈도우(3개)로 프로필 유지, 무제한 대화 기억
- **개인화 응답**: 프로필 기반으로 맞춤형 AI 응답 제공
@@ -43,7 +45,7 @@
| **Context7** | 라이브러리 문서 조회 API |
| **도메인 관리** | 코드 직접 처리 → Namecheap API |
| **도메인 추천** | GPT + Namecheap API (코드 레벨) |
| **Deposit Agent** | 예치금 관리 (OpenAI Assistants) |
| **예치금 관리** | 코드 직접 처리 → D1 |
| **Namecheap API** | 도메인 조회/가용성/가격 백엔드 |
| **Email Workers** | SMS → 메일 파싱 (입금 알림) |
| **Workers AI** | 폴백용 (Llama 3.1 8B) |
@@ -148,7 +150,7 @@ OpenAI Function Calling을 통해 AI가 자동으로 필요한 도구를 호출
| **문서** | "React hooks 사용법", "OpenAI API 예제" | Context7 |
| **도메인** | "도메인 목록", "anvil.it.com 네임서버", ".com 가격", "google.com whois" | 코드 직접 처리 + WHOIS API |
| **도메인 추천** | "커피숍 도메인 추천해줘", "스타트업 도메인 아이디어" | GPT + Namecheap |
| **예치금** | "잔액 확인", "충전하고 싶어", "10000원 입금했어" | D1 + Email Worker |
| **예치금** | "잔액 확인", "충전하고 싶어", "10000원 입금했어" | 코드 직접 처리 |
### 동작 방식
@@ -168,6 +170,31 @@ OpenAI: 날씨 데이터를 자연어로 응답 생성
응답: "🌤 서울 날씨\n온도: 5°C\n습도: 45%..."
```
### 동적 도구 로딩
메시지 키워드를 분석하여 필요한 도구만 선택적으로 로딩합니다. (토큰 40% 절약)
| 카테고리 | 도구 | 감지 패턴 |
|----------|------|-----------|
| domain | manage_domain, suggest_domains | 도메인, 네임서버, whois, .com |
| deposit | manage_deposit | 입금, 충전, 잔액, 계좌 |
| weather | get_weather | 날씨, 기온, 비, 눈 |
| search | search_web, lookup_docs | 검색, 찾아, 뭐야, 가격 |
| utility | get_current_time, calculate | (항상 포함) |
패턴 매칭 없으면 전체 도구 사용 (폴백)
### AI Gateway
OpenAI API 호출을 Cloudflare AI Gateway를 통해 프록시하여 지역 제한을 우회합니다.
```
Gateway ID: telegram-bot
URL: gateway.ai.cloudflare.com/v1/{account_id}/telegram-bot/openai/...
```
**대시보드**: Cloudflare Dashboard → AI → AI Gateway → telegram-bot
---
## 예치금 시스템
@@ -202,7 +229,7 @@ OpenAI: 날씨 데이터를 자연어로 응답 생성
```
[시나리오 2: 은행 SMS가 먼저 도착]
은행 SMS → Gmail → Apps Script
은행 SMS → 메일 전달 → Cloudflare Email Routing → Worker (email handler)
┌──────────────────┐
@@ -280,57 +307,23 @@ OpenAI: 날씨 데이터를 자연어로 응답 생성
감사합니다! 🎉
```
### Gmail → Apps Script → Worker 연동
### Cloudflare Email Routing
SMS를 Gmail로 전달받아 Apps Script에서 Worker API를 호출합니다.
SMS를 메일로 전달받아 Worker에서 직접 처리합니다.
**흐름:**
```
은행 SMS → Gmail(deposit.anvil@gmail.com) → Apps Script (1분마다)
POST /api/bank-notification → DB 저장 → 자동 매칭
매칭 성공 → 사용자/관리자 Telegram 알림
은행 SMS → 메일 전달 → Cloudflare Email Routing → Worker (email handler)
SMS 파싱 → DB 저장 → 자동 매칭
매칭 성공 → 사용자/관리자 Telegram 알림
```
**Apps Script 코드:**
```javascript
function checkBankEmails() {
var threads = GmailApp.search('is:unread 입금', 0, 10);
for (var i = 0; i < threads.length; i++) {
var messages = threads[i].getMessages();
for (var j = 0; j < messages.length; j++) {
var message = messages[j];
if (!message.isUnread()) continue;
var messageId = message.getId();
var body = message.getPlainBody();
try {
UrlFetchApp.fetch(
'https://telegram-summary-bot.kappa-d8e.workers.dev/api/bank-notification',
{
method: 'POST',
contentType: 'application/json',
payload: JSON.stringify({
content: body,
messageId: messageId,
secret: 'BANK_API_SECRET 값'
})
}
);
} catch (e) {
console.log('Error: ' + e);
}
}
threads[i].markRead();
}
}
```
**트리거 설정:** 시간 기반 → 분 타이머 → 1분마다
**설정 방법:**
1. Cloudflare Dashboard → Email → Email Routing → Routes
2. 수신 주소 설정 (예: `deposit@your-domain.com`)
3. Worker로 라우팅: `telegram-summary-bot`
**지원 은행 SMS 패턴:**
- 하나은행 (Web발신): `[Web발신] 하나,01/16, 23:30 427******27104 입금5원 황병하`
@@ -540,14 +533,14 @@ wrangler secret put WEBHOOK_SECRET
# OpenAI API Key (필수)
wrangler secret put OPENAI_API_KEY
# 입금 알림 API Secret (Apps Script 연동용)
wrangler secret put BANK_API_SECRET
# Brave Search API Key
wrangler secret put BRAVE_API_KEY
# Deposit API Secret (namecheap-api 연동용)
wrangler secret put DEPOSIT_API_SECRET
# namecheap-api 래퍼 인증 키 (도메인 추천용)
wrangler secret put NAMECHEAP_API_KEY
```
### Vault 연동 (선택)
@@ -582,6 +575,19 @@ curl https://telegram-summary-bot.kappa-d8e.workers.dev/setup-webhook
curl https://telegram-summary-bot.kappa-d8e.workers.dev/webhook-info
```
### 6. CLI 테스트 (선택)
```bash
# .env 파일 생성 (최초 1회)
echo 'WEBHOOK_SECRET=...' > .env # Vault: secret/telegram-bot
# 대화형 모드
npm run chat
# 단일 메시지 모드
npm run chat "안녕"
```
---
## 보안 설정
@@ -680,7 +686,7 @@ database_id = "c285bb5b-888b-405d-b36f-475ae5aed20e"
| `/webhook-info` | GET | Webhook 상태 |
| `/setup-webhook` | GET | Webhook 설정 |
| `/webhook` | POST | Telegram Webhook |
| `/api/bank-notification` | POST | 입금 알림 API (Apps Script 연동) |
| `/api/bank-notification` | POST | 입금 알림 API (레거시, Email Routing으로 대체) |
| `/api/deposit/balance` | GET | 예치금 잔액 조회 (namecheap-api용) |
| `/api/deposit/deduct` | POST | 예치금 차감 (namecheap-api용) |