kappa 9822b28028 feat: Gmail → Apps Script → Worker 입금 알림 연동
- POST /api/bank-notification 엔드포인트 추가
- 하나은행 Web발신 SMS 패턴 파싱 지원
- Gmail message_id 기반 중복 방지
- BANK_API_SECRET 인증 추가
- deposit_transactions 자동 매칭 구현
- 문서 업데이트 (CLAUDE.md, README.md)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 00:09:16 +09:00

Cloudflare Workers 텔레그램 봇

Cloudflare Workers + D1 + OpenAI를 활용한 사용자 프로필 기반 텔레그램 봇

목차

  1. 개요
  2. 아키텍처
  3. Function Calling
  4. 예치금 시스템
  5. 도메인 관리
  6. 프로젝트 구조
  7. 배포 가이드
  8. 보안 설정
  9. 봇 명령어

개요

주요 기능

  • OpenAI GPT-4o-mini: 고품질 AI 응답 및 Function Calling 지원
  • 사용자 프로필: 대화에서 사용자의 관심사, 목표, 맥락을 추출하여 프로필 구축
  • Function Calling: 날씨, 검색, 시간, 계산, 문서 조회, 도메인 관리, 예치금 관리 등 AI가 자동으로 도구 호출
  • Context7 연동: 프로그래밍 라이브러리 공식 문서 실시간 조회
  • Domain Agent: OpenAI Assistants API 기반 도메인 관리 에이전트 연동
  • Deposit Agent: OpenAI Assistants API 기반 예치금 관리 에이전트 연동
  • 예치금 시스템: 은행 입금 자동 감지 + 사용자 신고 매칭으로 자동 충전
  • Email Worker: SMS → 메일 → 자동 파싱으로 입금 알림 처리
  • 무한 컨텍스트: 슬라이딩 윈도우(3개)로 프로필 유지, 무제한 대화 기억
  • 개인화 응답: 프로필 기반으로 맞춤형 AI 응답 제공
  • 폴백 지원: OpenAI 미설정 시 Workers AI(Llama)로 자동 전환

기술 스택

서비스 용도
Workers 서버리스 런타임
D1 SQLite 데이터베이스
OpenAI GPT-4o-mini + Function Calling
Context7 라이브러리 문서 조회 API
Domain Agent 도메인 관리 (OpenAI Assistants)
Deposit Agent 예치금 관리 (OpenAI Assistants)
Namecheap API 도메인 조회/관리 백엔드
Email Workers SMS → 메일 파싱 (입금 알림)
Workers AI 폴백용 (Llama 3.1 8B)

아키텍처

메시지 처리 흐름

[사용자 메시지]
       │
       ▼
┌──────────────────┐
│  Cloudflare      │
│  Worker          │
└──────────────────┘
       │
       ▼
┌──────────────────┐
│  OpenAI API      │ ← GPT-4o-mini
│  (Function Call) │   도구 호출 자동 판단
└──────────────────┘
       │
   ┌───┴───┬───────┬───────┬───────┬───────┬───────┐
   ▼       ▼       ▼       ▼       ▼       ▼       ▼
[날씨]  [검색]  [시간]  [계산]  [문서]  [도메인] [예치금]
   │       │       │       │       │       │       │
   │       │       │       │       │       │       └── Deposit Agent (Assistants API)
   │       │       │       │       │       │                    ↓
   │       │       │       │       │       └── Domain Agent    D1 (자동 매칭)
   │       │       │       │       │                 ↓
   │       │       │       │       └── Context7     Namecheap API
   └───┬───┴───────┴───────┴───────┴───────────────────┘
       ▼
┌──────────────────┐
│  최종 응답 생성   │
└──────────────────┘
       │
       ▼
[D1 저장] → [Telegram 응답]

사용자 프로필 시스템

[사용자 메시지]
       │
       ▼
┌──────────────────┐
│  message_buffer  │ ← 최대 19개 (20개 되면 프로필 업데이트)
└──────────────────┘
       │ 20개 도달
       ▼
┌──────────────────┐
│  프로필 분석      │ ← 사용자 발언만 추출하여 분석
│  (OpenAI)        │   봇 응답은 무시
└──────────────────┘
       │
       ▼
┌──────────────────┐
│    summaries     │ ← 최근 3개만 유지 (슬라이딩 윈도우)
│  [v1] [v2] [v3]  │
└──────────────────┘

프로필 분석 내용

추출 정보 설명
관심사 사용자가 자주 언급하는 주제
목표 해결하려는 문제, 달성하려는 것
맥락 직업, 상황, 배경 정보
선호도 좋아하는 것, 싫어하는 것
질문 패턴 무엇에 대해 알고 싶어하는지

Function Calling

OpenAI Function Calling을 통해 AI가 자동으로 필요한 도구를 호출합니다.

지원 기능

기능 예시 질문 API
날씨 "서울 날씨", "도쿄 날씨 알려줘" wttr.in
검색 "파이썬이 뭐야", "클라우드플레어란" DuckDuckGo
시간 "지금 몇 시야", "뉴욕 시간" 내장
계산 "123 * 456", "100의 20%" 내장
문서 "React hooks 사용법", "OpenAI API 예제" Context7
도메인 "도메인 목록", "anvil.it.com 네임서버", ".com 가격", "google.com whois" Domain Agent + WHOIS API
예치금 "잔액 확인", "충전하고 싶어", "10000원 입금했어" D1 + Email Worker

동작 방식

사용자: "서울 날씨 어때?"
           │
           ▼
OpenAI: "get_weather 함수를 호출해야겠다"
           │
           ▼
Worker: wttr.in API 호출 → 날씨 데이터 수신
           │
           ▼
OpenAI: 날씨 데이터를 자연어로 응답 생성
           │
           ▼
응답: "🌤 서울 날씨\n온도: 5°C\n습도: 45%..."

예치금 시스템

은행 계좌 입금 기반 예치금 충전 시스템입니다. 사용자 신고와 은행 SMS 알림을 양방향으로 자동 매칭합니다.

입금 계좌

은행 계좌번호 예금주
하나은행 427-910018-27104 주식회사 아이언클래드

Vault 경로: secret/companies/ironclad-corp @ vault.anvil.it.com

자동 매칭 흐름

[시나리오 1: 사용자가 먼저 신고]

사용자: "홍길동 50000원 입금했어"
       │
       ▼
┌──────────────────┐
│ bank_notifications│ ← 기존 은행 알림 확인
└──────────────────┘
       │
       ├── 매칭 발견 → 즉시 confirmed + 잔액 증가
       │
       └── 매칭 없음 → pending 상태로 대기
[시나리오 2: 은행 SMS가 먼저 도착]

은행 SMS → Email Worker 수신
       │
       ▼
┌──────────────────┐
│  SMS 파싱        │ ← 입금자명, 금액, 은행 추출
│ (하나/KB/신한)   │
└──────────────────┘
       │
       ▼
┌──────────────────┐
│ deposit_transactions│ ← 대기중 입금 확인
└──────────────────┘
       │
       ├── 매칭 발견 → 즉시 confirmed + 잔액 증가
       │
       └── 매칭 없음 → bank_notifications에 저장 (나중에 매칭)

지원 기능

기능 설명 권한
잔액 조회 현재 예치금 잔액 확인 모든 사용자
계좌 안내 입금 계좌 정보 표시 모든 사용자
입금 신고 입금자명 + 금액으로 충전 요청 모든 사용자
거래 내역 최근 거래 내역 조회 모든 사용자
입금 취소 대기중 입금 취소 모든 사용자
대기 목록 미처리 입금 목록 조회 관리자 전용
수동 확인 입금 수동 확정 처리 관리자 전용
입금 거절 입금 요청 거절 관리자 전용

Gmail → Apps Script → Worker 연동

SMS를 Gmail로 전달받아 Apps Script에서 Worker API를 호출합니다.

흐름:

은행 SMS → Gmail(deposit.anvil@gmail.com) → Apps Script (1분마다)
                                                  ↓
                              POST /api/bank-notification → DB 저장 → 자동 매칭

Apps Script 코드:

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분마다

지원 은행 SMS 패턴:

  • 하나은행 (Web발신): [Web발신] 하나,01/16, 23:30 427******27104 입금5원 황병하
  • 하나은행 (기존): [하나은행] 01/16 14:30 입금 50,000원 홍길동 잔액 1,234,567원
  • KB국민: [KB] 입금 50,000원 01/16 14:30 홍길동
  • 신한: [신한] 01/16 입금 50,000원 홍길동

도메인 관리

OpenAI Assistants API 기반 도메인 관리 에이전트입니다.

지원 기능

기능 설명 권한
도메인 목록 내 도메인 목록 조회 소유자
도메인 정보 도메인 상세 정보 (만료일 등) 소유자
네임서버 조회 현재 네임서버 확인 누구나
네임서버 변경 네임서버 설정 변경 소유자
가격 조회 TLD/ccSLD 등록 가격 (원화) 누구나
WHOIS 조회 공개 WHOIS 정보 (RDAP) 누구나
가용성 확인 도메인 등록 가능 여부 누구나

가격 조회

Namecheap 가격 + 13% 마진, 매일 환율 업데이트

사용자: ".com 가격"
봇: ".com 도메인 등록 가격은 20,000원입니다."

사용자: "it.com 가격"
봇: "it.com 도메인 등록 가격은 55,000원입니다."

지원 TLD: com, net, org, io, me, info, biz, it.com, uk.com 등

WHOIS 조회

자체 WHOIS API 서버(Vercel)를 통해 TCP 43 포트로 직접 쿼리

사용자: "google.com whois"
봇: 등록일, 만료일, 네임서버, 등록기관 정보 표시
  • WHOIS API: https://whois-api-eight.vercel.app
  • 지원 TLD: com, net, org, io, co, me, kr, jp, cn, uk, de, fr 등 40+ TLD
  • ccSLD 미지원: it.com, uk.com, us.com 등 사설 레지스트리는 WHOIS 비공개

프로젝트 구조

telegram-bot-workers/
├── src/
│   ├── index.ts           # 메인 Worker
│   ├── types.ts           # 타입 정의
│   ├── security.ts        # Webhook 보안 검증
│   ├── telegram.ts        # Telegram API 유틸
│   ├── summary-service.ts # 프로필 분석 서비스
│   ├── openai-service.ts  # OpenAI + Function Calling
│   ├── deposit-agent.ts   # 예치금 에이전트 (Assistants API)
│   ├── n8n-service.ts     # n8n 연동 (선택)
│   └── commands.ts        # 봇 명령어 핸들러
├── schema.sql             # D1 스키마
├── wrangler.toml          # Wrangler 설정
├── n8n-workflow-example.json  # n8n 워크플로우 예시
├── package.json
├── tsconfig.json
└── README.md

배포 가이드

1. 프로젝트 설정

cd telegram-bot-workers
npm install

2. D1 데이터베이스

현재 설정:

[[d1_databases]]
binding = "DB"
database_name = "telegram-conversations"
database_id = "c285bb5b-888b-405d-b36f-475ae5aed20e"

스키마:

  • users - 사용자 정보
  • message_buffer - 메시지 임시 저장
  • summaries - 프로필 저장
  • user_deposits - 예치금 계정
  • deposit_transactions - 예치금 거래 내역
  • bank_notifications - 은행 입금 알림 (SMS 파싱)

3. Secrets 설정

# Bot Token (BotFather에서 발급)
wrangler secret put BOT_TOKEN

# Webhook Secret
wrangler secret put WEBHOOK_SECRET

# OpenAI API Key (필수)
wrangler secret put OPENAI_API_KEY

# 입금 알림 API Secret (Apps Script 연동용)
wrangler secret put BANK_API_SECRET

Vault 연동 (선택)

API 키는 HashiCorp Vault에서 중앙 관리됩니다.

# Vault에서 OpenAI API 키 조회
vault kv get secret/openai

# 저장된 정보
# - api_key: OpenAI API 키
# - email: kappa.inouter@gmail.com (계정 관리용)

# Vault에서 키 가져와서 Worker에 설정
OPENAI_KEY=$(vault kv get -field=api_key secret/openai)
echo $OPENAI_KEY | wrangler secret put OPENAI_API_KEY

참고: Vault 서버: https://vault.anvil.it.com

4. 배포

wrangler deploy

5. Webhook 설정

curl https://telegram-summary-bot.kappa-d8e.workers.dev/setup-webhook
curl https://telegram-summary-bot.kappa-d8e.workers.dev/webhook-info

보안 설정

Webhook 보안 검증

검증 항목 설명
Secret Token X-Telegram-Bot-Api-Secret-Token 헤더 검증
Timing-safe 비교 타이밍 공격 방지
Timestamp 60초 이내 메시지만 처리
Rate Limiting 30req/분/사용자

API 키 관리

저장 위치 비고
BOT_TOKEN Wrangler Secret BotFather 발급
WEBHOOK_SECRET Wrangler Secret 자동 생성
OPENAI_API_KEY Wrangler Secret + Vault kappa.inouter@gmail.com

Vault 경로: secret/openai @ vault.anvil.it.com


봇 명령어

사용자 명령어

명령어 설명
/start 봇 시작, 기능 소개
/help 도움말
/profile 내 프로필 보기
/reset 대화 초기화 (확인 필요)
/reset-confirm 초기화 확인 (실제 삭제)

개발자 명령어 (숨김)

명령어 설명
/context 현재 컨텍스트 상태 (버퍼 수, 프로필 버전)
/stats 대화 통계
/debug 디버그 정보

설정값

wrangler.toml:

name = "telegram-summary-bot"
main = "src/index.ts"
compatibility_date = "2024-01-01"

[ai]
binding = "AI"

[vars]
SUMMARY_THRESHOLD = "20"
MAX_SUMMARIES_PER_USER = "3"
N8N_WEBHOOK_URL = "https://n8n.anvil.it.com"
DOMAIN_AGENT_ID = "asst_MzPFKoqt7V4w6bc0UwcXU4ob"
DOMAIN_OWNER_ID = "821596605"
DEPOSIT_AGENT_ID = "asst_XMoVGU7ZwRpUPI6PHGvRNm8E"
DEPOSIT_ADMIN_ID = "821596605"

[[d1_databases]]
binding = "DB"
database_name = "telegram-conversations"
database_id = "c285bb5b-888b-405d-b36f-475ae5aed20e"

비용 예측

월간 예상 비용

사용량 D1 OpenAI Workers
1만 메시지 $0 ~$0.20 $0 ~$0.20
10만 메시지 $0 ~$2.00 $0 ~$2.00
100만 메시지 $0 ~$20.00 ~$0.30 ~$20.30

GPT-4o-mini: 입력 $0.15/1M, 출력 $0.60/1M 토큰


API 엔드포인트

경로 메서드 설명
/ GET 서비스 정보
/health GET 헬스 체크
/webhook-info GET Webhook 상태
/setup-webhook GET Webhook 설정
/webhook POST Telegram Webhook
/api/bank-notification POST 입금 알림 API (Apps Script 연동)

참고


소스 코드

Gitea: https://gitea.anvil.it.com/kaffa/telegram-bot-workers

Description
Telegram bot with Cloudflare Workers + D1 + OpenAI
Readme MIT 1.1 MiB
Languages
TypeScript 99.7%
Shell 0.3%