Files
telegram-bot-workers/openapi.yaml
kaffa bf6bf2af88
Some checks failed
TypeScript CI / build (push) Has been cancelled
chore: anvil.it.com → inouter.com
2026-03-27 16:16:08 +00:00

558 lines
17 KiB
YAML

openapi: 3.0.3
info:
title: Telegram Bot Workers API
description: |
Cloudflare Workers 기반 Telegram Bot의 Public API 문서입니다.
## 인증 방식
- **API Key**: `X-API-Key` 헤더 사용 (Deposit API)
- **Bearer Token**: `Authorization: Bearer {token}` 헤더 (Metrics API)
- **Query Parameter**: `?token=...` (Telegram Webhook 관련)
- **CORS**: hosting.inouter.com만 허용 (Contact Form)
## Rate Limiting
- 사용자당 30 requests / 60초 (Telegram 메시지)
- Rate limit 초과 시 429 응답
## Architecture
- **Runtime**: Cloudflare Workers (Edge Computing)
- **Database**: D1 SQLite
- **KV Store**: Rate Limiting, Caching
- **AI**: OpenAI API (via Cloudflare AI Gateway)
## Related Services
- **namecheap-api**: 도메인 등록 백엔드 (Deposit API 사용)
- **Email Routing**: 입금 SMS 자동 매칭
- **Cloudflare Pages**: 공식 웹사이트 (hosting.inouter.com)
version: 1.0.0
contact:
name: API Support
url: https://hosting.inouter.com
license:
name: MIT
servers:
- url: https://telegram-summary-bot.kappa-d8e.workers.dev
description: Production server
- url: http://localhost:8787
description: Local development
tags:
- name: Health
description: 서비스 상태 확인
- name: Telegram
description: Telegram Webhook 관리
- name: Contact
description: 웹사이트 문의
- name: Deposit
description: 예치금 관리 (Internal API)
- name: Monitoring
description: 시스템 모니터링
paths:
/health:
get:
tags: [Health]
summary: Health Check
description: |
서비스 정상 동작 여부를 확인합니다.
**보안 정책**: 최소 정보만 반환 (DB 정보 미노출)
operationId: getHealth
responses:
'200':
description: 서비스 정상
content:
application/json:
schema:
type: object
required: [status, timestamp]
properties:
status:
type: string
enum: [ok]
example: ok
description: 서비스 상태
timestamp:
type: string
format: date-time
example: "2026-01-19T12:34:56.789Z"
description: 응답 생성 시각 (ISO 8601)
/webhook-info:
get:
tags: [Telegram]
summary: Webhook 정보 조회
description: |
현재 설정된 Telegram Webhook 정보를 확인합니다.
**인증**: Telegram Bot Token 필요
operationId: getWebhookInfo
parameters:
- name: token
in: query
required: true
schema:
type: string
minLength: 40
description: Telegram Bot Token (BOT_TOKEN)
example: "123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11"
responses:
'200':
description: Webhook 정보 (Telegram API 응답)
content:
application/json:
schema:
type: object
description: Telegram getWebhookInfo API 응답
example:
ok: true
result:
url: "https://telegram-summary-bot.kappa-d8e.workers.dev/webhook"
has_custom_certificate: false
pending_update_count: 0
'401':
description: 인증 실패 (잘못된 Bot Token)
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
success: false
error: "Unauthorized"
'500':
description: Telegram API 호출 실패
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/setup-webhook:
get:
tags: [Telegram]
summary: Webhook 설정
description: |
Telegram Webhook을 설정합니다.
**인증**: Bot Token + Webhook Secret 필요
**주의**: 이 엔드포인트는 초기 설정 시에만 사용됩니다.
operationId: setupWebhook
parameters:
- name: token
in: query
required: true
schema:
type: string
minLength: 40
description: Telegram Bot Token (BOT_TOKEN)
- name: secret
in: query
required: true
schema:
type: string
minLength: 1
description: Webhook Secret Token (WEBHOOK_SECRET)
responses:
'200':
description: Webhook 설정 성공
content:
text/plain:
schema:
type: string
example: "Webhook 설정 완료"
'400':
description: 잘못된 요청 (파라미터 누락)
content:
text/plain:
schema:
type: string
example: "Token과 Secret이 필요합니다"
'500':
description: Webhook 설정 실패
content:
text/plain:
schema:
type: string
/api/contact:
post:
tags: [Contact]
summary: 문의 제출
description: |
웹사이트 문의 폼을 제출합니다.
**CORS 정책**: hosting.inouter.com만 허용
**처리**: Telegram 메시지로 전달
operationId: submitContact
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [name, email, message]
properties:
name:
type: string
minLength: 1
maxLength: 100
example: "홍길동"
description: 문의자 이름
email:
type: string
format: email
maxLength: 100
example: "hong@example.com"
description: 문의자 이메일
phone:
type: string
maxLength: 20
example: "010-1234-5678"
description: 문의자 연락처 (선택)
message:
type: string
minLength: 10
maxLength: 1000
example: "도메인 등록 문의드립니다."
description: 문의 내용
responses:
'200':
description: 문의 접수 완료
content:
application/json:
schema:
type: object
required: [success, message]
properties:
success:
type: boolean
example: true
message:
type: string
example: "문의가 접수되었습니다."
'400':
description: 잘못된 요청 (필드 누락 또는 형식 오류)
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
success: false
error: "이름, 이메일, 메시지는 필수입니다."
'403':
description: CORS 위반 (허용되지 않은 Origin)
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
success: false
error: "Forbidden"
'500':
description: 서버 오류
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
options:
tags: [Contact]
summary: CORS Preflight
description: CORS preflight 요청 처리
operationId: contactPreflight
responses:
'200':
description: CORS 허용
headers:
Access-Control-Allow-Origin:
schema:
type: string
example: https://hosting.inouter.com
Access-Control-Allow-Methods:
schema:
type: string
example: POST, OPTIONS
Access-Control-Allow-Headers:
schema:
type: string
example: Content-Type
/api/deposit/balance:
get:
tags: [Deposit]
summary: 잔액 조회
description: |
사용자의 예치금 잔액을 조회합니다.
**용도**: Internal API (namecheap-api 전용)
**인증**: API Key 필요
operationId: getDepositBalance
security:
- ApiKeyAuth: []
parameters:
- name: telegram_id
in: query
required: true
schema:
type: string
pattern: '^\d+$'
description: Telegram User ID
example: "821596605"
responses:
'200':
description: 잔액 정보
content:
application/json:
schema:
type: object
required: [balance]
properties:
balance:
type: integer
minimum: 0
example: 50000
description: 예치금 잔액 (원)
'400':
description: 잘못된 요청 (telegram_id 누락)
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
success: false
error: "telegram_id가 필요합니다."
'401':
description: 인증 실패 (잘못된 API Key)
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
success: false
error: "Unauthorized"
'404':
description: 사용자 없음
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
success: false
error: "사용자를 찾을 수 없습니다."
/api/deposit/deduct:
post:
tags: [Deposit]
summary: 잔액 차감
description: |
예치금에서 금액을 차감합니다.
**용도**: Internal API (namecheap-api 전용)
**인증**: API Key 필요
**트랜잭션**: DB 트랜잭션으로 원자성 보장
operationId: deductDeposit
security:
- ApiKeyAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [telegram_id, amount, reason]
properties:
telegram_id:
type: string
pattern: '^\d+$'
example: "821596605"
description: Telegram User ID
amount:
type: integer
minimum: 1
example: 15000
description: 차감 금액 (원, 양수)
reason:
type: string
minLength: 1
maxLength: 200
example: "도메인 등록: example.com"
description: 차감 사유
responses:
'200':
description: 차감 성공
content:
application/json:
schema:
type: object
required: [success, new_balance, transaction_id]
properties:
success:
type: boolean
example: true
new_balance:
type: integer
minimum: 0
example: 35000
description: 차감 후 잔액 (원)
transaction_id:
type: integer
example: 123
description: 생성된 거래 ID
'400':
description: 잘못된 요청 또는 잔액 부족
content:
application/json:
schema:
type: object
required: [success, error]
properties:
success:
type: boolean
example: false
error:
type: string
example: "잔액이 부족합니다."
examples:
insufficient_balance:
summary: 잔액 부족
value:
success: false
error: "잔액이 부족합니다."
invalid_amount:
summary: 잘못된 금액
value:
success: false
error: "금액은 양수여야 합니다."
'401':
description: 인증 실패
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: 사용자 없음
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/api/metrics:
get:
tags: [Monitoring]
summary: 시스템 메트릭스
description: |
Circuit Breaker 상태 및 API 성능 메트릭스를 조회합니다.
**인증**: Bearer Token 필요 (관리자 전용)
**용도**: 시스템 모니터링 및 디버깅
operationId: getMetrics
security:
- BearerAuth: []
responses:
'200':
description: 메트릭스 정보
content:
application/json:
schema:
type: object
required: [circuitBreakers, apiMetrics]
properties:
circuitBreakers:
type: object
description: Circuit Breaker 상태 맵 (서비스명 → 상태)
additionalProperties:
type: object
properties:
state:
type: string
enum: [CLOSED, OPEN, HALF_OPEN]
description: 현재 상태
failureCount:
type: integer
description: 연속 실패 횟수
lastFailureTime:
type: integer
description: 마지막 실패 시각 (Unix timestamp ms)
nextAttemptTime:
type: integer
description: 다음 시도 가능 시각 (Unix timestamp ms)
example:
"OpenAI API":
state: "CLOSED"
failureCount: 0
lastFailureTime: null
nextAttemptTime: null
apiMetrics:
type: object
description: API 호출 통계 맵 (API명 → 메트릭스)
additionalProperties:
type: object
properties:
totalCalls:
type: integer
description: 총 호출 횟수
successCalls:
type: integer
description: 성공 횟수
failureCalls:
type: integer
description: 실패 횟수
averageDuration:
type: number
description: 평균 응답 시간 (ms)
lastError:
type: string
nullable: true
description: 마지막 에러 메시지
example:
"OpenAI Chat Completion":
totalCalls: 1234
successCalls: 1200
failureCalls: 34
averageDuration: 1523.5
lastError: null
'401':
description: 인증 실패
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
success: false
error: "Unauthorized"
components:
securitySchemes:
ApiKeyAuth:
type: apiKey
in: header
name: X-API-Key
description: |
Deposit API 인증 키 (DEPOSIT_API_SECRET)
**용도**: namecheap-api에서 사용
**획득**: wrangler secret
BearerAuth:
type: http
scheme: bearer
description: |
Metrics API 인증 토큰 (WEBHOOK_SECRET)
**형식**: `Authorization: Bearer {WEBHOOK_SECRET}`
**용도**: 관리자 전용 모니터링
schemas:
Error:
type: object
required: [success, error]
properties:
success:
type: boolean
example: false
description: 항상 false
error:
type: string
example: "오류 메시지"
description: 에러 설명