/ scripts / generate-hindi-search-volumes.js
generate-hindi-search-volumes.js
  1  #!/usr/bin/env node
  2  
  3  /**
  4   * Generate search volume CSVs for Hindi keywords
  5   *
  6   * This script generates search volume data for Hindi keyword files:
  7   * - data/in/businesses-hindi.txt → data/in/businesses-hindi-search-volume.csv
  8   * - data/in/regions-hindi.txt → data/in/regions-hindi-search-volume.csv
  9   *
 10   * Usage:
 11   *   node scripts/generate-hindi-search-volumes.js [--type businesses|regions|all]
 12   */
 13  
 14  import 'dotenv/config';
 15  import { generateSearchVolumeCSV } from '../src/utils/keyword-validator.js';
 16  import Logger from '../src/utils/logger.js';
 17  import path from 'path';
 18  import fs from 'fs';
 19  
 20  const logger = new Logger('HindiSearchVolumes');
 21  
 22  async function main() {
 23    // Check DataForSEO credentials
 24    if (!process.env.DATAFORSEO_LOGIN || !process.env.DATAFORSEO_PASSWORD) {
 25      logger.error(
 26        'DataForSEO credentials required. Add DATAFORSEO_LOGIN and DATAFORSEO_PASSWORD to .env'
 27      );
 28      process.exit(1);
 29    }
 30  
 31    // Parse command line arguments
 32    const args = process.argv.slice(2);
 33    const typeArg = args.find(arg => arg.startsWith('--type='));
 34    const type = typeArg ? typeArg.split('=')[1] : 'all';
 35  
 36    if (!['businesses', 'regions', 'all'].includes(type)) {
 37      logger.error('Invalid type. Use --type=businesses, --type=regions, or --type=all');
 38      process.exit(1);
 39    }
 40  
 41    const dataDir = './data/in';
 42    const tasks = [];
 43  
 44    // Determine which files to process
 45    if (type === 'businesses' || type === 'all') {
 46      tasks.push({
 47        name: 'businesses',
 48        inputPath: path.join(dataDir, 'businesses-hindi.txt'),
 49        outputPath: path.join(dataDir, 'businesses-hindi-search-volume.csv'),
 50      });
 51    }
 52  
 53    if (type === 'regions' || type === 'all') {
 54      tasks.push({
 55        name: 'regions',
 56        inputPath: path.join(dataDir, 'regions-hindi.txt'),
 57        outputPath: path.join(dataDir, 'regions-hindi-search-volume.csv'),
 58      });
 59    }
 60  
 61    logger.info(`Generating Hindi search volume CSVs (type: ${type})...`);
 62    logger.info(`Language: Hindi (hi), Country: India (IN)`);
 63    logger.info('');
 64  
 65    let successCount = 0;
 66    let totalKeywords = 0;
 67  
 68    for (const task of tasks) {
 69      if (!fs.existsSync(task.inputPath)) {
 70        logger.warn(`File not found: ${task.inputPath}`);
 71        continue;
 72      }
 73  
 74      logger.info(`Processing ${task.name}...`);
 75      logger.info(`  Input: ${task.inputPath}`);
 76      logger.info(`  Output: ${task.outputPath}`);
 77  
 78      try {
 79        const stats = await generateSearchVolumeCSV(
 80          task.inputPath,
 81          'IN', // Country code
 82          task.outputPath,
 83          'hi' // Language code for Hindi
 84        );
 85  
 86        logger.success(`✓ ${task.name}: ${stats.totalKeywords} keywords generated`);
 87        logger.info(`  Seeds: ${stats.seedCount}, Expanded: ${stats.expandedCount}`);
 88        logger.info('');
 89  
 90        successCount++;
 91        totalKeywords += stats.totalKeywords;
 92      } catch (err) {
 93        logger.error(`✗ ${task.name}: ${err.message}`);
 94        logger.error(`  ${err.stack}`);
 95        logger.info('');
 96  
 97        if (err.message.includes('API') || err.message.includes('DataForSEO')) {
 98          logger.warn('Stopping due to API error');
 99          break;
100        }
101      }
102    }
103  
104    logger.info('='.repeat(60));
105    logger.success(`Completed: ${successCount}/${tasks.length} tasks`);
106    logger.success(`Total keywords generated: ${totalKeywords}`);
107  }
108  
109  main().catch(err => {
110    logger.error(`Fatal error: ${err.message}`);
111    console.error(err);
112    process.exit(1);
113  });