UNPKG

jobnimbus-mcp-client

Version:

JobNimbus MCP Client - Connect Claude Desktop to remote JobNimbus MCP server

286 lines 14.4 kB
/** * Get Seasonal Door Timing * Optimal timing for door-to-door sales by season with weather analysis and historical performance */ import { BaseTool } from '../baseTool.js'; export class GetSeasonalDoorTimingTool extends BaseTool { get definition() { return { name: 'get_seasonal_door_timing', description: 'Optimal timing for door-to-door sales by season with weather analysis, historical performance, and strategic recommendations', inputSchema: { type: 'object', properties: { service_type: { type: 'string', description: 'Service type to optimize timing for (e.g., "roofing", "solar", "hvac")', }, include_weather_analysis: { type: 'boolean', default: true, description: 'Include weather impact analysis', }, current_month_only: { type: 'boolean', default: false, description: 'Focus only on current month recommendations', }, }, }, }; } async execute(input, context) { try { const serviceType = input.service_type || 'general services'; const includeWeather = input.include_weather_analysis !== false; const currentMonthOnly = input.current_month_only || false; // Fetch jobs data const jobsResponse = await this.client.get(context.apiKey, 'jobs', { size: 100 }); const jobs = jobsResponse.data?.results || []; // Analyze historical job creation by month const monthlyData = new Map(); for (let month = 0; month < 12; month++) { monthlyData.set(month, 0); } for (const job of jobs) { const createdDate = job.date_created || 0; if (createdDate > 0) { const date = new Date(createdDate); const month = date.getMonth(); monthlyData.set(month, (monthlyData.get(month) || 0) + 1); } } // Define seasonal windows const seasonalWindows = [ { season: 'Spring (March - May)', months: ['March', 'April', 'May'], optimal_rating: 'Excellent', best_days: ['Tuesday', 'Wednesday', 'Thursday', 'Saturday'], best_hours: ['10:00 AM - 1:00 PM', '5:00 PM - 7:30 PM'], expected_receptivity: 85, weather_considerations: [ 'Mild temperatures ideal for outdoor conversations', 'After-winter home improvement mindset', 'Spring cleaning and renovation season', ], conversion_rate_multiplier: 1.3, }, { season: 'Summer (June - August)', months: ['June', 'July', 'August'], optimal_rating: 'Good', best_days: ['Thursday', 'Friday', 'Saturday'], best_hours: ['6:00 PM - 8:00 PM', '9:00 AM - 11:00 AM (weekends)'], expected_receptivity: 70, weather_considerations: [ 'Avoid extreme heat hours (2-5 PM)', 'Homeowners often on vacation', 'Evening is best due to heat', ], conversion_rate_multiplier: 1.0, }, { season: 'Fall (September - November)', months: ['September', 'October', 'November'], optimal_rating: 'Excellent', best_days: ['Wednesday', 'Thursday', 'Saturday'], best_hours: ['10:00 AM - 1:00 PM', '4:00 PM - 6:30 PM'], expected_receptivity: 90, weather_considerations: [ 'Pre-winter preparation mindset', 'Comfortable weather for door knocking', 'Homeowners focusing on home before holidays', ], conversion_rate_multiplier: 1.4, }, { season: 'Winter (December - February)', months: ['December', 'January', 'February'], optimal_rating: 'Fair', best_days: ['Saturday', 'Sunday afternoon'], best_hours: ['11:00 AM - 2:00 PM', '2:00 PM - 5:00 PM'], expected_receptivity: 50, weather_considerations: [ 'Holiday season - low receptivity in December', 'Cold weather - shorter conversations', 'Post-storm opportunities for damage assessment', ], conversion_rate_multiplier: 0.7, }, ]; // Build monthly timing recommendations const monthlyTimings = []; const monthNames = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December', ]; const currentMonth = new Date().getMonth(); for (let month = 0; month < 12; month++) { if (currentMonthOnly && month !== currentMonth) continue; const jobsCount = monthlyData.get(month) || 0; // Determine season const season = month >= 2 && month <= 4 ? 'Spring' : month >= 5 && month <= 7 ? 'Summer' : month >= 8 && month <= 10 ? 'Fall' : 'Winter'; // Weather impact const weatherImpact = season === 'Spring' || season === 'Fall' ? 'Favorable' : season === 'Summer' ? 'Neutral' : 'Challenging'; // Holiday considerations const holidays = []; if (month === 11) holidays.push('Avoid first 3 weeks of December (holiday rush)'); if (month === 0) holidays.push('Early January good for New Year resolutions'); if (month === 6) holidays.push('July 4th week - low receptivity'); if (month === 10) holidays.push('Thanksgiving week - avoid'); // Time slots const timeSlots = []; if (season === 'Spring' || season === 'Fall') { timeSlots.push({ day_type: 'Weekday', time_range: '10:00 AM - 1:00 PM', effectiveness_score: 85, contact_likelihood: 60, notes: 'Morning is ideal for retirees and work-from-home', }); timeSlots.push({ day_type: 'Weekday', time_range: '5:00 PM - 7:30 PM', effectiveness_score: 90, contact_likelihood: 80, notes: 'Peak time - people home from work', }); timeSlots.push({ day_type: 'Weekend', time_range: '10:00 AM - 2:00 PM', effectiveness_score: 80, contact_likelihood: 70, notes: 'Mid-day weekend works well', }); } else if (season === 'Summer') { timeSlots.push({ day_type: 'Weekday', time_range: '6:00 PM - 8:00 PM', effectiveness_score: 75, contact_likelihood: 70, notes: 'Evening to avoid heat', }); timeSlots.push({ day_type: 'Weekend', time_range: '9:00 AM - 11:00 AM', effectiveness_score: 70, contact_likelihood: 65, notes: 'Early before it gets too hot', }); } else { // Winter timeSlots.push({ day_type: 'Weekend', time_range: '11:00 AM - 2:00 PM', effectiveness_score: 60, contact_likelihood: 55, notes: 'Warmest part of day', }); } // Recommended approach let approach = ''; if (season === 'Spring') { approach = 'Emphasize spring specials and pre-summer prep. Mention competitors likely booked soon.'; } else if (season === 'Summer') { approach = 'Focus on energy savings and comfort. Schedule appointments for fall if not urgent.'; } else if (season === 'Fall') { approach = 'Highlight winter preparation and end-of-year budgets. Strong urgency messaging works.'; } else { // Winter approach = 'Post-storm damage assessment. Focus on emergency services and spring booking discounts.'; } monthlyTimings.push({ month: monthNames[month], jobs_created_historical: jobsCount, optimal_time_slots: timeSlots, weather_impact: weatherImpact, holiday_considerations: holidays.length > 0 ? holidays : ['No major conflicts'], recommended_approach: approach, }); } // Weather guidance const weatherGuidance = { ideal_conditions: [ 'Clear skies, 60-75°F (15-24°C)', 'Light breeze, no precipitation', 'Good visibility, daylight remaining', ], avoid_conditions: [ 'Heavy rain, snow, or extreme heat (>95°F)', 'Severe weather warnings', 'Temperatures below 32°F for extended knocking', ], seasonal_prep: [ 'Spring: Bring storm damage photos, focus on post-winter repairs', 'Summer: Hydrate, use sun protection, keep presentations short', 'Fall: Emphasize urgency before winter, highlight energy savings', 'Winter: Dress warm but professional, focus on emergencies and spring booking', ], }; // Generate recommendations const recommendations = []; const peakMonths = Array.from(monthlyData.entries()) .sort((a, b) => b[1] - a[1]) .slice(0, 3) .map(([month]) => monthNames[month]); recommendations.push(`📊 Historical peak months: ${peakMonths.join(', ')}`); const now = new Date(); const currentMonthName = monthNames[now.getMonth()]; const currentSeason = now.getMonth() >= 2 && now.getMonth() <= 4 ? 'Spring' : now.getMonth() >= 5 && now.getMonth() <= 7 ? 'Summer' : now.getMonth() >= 8 && now.getMonth() <= 10 ? 'Fall' : 'Winter'; const currentSeasonWindow = seasonalWindows.find(s => s.season.includes(currentSeason)); if (currentSeasonWindow) { recommendations.push(`🌟 Current season (${currentSeason}) rating: ${currentSeasonWindow.optimal_rating}`); recommendations.push(`⏰ Best times right now: ${currentSeasonWindow.best_hours.join(' or ')}`); } recommendations.push('📅 Fall (Sep-Nov) is historically the best season for door-to-door sales'); recommendations.push('🌡️ Weather matters - check forecast before planning routes'); recommendations.push('🎯 Weekday evenings (5-7:30 PM) have highest contact rates year-round'); return { data_source: 'Live JobNimbus API data + Industry best practices', analysis_timestamp: new Date().toISOString(), service_type: serviceType, current_month: currentMonthName, current_season: currentSeason, seasonal_windows: seasonalWindows, monthly_timing_recommendations: monthlyTimings, weather_guidance: includeWeather ? weatherGuidance : undefined, recommendations: recommendations, best_practices: [ 'Track weather forecasts 3-5 days in advance', 'Avoid first/last week of month (budget constraints)', 'Post-storm periods offer excellent opportunities', 'Monday mornings and Friday evenings typically less effective', 'Adjust schedule based on local events and holidays', 'Door knock during daylight hours for safety and visibility', ], key_insights: [ `${seasonalWindows.find(s => s.optimal_rating === 'Excellent')?.season || 'Spring/Fall'} offers highest conversion potential`, `Winter requires adjusted strategy - focus on emergency services`, `Summer vacations reduce contact rates - plan accordingly`, `Weather-dependent services (roofing, exteriors) peak in spring/fall`, ], }; } catch (error) { return { error: error instanceof Error ? error.message : 'Unknown error', status: 'Failed', }; } } } //# sourceMappingURL=getSeasonalDoorTiming.js.map