feat: DuckDuckGo → Brave Search 교체 + 입금 알림 개선

## 검색 API 교체
- DuckDuckGo Instant Answer API → Brave Search API
- 실제 웹 검색 결과 반환 (제목, 설명, URL)
- Vault에 API 키 저장 (secret/brave-search)
- Free AI 플랜: 2,000 queries/월

## 시스템 프롬프트 개선
- 검색 도구 사용 조건 명시 (최신 정보, 실시간 가격 등)
- 도구 description에 트리거 키워드 추가

## 입금 알림 개선
- 자동 매칭 성공 시 사용자에게 Telegram 알림 전송
- tryAutoMatch() 반환값에 userId, amount 추가

## 문서 업데이트
- Function Calling Tools 테이블에 트리거 키워드 컬럼 추가
- AI 시스템 프롬프트 섹션 추가
- Deposit Agent 프롬프트 수정 방법 문서화
- 자동 알림 시스템 섹션 추가

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
kappa
2026-01-17 10:25:27 +09:00
parent 9822b28028
commit 363a0a504f
6 changed files with 198 additions and 38 deletions

View File

@@ -223,6 +223,47 @@ export default {
// 자동 매칭 시도
const matched = await tryAutoMatch(env.DB, notificationId as number, notification);
// 매칭 성공 시 사용자에게 알림
if (matched && env.BOT_TOKEN) {
const user = await env.DB.prepare(
'SELECT telegram_id FROM users WHERE id = ?'
).bind(matched.userId).first<{ telegram_id: string }>();
if (user) {
// 업데이트된 잔액 조회
const deposit = await env.DB.prepare(
'SELECT balance FROM user_deposits WHERE user_id = ?'
).bind(matched.userId).first<{ balance: number }>();
await sendMessage(
env.BOT_TOKEN,
parseInt(user.telegram_id),
`✅ <b>입금 확인 완료!</b>\n\n` +
`입금액: ${matched.amount.toLocaleString()}\n` +
`현재 잔액: ${(deposit?.balance || 0).toLocaleString()}\n\n` +
`감사합니다! 🎉`
);
}
}
// 관리자에게 알림
if (env.BOT_TOKEN && env.DEPOSIT_ADMIN_ID) {
const statusMsg = matched
? `✅ 자동 매칭 완료! (거래 #${matched.transactionId})`
: '⏳ 매칭 대기 중 (사용자 입금 신고 필요)';
await sendMessage(
env.BOT_TOKEN,
parseInt(env.DEPOSIT_ADMIN_ID),
`🏦 <b>입금 알림</b>\n\n` +
`은행: ${notification.bankName}\n` +
`입금자: ${notification.depositorName}\n` +
`금액: ${notification.amount.toLocaleString()}\n` +
`${notification.balanceAfter ? `잔액: ${notification.balanceAfter.toLocaleString()}\n` : ''}` +
`\n${statusMsg}`
);
}
return Response.json({
success: true,
notification,
@@ -308,6 +349,29 @@ Documentation: https://github.com/your-repo
// 자동 매칭 시도
const matched = await tryAutoMatch(env.DB, notificationId, notification);
// 매칭 성공 시 사용자에게 알림
if (matched && env.BOT_TOKEN) {
const user = await env.DB.prepare(
'SELECT telegram_id FROM users WHERE id = ?'
).bind(matched.userId).first<{ telegram_id: string }>();
if (user) {
// 업데이트된 잔액 조회
const deposit = await env.DB.prepare(
'SELECT balance FROM user_deposits WHERE user_id = ?'
).bind(matched.userId).first<{ balance: number }>();
await sendMessage(
env.BOT_TOKEN,
parseInt(user.telegram_id),
`✅ <b>입금 확인 완료!</b>\n\n` +
`입금액: ${matched.amount.toLocaleString()}\n` +
`현재 잔액: ${(deposit?.balance || 0).toLocaleString()}\n\n` +
`감사합니다! 🎉`
);
}
}
// 관리자에게 알림
if (env.BOT_TOKEN && env.DEPOSIT_ADMIN_ID) {
const statusMsg = matched
@@ -444,7 +508,7 @@ async function tryAutoMatch(
db: D1Database,
notificationId: number,
notification: BankNotification
): Promise<{ transactionId: number } | null> {
): Promise<{ transactionId: number; userId: number; amount: number } | null> {
// 매칭 조건: 입금자명 + 금액이 일치하는 pending 거래
const pendingTx = await db.prepare(
`SELECT dt.id, dt.user_id, dt.amount
@@ -481,5 +545,5 @@ async function tryAutoMatch(
).bind(pendingTx.id, notificationId),
]);
return { transactionId: pendingTx.id };
return { transactionId: pendingTx.id, userId: pendingTx.user_id, amount: pendingTx.amount };
}