Files
telegram-bot-workers/src/tools/weather-tool.ts
kappa dab279c765 fix: security hardening and performance improvements
Security:
- Add token+secret auth to /setup-webhook and /webhook-info endpoints
- Disable /api/test in production environment (ENVIRONMENT=production)

Performance:
- Add retryWithBackoff to weather-tool (maxRetries: 2)
- Add KV caching to executeLookupDocs (1h TTL)

Code Quality:
- Centralize error messages in src/constants/messages.ts
- Update 5 files to use centralized error constants

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 17:35:51 +09:00

93 lines
2.4 KiB
TypeScript

// Weather Tool - wttr.in integration
import type { Env } from '../types';
import { retryWithBackoff } from '../utils/retry';
import { ERROR_MESSAGES } from '../constants/messages';
// wttr.in API 응답 타입 정의
interface WttrCurrentCondition {
temp_C: string;
FeelsLikeC: string;
weatherDesc: Array<{ value: string }>;
humidity: string;
windspeedKmph: string;
winddir16Point: string;
uvIndex: string;
visibility: string;
}
interface WttrWeatherDay {
date: string;
maxtempC: string;
mintempC: string;
hourly: Array<{
time: string;
tempC: string;
weatherDesc: Array<{ value: string }>;
chanceofrain: string;
}>;
}
interface WttrResponse {
current_condition: WttrCurrentCondition[];
weather: WttrWeatherDay[];
nearest_area: Array<{
areaName: Array<{ value: string }>;
country: Array<{ value: string }>;
}>;
}
export const weatherTool = {
type: 'function',
function: {
name: 'get_weather',
description: '특정 도시의 현재 날씨 정보를 가져옵니다',
parameters: {
type: 'object',
properties: {
city: {
type: 'string',
description: '도시 이름 (예: Seoul, Tokyo, New York)',
},
},
required: ['city'],
},
},
};
export async function executeWeather(args: { city: string }, env?: Env): Promise<string> {
const city = args.city || 'Seoul';
try {
const wttrUrl = env?.WTTR_IN_URL || 'https://wttr.in';
const response = await retryWithBackoff(
() => fetch(`${wttrUrl}/${encodeURIComponent(city)}?format=j1`),
{ maxRetries: 2, initialDelayMs: 500 }
);
if (!response.ok) {
throw new Error(`API 응답 실패: ${response.status}`);
}
const data = await response.json() as WttrResponse;
// 안전한 접근 - 데이터 유효성 확인
if (!data.current_condition?.[0]) {
return `${ERROR_MESSAGES.WEATHER_SERVICE_UNAVAILABLE}: ${city}`;
}
const current = data.current_condition[0];
// weatherDesc 배열 존재 확인
if (!current.weatherDesc?.[0]?.value) {
return `날씨 정보가 불완전합니다: ${city}`;
}
return `🌤 ${city} 날씨
온도: ${current.temp_C}°C (체감 ${current.FeelsLikeC}°C)
상태: ${current.weatherDesc[0].value}
습도: ${current.humidity}%
풍속: ${current.windspeedKmph} km/h`;
} catch (error) {
return `${ERROR_MESSAGES.WEATHER_SERVICE_UNAVAILABLE}: ${city}`;
}
}