Files
telegram-bot-workers/src/services/conversation-service.ts
kappa eee934391a feat(phase-5-3): Logger, Metrics, 알림 시스템 통합
Phase 5-3 모니터링 강화 작업의 통합을 완료했습니다.

변경사항:
- Logger 통합: console.log를 구조화된 로깅으로 전환 (9개 파일)
  - JSON 기반 로그, 환경별 자동 전환 (개발/프로덕션)
  - 타입 안전성 보장, 성능 측정 타이머 내장

- Metrics 통합: 실시간 성능 모니터링 시스템 연결 (3개 파일)
  - Circuit Breaker 상태 추적 (api_call_count, error_count, state)
  - Retry 재시도 횟수 추적 (retry_count)
  - OpenAI API 응답 시간 측정 (api_call_duration)

- 알림 통합: 장애 자동 알림 시스템 구현 (2개 파일)
  - Circuit Breaker OPEN 상태 → 관리자 Telegram 알림
  - 재시도 실패 → 관리자 Telegram 알림
  - Rate Limiting 적용 (1시간에 1회)

- 문서 업데이트:
  - CLAUDE.md: coder 에이전트 설명 강화 (20년+ 시니어 전문가)
  - README.md, docs/: 아키텍처 문서 추가

영향받은 파일: 16개 (수정 14개, 신규 2개)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-19 21:23:38 +09:00

75 lines
2.1 KiB
TypeScript

import { Env } from '../types';
import {
addToBuffer,
processAndSummarize,
generateAIResponse,
} from '../summary-service';
import { sendChatAction } from '../telegram';
export interface ConversationResult {
responseText: string;
isProfileUpdated: boolean;
keyboardData?: any;
}
export class ConversationService {
constructor(private env: Env) {}
/**
* 사용자 메시지를 처리하고 AI 응답을 생성합니다.
* 버퍼링, AI 생성, 요약 프로세스를 포함합니다.
*/
async processUserMessage(
userId: number,
chatId: string,
text: string,
telegramUserId: string
): Promise<ConversationResult> {
// 1. 타이핑 액션 전송 (비동기로 실행, 기다리지 않음)
sendChatAction(this.env.BOT_TOKEN, Number(chatId), 'typing').catch(console.error);
// 2. 사용자 메시지 버퍼에 추가
await addToBuffer(this.env.DB, userId, chatId, 'user', text);
// 3. AI 응답 생성
let responseText = await generateAIResponse(
this.env,
userId,
chatId,
text,
telegramUserId
);
// 4. 봇 응답 버퍼에 추가 (키보드 데이터 마커 등은 그대로 저장)
// 실제 사용자에게 보여질 텍스트만 저장하는 것이 좋으나,
// 현재 구조상 전체를 저장하고 나중에 컨텍스트로 활용 시 정제될 수 있음
await addToBuffer(this.env.DB, userId, chatId, 'bot', responseText);
// 5. 임계값 도달 시 프로필 업데이트 (요약)
const { summarized } = await processAndSummarize(
this.env,
userId,
chatId
);
// 키보드 데이터 파싱
let keyboardData: any = null;
const keyboardMatch = responseText.match(/__KEYBOARD__(.+?)__END__\n?/);
if (keyboardMatch) {
responseText = responseText.replace(/__KEYBOARD__.+?__END__\n?/, '');
try {
keyboardData = JSON.parse(keyboardMatch[1]);
} catch (e) {
console.error('[ConversationService] Keyboard parsing error:', e);
}
}
return {
responseText,
isProfileUpdated: summarized,
keyboardData
};
}
}