Files
telegram-bot-workers/src/tools/weather-tool.ts
kappa e32e3c6a44 refactor: improve OpenAI service and tools
- Enhance OpenAI message types with tool_calls support
- Improve security validation and rate limiting
- Update utility tools and weather tool
- Minor fixes in deposit-agent and domain-register

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 20:26:31 +09:00

97 lines
2.6 KiB
TypeScript

// Weather Tool - wttr.in integration
import type { Env } from '../types';
import { retryWithBackoff } from '../utils/retry';
import { ERROR_MESSAGES } from '../constants/messages';
import { createLogger } from '../utils/logger';
const logger = createLogger('weather');
// 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) {
logger.error('날씨 조회 실패', error as Error, { city });
return `${ERROR_MESSAGES.WEATHER_SERVICE_UNAVAILABLE}: ${city}`;
}
}