feat: CLI 테스트 클라이언트 추가
- /api/test 엔드포인트 추가 (Worker에서 직접 응답 반환) - scripts/chat.ts CLI 클라이언트 - npm run chat 스크립트 추가 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -9,7 +9,8 @@
|
|||||||
"db:create": "wrangler d1 create telegram-summary-db",
|
"db:create": "wrangler d1 create telegram-summary-db",
|
||||||
"db:init": "wrangler d1 execute telegram-summary-db --file=schema.sql",
|
"db:init": "wrangler d1 execute telegram-summary-db --file=schema.sql",
|
||||||
"db:init:local": "wrangler d1 execute telegram-summary-db --local --file=schema.sql",
|
"db:init:local": "wrangler d1 execute telegram-summary-db --local --file=schema.sql",
|
||||||
"tail": "wrangler tail"
|
"tail": "wrangler tail",
|
||||||
|
"chat": "npx tsx scripts/chat.ts"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@cloudflare/workers-types": "^4.20241127.0",
|
"@cloudflare/workers-types": "^4.20241127.0",
|
||||||
|
|||||||
103
scripts/chat.ts
Normal file
103
scripts/chat.ts
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
#!/usr/bin/env npx tsx
|
||||||
|
/**
|
||||||
|
* Telegram Bot CLI Chat Client
|
||||||
|
* - Worker의 /api/test 엔드포인트를 통해 직접 대화
|
||||||
|
* - 사용법: npx tsx scripts/chat.ts
|
||||||
|
* 또는: npx tsx scripts/chat.ts "메시지"
|
||||||
|
*/
|
||||||
|
|
||||||
|
import * as readline from 'readline';
|
||||||
|
|
||||||
|
const WORKER_URL = process.env.WORKER_URL || 'https://telegram-summary-bot.kappa-d8e.workers.dev';
|
||||||
|
const WEBHOOK_SECRET = process.env.WEBHOOK_SECRET;
|
||||||
|
const USER_ID = process.env.TELEGRAM_USER_ID || '821596605';
|
||||||
|
|
||||||
|
interface TestResponse {
|
||||||
|
input: string;
|
||||||
|
response: string;
|
||||||
|
user_id: string;
|
||||||
|
error?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function sendMessage(text: string): Promise<string> {
|
||||||
|
if (!WEBHOOK_SECRET) {
|
||||||
|
return '❌ WEBHOOK_SECRET 환경변수가 필요합니다.\n export WEBHOOK_SECRET="your-secret"';
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(`${WORKER_URL}/api/test`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
text,
|
||||||
|
user_id: USER_ID,
|
||||||
|
secret: WEBHOOK_SECRET,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const data = await response.json() as TestResponse;
|
||||||
|
|
||||||
|
if (data.error) {
|
||||||
|
return `❌ Error: ${data.error}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return data.response;
|
||||||
|
} catch (error) {
|
||||||
|
return `❌ Request failed: ${error}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function interactiveMode() {
|
||||||
|
console.log('🤖 Telegram Bot CLI');
|
||||||
|
console.log(`📡 ${WORKER_URL}`);
|
||||||
|
console.log(`👤 User: ${USER_ID}`);
|
||||||
|
console.log('─'.repeat(40));
|
||||||
|
console.log('메시지를 입력하세요. 종료: exit\n');
|
||||||
|
|
||||||
|
const rl = readline.createInterface({
|
||||||
|
input: process.stdin,
|
||||||
|
output: process.stdout,
|
||||||
|
});
|
||||||
|
|
||||||
|
const prompt = () => {
|
||||||
|
rl.question('\x1b[36m>\x1b[0m ', async (input) => {
|
||||||
|
const text = input.trim();
|
||||||
|
|
||||||
|
if (text === 'exit' || text === 'quit' || text === 'q') {
|
||||||
|
console.log('👋 종료');
|
||||||
|
rl.close();
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!text) {
|
||||||
|
prompt();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('\x1b[33m⏳ 처리 중...\x1b[0m');
|
||||||
|
const response = await sendMessage(text);
|
||||||
|
console.log(`\n\x1b[32m🤖\x1b[0m ${response}\n`);
|
||||||
|
prompt();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
prompt();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const args = process.argv.slice(2);
|
||||||
|
|
||||||
|
if (args.length > 0) {
|
||||||
|
// 단일 메시지 모드
|
||||||
|
const text = args.join(' ');
|
||||||
|
const response = await sendMessage(text);
|
||||||
|
console.log(response);
|
||||||
|
} else {
|
||||||
|
// 대화형 모드
|
||||||
|
await interactiveMode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main().catch(console.error);
|
||||||
58
src/index.ts
58
src/index.ts
@@ -390,6 +390,64 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 테스트 API - 메시지 처리 후 응답 직접 반환
|
||||||
|
if (url.pathname === '/api/test' && request.method === 'POST') {
|
||||||
|
try {
|
||||||
|
const body = await request.json() as { text: string; user_id?: string; secret?: string };
|
||||||
|
|
||||||
|
// 간단한 인증
|
||||||
|
if (body.secret !== env.WEBHOOK_SECRET) {
|
||||||
|
return Response.json({ error: 'Unauthorized' }, { status: 401 });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!body.text) {
|
||||||
|
return Response.json({ error: 'text required' }, { status: 400 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const telegramUserId = body.user_id || '821596605';
|
||||||
|
const chatIdStr = telegramUserId;
|
||||||
|
|
||||||
|
// 사용자 조회/생성
|
||||||
|
const userId = await getOrCreateUser(env.DB, telegramUserId, 'TestUser', 'testuser');
|
||||||
|
|
||||||
|
let responseText: string;
|
||||||
|
|
||||||
|
// 명령어 처리
|
||||||
|
if (body.text.startsWith('/')) {
|
||||||
|
const [command, ...argParts] = body.text.split(' ');
|
||||||
|
const args = argParts.join(' ');
|
||||||
|
responseText = await handleCommand(env, userId, chatIdStr, command, args);
|
||||||
|
} else {
|
||||||
|
// 1. 사용자 메시지 버퍼에 추가
|
||||||
|
await addToBuffer(env.DB, userId, chatIdStr, 'user', body.text);
|
||||||
|
|
||||||
|
// 2. AI 응답 생성
|
||||||
|
responseText = await generateAIResponse(env, userId, chatIdStr, body.text, telegramUserId);
|
||||||
|
|
||||||
|
// 3. 봇 응답 버퍼에 추가
|
||||||
|
await addToBuffer(env.DB, userId, chatIdStr, 'bot', responseText);
|
||||||
|
|
||||||
|
// 4. 임계값 도달시 프로필 업데이트
|
||||||
|
const { summarized } = await processAndSummarize(env, userId, chatIdStr);
|
||||||
|
if (summarized) {
|
||||||
|
responseText += '\n\n👤 프로필이 업데이트되었습니다.';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// HTML 태그 제거 (CLI 출력용)
|
||||||
|
const plainText = responseText.replace(/<[^>]*>/g, '');
|
||||||
|
|
||||||
|
return Response.json({
|
||||||
|
input: body.text,
|
||||||
|
response: plainText,
|
||||||
|
user_id: telegramUserId,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[Test API] Error:', error);
|
||||||
|
return Response.json({ error: String(error) }, { status: 500 });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Telegram Webhook 처리
|
// Telegram Webhook 처리
|
||||||
if (url.pathname === '/webhook') {
|
if (url.pathname === '/webhook') {
|
||||||
// 보안 검증
|
// 보안 검증
|
||||||
|
|||||||
Reference in New Issue
Block a user