Copy script
Copied
Copy script
Copied
Professional SEO Assessment Tool with Nimble SERP API
Comprehensive SEO analysis tool that uses Nimble SERP API to assess keyword rankings, identify competitors, and generate strategic recommendations. Analyzes brand, product, and competitive keywords with detailed reporting, competitor analysis, and actionable insights. Perfect for monthly SEO tracking, competitive research, and measuring SEO campaign effectiveness. Features customizable keyword sets, multi-country support, and professional-grade reporting.

Created by
andrew van beek - Keyboard Team
Requirements
KEYBOARD_NIMBLE_SERP_KEY
Script
Copy script
Copied
Copy script
Copied
const axios = require('axios'); // SEO Assessment Tool using Nimble SERP API console.log(`🔍 Starting SEO assessment for ${website}...\n`); const NIMBLE_API_KEY = process.env.KEYBOARD_NIMBLE_SERP_KEY; // Combine all keywords into categories const keywordSets = { brand: brandKeywords, product: productKeywords, competitive: competitiveKeywords }; // Nimble SERP API configuration const serpAPI = { endpoint: 'https://api.webit.live/api/v1/realtime/serp', headers: { 'Authorization': `Bearer ${NIMBLE_API_KEY}`, 'Content-Type': 'application/json' } }; // Function to get SERP data for a keyword async function getSerpData(query) { console.log(`🔎 Analyzing: "${query}"`); try { const response = await axios.post(serpAPI.endpoint, { query: query, search_engine: searchEngine, country: country, locale: 'en', parse: true, render: false }, { headers: serpAPI.headers, timeout: 10000 }); const organicResults = response.data.parsing?.entities?.OrganicResult || []; const paidResults = response.data.parsing?.entities?.PaidResult || []; return { query, success: true, organicResults, paidResults, totalResults: organicResults.length }; } catch (error) { console.error(`❌ Error for "${query}":`, error.message); return { query, success: false, error: error.message, organicResults: [], paidResults: [] }; } } // Analyze website presence in results function analyzePresence(results, domain = website) { const analysis = { found: false, position: null, url: null, title: null, snippet: null }; results.forEach((result, index) => { if (result.url && result.url.includes(domain)) { analysis.found = true; analysis.position = index + 1; analysis.url = result.url; analysis.title = result.title; analysis.snippet = result.snippet; } }); return analysis; } // Extract top competitors function getTopCompetitors(results) { if (!includeCompetitorAnalysis) return []; return results.slice(0, 5).map((result, index) => { if (result.url) { try { const domain = new URL(result.url).hostname; return { position: index + 1, domain: domain, title: result.title, url: result.url }; } catch (e) { return null; } } return null; }).filter(Boolean).filter(comp => !comp.domain.includes(website)); } // Main assessment function async function runAssessment() { const assessment = { timestamp: new Date().toISOString(), website: website, results: {}, summary: { totalKeywords: 0, foundKeywords: 0, positions: [], allCompetitors: [] } }; console.log('📊 Running SEO analysis...\n'); // Process each category for (const [category, keywords] of Object.entries(keywordSets)) { console.log(`\n📋 ${category.toUpperCase()} keywords:`); assessment.results[category] = {}; assessment.summary.totalKeywords += keywords.length; for (const keyword of keywords) { // Add delay between requests await new Promise(resolve => setTimeout(resolve, 800)); const serpData = await getSerpData(keyword); if (serpData.success) { const presence = analyzePresence(serpData.organicResults); const competitors = getTopCompetitors(serpData.organicResults); assessment.results[category][keyword] = { presence, totalResults: serpData.organicResults.length, paidResultsCount: serpData.paidResults.length, topCompetitors: competitors.slice(0, 3) }; if (presence.found) { assessment.summary.foundKeywords++; assessment.summary.positions.push(presence.position); console.log(` ✅ "${keyword}": Position ${presence.position}`); } else { console.log(` ❌ "${keyword}": Not in top 10`); } // Collect competitors if (includeCompetitorAnalysis) { assessment.summary.allCompetitors.push(...competitors); } } else { assessment.results[category][keyword] = { error: serpData.error, presence: { found: false }, topCompetitors: [] }; console.log(` ⚠️ "${keyword}": ${serpData.error}`); } } } return assessment; } // Generate report function generateReport(assessment) { console.log('\n\n📈 SEO ASSESSMENT RESULTS\n'); console.log('=' .repeat(50)); const summary = assessment.summary; const avgPosition = summary.positions.length > 0 ? (summary.positions.reduce((a, b) => a + b, 0) / summary.positions.length).toFixed(1) : 'N/A'; // Performance Overview console.log('\n📊 PERFORMANCE OVERVIEW:'); console.log(` 🎯 Website: ${assessment.website}`); console.log(` 📅 Analysis Date: ${new Date(assessment.timestamp).toLocaleDateString()}`); console.log(` 🔍 Keywords Analyzed: ${summary.totalKeywords}`); console.log(` ✅ Currently Ranking: ${summary.foundKeywords} keywords`); console.log(` 📈 Success Rate: ${((summary.foundKeywords / summary.totalKeywords) * 100).toFixed(1)}%`); console.log(` 📍 Average Position: ${avgPosition}`); // Category Breakdown console.log('\n📋 DETAILED BREAKDOWN:'); Object.entries(assessment.results).forEach(([category, keywords]) => { const ranking = Object.values(keywords).filter(k => k.presence?.found).length; const total = Object.keys(keywords).length; console.log(`\n🏷️ ${category.toUpperCase()}: ${ranking}/${total} ranking`); Object.entries(keywords).forEach(([keyword, data]) => { if (data.presence?.found) { console.log(` ✅ "${keyword}" - Position ${data.presence.position}`); console.log(` 📄 Title: ${data.presence.title}`); } else if (data.error) { console.log(` ⚠️ "${keyword}" - API Error`); } else { console.log(` ❌ "${keyword}" - Not ranking`); if (includeCompetitorAnalysis && data.topCompetitors && data.topCompetitors.length > 0) { console.log(` 🏆 Top competitors: ${data.topCompetitors.slice(0, 3).map(c => c.domain).join(', ')}`); } } }); }); // Competitor Analysis if (includeCompetitorAnalysis) { const competitorCount = {}; summary.allCompetitors.forEach(comp => { competitorCount[comp.domain] = (competitorCount[comp.domain] || 0) + 1; }); const topCompetitors = Object.entries(competitorCount) .sort((a, b) => b[1] - a[1]) .slice(0, 6); console.log('\n\n🏆 TOP COMPETITORS:'); if (topCompetitors.length > 0) { topCompetitors.forEach(([domain, count], index) => { console.log(`${index + 1}. ${domain} (${count} appearances)`); }); } else { console.log('No consistent competitors found across searches'); } } // Strategic Recommendations console.log('\n\n💡 STRATEGIC RECOMMENDATIONS:'); console.log('=' .repeat(40)); const brandRanking = Object.values(assessment.results.brand || {}).filter(r => r.presence?.found).length; const productRanking = Object.values(assessment.results.product || {}).filter(r => r.presence?.found).length; const competitiveRanking = Object.values(assessment.results.competitive || {}).filter(r => r.presence?.found).length; console.log('\n🎯 PRIORITY ACTIONS:'); if (brandRanking === 0) { console.log('1. [CRITICAL] Brand Visibility - Create brand-focused content and optimize for brand terms'); } if (productRanking === 0) { console.log('2. [HIGH] Product Keywords - Develop landing pages targeting product/service terms'); } if (competitiveRanking === 0) { console.log('3. [HIGH] Competitive Position - Build comparison content and alternative positioning'); } if (summary.foundKeywords > 0) { const lowPositions = summary.positions.filter(p => p > 5).length; if (lowPositions > 0) { console.log(`4. [MEDIUM] Optimize ${lowPositions} existing rankings to improve positions`); } } console.log('\n📝 CONTENT & TECHNICAL:'); console.log('• Create targeted landing pages for missing keywords'); console.log('• Optimize existing pages for better positions'); console.log('• Implement schema markup and technical SEO'); console.log('• Monitor and track progress monthly'); return { performanceScore: (summary.foundKeywords / summary.totalKeywords) * 100, avgPosition: avgPosition, recommendationCount: 4 }; } // Execute assessment try { const startTime = Date.now(); const assessment = await runAssessment(); const endTime = Date.now(); const duration = (endTime - startTime) / 1000; const report = generateReport(assessment); console.log('\n\n✅ SEO ASSESSMENT COMPLETED!'); console.log(`⏱️ Execution Time: ${duration.toFixed(1)} seconds`); console.log(`📊 Performance Score: ${report.performanceScore.toFixed(1)}%`); console.log(`🎯 Average Position: ${report.avgPosition}`); console.log(`💡 Recommendations: ${report.recommendationCount} strategic areas identified`); console.log('\n🔍 VERIFICATION:'); console.log('✅ SERP API authentication successful'); console.log('✅ All keyword categories analyzed'); console.log('✅ Strategic recommendations generated'); if (assessment.summary.foundKeywords > 0) { console.log(`✅ Found ${assessment.summary.foundKeywords} existing rankings to optimize`); } else { console.log('⚠️ No current rankings - significant SEO opportunity identified'); } } catch (error) { console.error('💥 Assessment failed:', error.message); }