4477551ae29d1e5e24d7467504ab4a4e1a8b53a8
- 원페이지 다크테마 디자인 - 서비스: 호스팅, 해외 서버, DDoS 방어, 도메인 - 요금제: Starter/Pro/Enterprise - Cloudflare Pages 배포: anvil-hosting.pages.dev Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Cloudflare Workers 텔레그램 봇
Cloudflare Workers + D1 + OpenAI를 활용한 사용자 프로필 기반 텔레그램 봇
목차
개요
주요 기능
- OpenAI GPT-4o-mini: 고품질 AI 응답 및 Function Calling 지원
- 사용자 프로필: 대화에서 사용자의 관심사, 목표, 맥락을 추출하여 프로필 구축
- Function Calling: 날씨, 검색, 시간, 계산, 문서 조회 등 AI가 자동으로 도구 호출
- Context7 연동: 프로그래밍 라이브러리 공식 문서 실시간 조회
- 무한 컨텍스트: 슬라이딩 윈도우(3개)로 프로필 유지, 무제한 대화 기억
- 개인화 응답: 프로필 기반으로 맞춤형 AI 응답 제공
- 폴백 지원: OpenAI 미설정 시 Workers AI(Llama)로 자동 전환
기술 스택
| 서비스 | 용도 |
|---|---|
| Workers | 서버리스 런타임 |
| D1 | SQLite 데이터베이스 |
| OpenAI | GPT-4o-mini + Function Calling |
| Context7 | 라이브러리 문서 조회 API |
| Workers AI | 폴백용 (Llama 3.1 8B) |
아키텍처
메시지 처리 흐름
[사용자 메시지]
│
▼
┌──────────────────┐
│ Cloudflare │
│ Worker │
└──────────────────┘
│
▼
┌──────────────────┐
│ OpenAI API │ ← GPT-4o-mini
│ (Function Call) │ 도구 호출 자동 판단
└──────────────────┘
│
┌───┴───┬───────┬───────┬───────┐
▼ ▼ ▼ ▼ ▼
[날씨] [검색] [시간] [계산] [문서] → 외부 API
│ │ │ │ │
│ │ │ │ └── Context7 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 |
동작 방식
사용자: "서울 날씨 어때?"
│
▼
OpenAI: "get_weather 함수를 호출해야겠다"
│
▼
Worker: wttr.in API 호출 → 날씨 데이터 수신
│
▼
OpenAI: 날씨 데이터를 자연어로 응답 생성
│
▼
응답: "🌤 서울 날씨\n온도: 5°C\n습도: 45%..."
프로젝트 구조
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
│ ├── 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- 프로필 저장
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
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"
[[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 |
참고
소스 코드
Gitea: https://gitea.anvil.it.com/kaffa/telegram-bot-workers
Languages
TypeScript
99.7%
Shell
0.3%