@profullstack/lead-generator
v1.2.4
Published
A CLI tool for sending mass lead emails to prospective clients from CSV files with AI-powered personalization
Readme
Lead Generator
A powerful CLI tool and Node.js module for sending mass lead emails with AI-powered personalization and automated voice cold-calling. Built for sales teams who want to scale their outreach while maintaining personalization and professionalism.
Features
- 📧 Mass Email Campaigns - Send personalized emails to hundreds of leads
- 📞 Voice AI Cold-calling - Automated cold calling with Bland.ai integration
- 🤖 AI Personalization - OpenAI-powered template customization
- 📊 CSV Processing - Import leads from CSV files with validation
- 🎯 Smart Templates - 10 pre-built sales email templates
- 📈 Batch Processing - Configurable batch sizes with rate limiting
- 🔍 Email Validation - Comprehensive lead data validation
- 🎣 Webhook Server - Real-time call outcome processing with Hono.js
- 🎛️ IVR System - Press 1 for Calendly, Press 2 to opt-out
- 🛠️ CLI & Module - Use as command-line tool or Node.js module
Installation
Using pnpm (recommended)
pnpm install @profullstack/lead-generatorUsing npm
npm install @profullstack/lead-generatorGlobal Installation (for CLI usage)
pnpm install -g @profullstack/lead-generatorQuick Start
1. Environment Setup
Create a .env file with your API keys:
# Mailgun Configuration (Required for email campaigns)
MAILGUN_API_KEY=your_mailgun_api_key_here
MAILGUN_DOMAIN=your_mailgun_domain_here
# OpenAI Configuration (Required for AI personalization)
OPENAI_API_KEY=your_openai_api_key_here
# Bland.ai Configuration (Required for voice calling)
BLAND_AI_API_KEY=your_bland_ai_api_key_here
VOICE_WEBHOOK_PORT=3001
VOICE_WEBHOOK_URL=https://your-domain.com/webhook
# SMS & Calendly Configuration (Optional)
SMS_SERVICE_API_KEY=your_sms_api_key_here
CALENDLY_LINK=https://calendly.com/your-meeting-link
# Sender Information
DEFAULT_FROM_EMAIL=your_name@your_domain.com
DEFAULT_FROM_NAME=Your Name2. Prepare Your CSV File
Your CSV file should include these columns:
FirstName(required)LastName(optional)Company(required)WorkEmail(required if PersonalEmail not provided)PersonalEmail(required if WorkEmail not provided)Phone(optional, for future voice features)Industry(optional, helps with personalization)Title(optional, helps with personalization)
Example CSV:
FirstName,LastName,Company,WorkEmail,PersonalEmail,Phone,Industry,Title
John,Doe,Acme Corp,[email protected],[email protected],555-0123,Technology,CTO
Jane,Smith,Beta Inc,[email protected],,555-0456,Healthcare,VP Engineering3. Send Your First Campaign
# Using CLI
lead-generator send leads.csv --template expansion --sender-name "Your Name"
# Or using the short alias
lg send leads.csv -t expansionCLI Usage
Commands
Send Campaign
lead-generator send <csv-file> [options]
Options:
--template, -t Template ID or "random" (default: "random")
--sender-name Sender name
--sender-email Sender email
--sender-title Sender title (default: "Sales Director")
--batch-size Emails per batch (default: 300)
--delay Delay between batches in ms (default: 1000)
--dry-run Simulate without sending (default: false)
--ai-personalization Enable AI personalization (default: true)
--output, -o Save results to fileList Templates
lead-generator templates [options]
Options:
--category, -c Filter by category
--tone Filter by tone
--details, -d Show template detailsValidate CSV
lead-generator validate <csv-file> [options]
Options:
--output, -o Save validation report to fileVoice AI Cold-calling
# Start cold-calling campaign
lead-generator coldcall run <csv-file> [options]
Options:
--script Voice script template (default: "default")
--batch-size Number of calls per batch (default: 10)
--delay Delay between calls in seconds (default: 30)
--dry-run Simulate calling without making actual calls
--output, -o Save campaign results to file
# Check campaign status
lead-generator coldcall status [options]
Options:
--campaign-id Specific campaign ID to check
--detailed, -d Show detailed status information
# Generate call reports
lead-generator coldcall report [options]
Options:
--campaign-id Specific campaign ID to report on
--output, -o Output file for report (default: "call-report.csv")
--format Report format: csv or json (default: "csv")Examples
# Send email campaign with specific template
lead-generator send leads.csv --template problem-solver --dry-run
# Start voice calling campaign
lead-generator coldcall run contacts.csv --batch-size 5 --delay 45
# Check status of specific campaign
lead-generator coldcall status --campaign-id abc123 --detailed
# Generate detailed call report
lead-generator coldcall report --format json --output call-results.json
# List all templates with details
lead-generator templates --details
# Validate CSV file
lead-generator validate leads.csv --output validation-report.json
# Send campaign and save results
lead-generator send leads.csv -t expansion -o campaign-results.jsonVoice AI Cold-calling
Quick Start
# 1. Prepare CSV with phone numbers
# Required columns: Name, PhoneNumber, Email (optional)
# 2. Start cold-calling campaign
lead-generator coldcall run contacts.csv
# 3. Monitor campaign progress
lead-generator coldcall status
# 4. Generate detailed reports
lead-generator coldcall report --format jsonCSV Format for Voice Calling
Your CSV file should include these columns for voice campaigns:
Name(required) - Contact's full namePhoneNumber(required) - Phone number in international format (+1234567890)Email(optional) - For follow-up emailsCompany(optional) - Company name for personalization
Example CSV:
Name,PhoneNumber,Email,Company
John Doe,+1234567890,[email protected],Acme Corp
Jane Smith,+1987654321,[email protected],Beta Inc
Bob Johnson,+1555123456,[email protected],Gamma LLCIVR System
The voice AI includes an interactive voice response (IVR) system:
- Press 1: Interested in learning more
- Automatically sends SMS with Calendly link
- Logs as "scheduled meeting" in analytics
- Press 2: Not interested / Opt out
- Adds contact to do-not-call list
- Logs as "opted out" in analytics
Webhook Server
The system includes a Hono.js webhook server that:
- Receives real-time callbacks from Bland.ai when calls complete
- Processes IVR responses automatically (Press 1/2 handling)
- Sends SMS messages with Calendly links for interested prospects
- Manages do-not-call lists for opt-outs
- Generates analytics and call statistics
- Logs all call outcomes to JSON files
Webhook Endpoints
POST /webhook- Main Bland.ai callback endpointGET /health- Health checkGET /logs- Retrieve call logsGET /stats- Get call statisticsDELETE /logs- Clear logs (testing)
Voice Campaign Analytics
Track comprehensive metrics:
- Answer Rate: Percentage of calls answered
- Conversion Rate: Percentage who pressed 1 (interested)
- Opt-out Rate: Percentage who pressed 2
- Average Call Duration: Mean call length
- Campaign ROI: Cost per interested prospect
Example analytics output:
{
"total": 100,
"answered": 65,
"scheduledMeetings": 12,
"optedOut": 8,
"answerRate": "65.00%",
"conversionRate": "18.46%",
"averageDuration": 45
}Node.js Module Usage
Basic Usage
import { LeadGenerator } from '@profullstack/lead-generator';
const generator = new LeadGenerator({
mailgunApiKey: 'your-api-key',
mailgunDomain: 'your-domain.com',
openaiApiKey: 'your-openai-key',
senderName: 'Your Name',
senderEmail: '[email protected]'
});
// Run complete campaign
const results = await generator.runCampaign('leads.csv', {
templateId: 'expansion',
dryRun: false
});
console.log(`Sent ${results.sending.successful} emails`);Quick Start Function
import { quickStart } from '@profullstack/lead-generator';
const results = await quickStart('leads.csv', {
mailgunApiKey: 'your-api-key',
mailgunDomain: 'your-domain.com',
senderName: 'Your Name',
senderEmail: '[email protected]',
templateId: 'social-proof'
});Voice AI Module Usage
import { BlandAIService, startWebhookServer } from '@profullstack/lead-generator';
// Initialize Bland.ai service
const blandService = new BlandAIService({
apiKey: 'your-bland-ai-key',
webhookUrl: 'https://your-domain.com/webhook'
});
// Start webhook server
const webhookServer = await startWebhookServer({
port: 3001,
calendlyLink: 'https://calendly.com/your-meeting'
});
// Process contacts for calling
const { validLeads } = await processLeadsFromCSV('contacts.csv', {
requirePhone: true
});
// Start call campaign
const campaign = await blandService.startCallCampaign(validLeads, {
batchSize: 10,
delay: 30000, // 30 seconds between calls
script: 'default'
});
console.log(`Campaign ${campaign.campaignId} started with ${campaign.totalCalls} calls`);
// Check campaign status
const status = await blandService.getCampaignStatus(campaign.campaignId);
console.log(`Campaign status: ${status.status}, completed: ${status.completed}`);
// Generate report
const report = await blandService.generateCampaignReport(campaign.campaignId);
console.log(`Answer rate: ${report.answerRate}%, Conversion rate: ${report.conversionRate}%`);Webhook Server Usage
import { WebhookServer } from '@profullstack/lead-generator';
// Create webhook server
const server = new WebhookServer({
port: 3001,
logFile: './logs/call-outcomes.json',
calendlyLink: 'https://calendly.com/your-meeting',
smsApiKey: 'your-sms-api-key'
});
// Start server
await server.start();
console.log('Webhook server running on port 3001');
// Access call logs
const logs = server.callLogs;
console.log(`Total calls logged: ${logs.length}`);
// Get statistics
const stats = server.generateStats();
console.log(`Answer rate: ${stats.answerRate}%`);
console.log(`Conversion rate: ${stats.conversionRate}%`);
// Stop server when done
await server.stop();Individual Module Usage
import {
processLeadsFromCSV,
personalizeTemplate,
sendBatchEmails,
getTemplateById,
BlandAIService,
WebhookServer
} from '@profullstack/lead-generator';
// Process CSV for email campaigns
const { validLeads } = await processLeadsFromCSV('leads.csv');
// Process CSV for voice campaigns (requires phone numbers)
const { validLeads: voiceLeads } = await processLeadsFromCSV('contacts.csv', {
requirePhone: true
});
// Get template
const template = getTemplateById('expansion');
// Personalize emails
const personalizedEmails = await batchPersonalize(
[template],
validLeads,
{ name: 'Your Name', email: '[email protected]' }
);
// Send emails
const emailResults = await sendBatchEmails(emailsToSend, {
apiKey: 'your-mailgun-key',
domain: 'your-domain.com'
});
// Make voice calls
const blandService = new BlandAIService({ apiKey: 'your-bland-ai-key' });
const callResults = await blandService.startCallCampaign(voiceLeads, {
batchSize: 5,
delay: 45000
});Available Templates
| ID | Name | Category | Tone | Use Case |
|----|------|----------|------|----------|
| expansion | Team Expansion Focus | growth | professional | When prospect is expanding |
| problem-solver | Problem Solver | solution | consultative | Addressing pain points |
| social-proof | Social Proof | social-proof | confident | Leveraging success stories |
| curiosity | Curiosity Gap | curiosity | intriguing | Creating intrigue |
| direct | Direct Value Prop | direct | straightforward | Clear value proposition |
| question | Question-Based | engagement | conversational | Engaging with questions |
| referral | Referral/Connection | referral | warm | Mutual connections |
| urgency | Urgency/Scarcity | urgency | urgent | Time-sensitive offers |
| insight | Industry Insight | insight | informative | Sharing insights |
| follow-up | Follow-up | follow-up | respectful | Re-engagement |
Configuration
Environment Variables
# Mailgun Configuration (Email Campaigns)
MAILGUN_API_KEY=your_mailgun_api_key
MAILGUN_DOMAIN=your_mailgun_domain
MAILGUN_BASE_URL=https://api.mailgun.net
# OpenAI Configuration (AI Personalization)
OPENAI_API_KEY=your_openai_api_key
OPENAI_MODEL=gpt-4o-mini
OPENAI_MAX_TOKENS=500
OPENAI_TEMPERATURE=0.7
# Bland.ai Configuration (Voice Calling)
BLAND_AI_API_KEY=your_bland_ai_api_key
BLAND_AI_BASE_URL=https://api.bland.ai
VOICE_WEBHOOK_PORT=3001
VOICE_WEBHOOK_URL=https://your-domain.com/webhook
# Call Configuration
CALL_BATCH_SIZE=10
CALL_DELAY_SECONDS=30
CALL_HOURS_START=9
CALL_HOURS_END=17
CALL_TIMEZONE=America/New_York
# SMS & Calendly Configuration
SMS_SERVICE_API_KEY=your_sms_api_key
CALENDLY_LINK=https://calendly.com/your-meeting-link
# Email Configuration
[email protected]
DEFAULT_FROM_NAME=Your Name
[email protected]
# Batch Processing
BATCH_SIZE=300
BATCH_DELAY_MS=1000
MAX_RETRIES=3
# Features
PERSONALIZATION_ENABLED=true
DRY_RUN=falseProgrammatic Configuration
const generator = new LeadGenerator({
// Mailgun settings
mailgunApiKey: 'your-key',
mailgunDomain: 'your-domain.com',
// OpenAI settings
openaiApiKey: 'your-key',
openaiModel: 'gpt-4',
// Sender info
senderName: 'Your Name',
senderEmail: '[email protected]',
senderTitle: 'Sales Director',
// Campaign settings
batchSize: 100,
delay: 2000,
enablePersonalization: true,
trackOpens: true,
trackClicks: true
});API Reference
LeadGenerator Class
Constructor
new LeadGenerator(config)Methods
runCampaign(csvFilePath, options)- Run complete campaignvalidateConfig()- Validate configurationgetTemplates(filters)- Get available templatespreviewEmail(templateId, leadData)- Preview personalized email
Functions
quickStart(csvFilePath, config)- Quick campaign setupprocessLeadsFromCSV(filePath)- Process CSV filepersonalizeTemplate(template, leadData, senderInfo)- Personalize single templatesendBatchEmails(emails, options)- Send email batchgetTemplateById(id)- Get template by ID
Testing
Run the test suite:
# Run all tests
pnpm test
# Run specific test files
pnpm test:csv
pnpm test:email
pnpm test:ai
# Run with coverage
pnpm test --coverageDevelopment
Setup Development Environment
# Clone repository
git clone https://github.com/profullstack/lead-generator.git
cd lead-generator
# Install dependencies
pnpm install
# Copy environment file
cp .env.example .env
# Edit .env with your API keysProject Structure
lead-generator/
├── bin/
│ └── lead-generator.js # CLI entry point
├── src/
│ ├── templates/ # Email templates
│ ├── csv-parser.js # CSV processing
│ ├── ai-service.js # OpenAI integration
│ ├── email-service.js # Mailgun integration
│ └── voice-service.js # Voice AI stub
├── test/ # Test files
├── index.js # Main module export
└── package.jsonContributing
- Fork the repository
- Create a feature branch
- Write tests for new functionality
- Implement the feature
- Run tests and ensure they pass
- Submit a pull request
Troubleshooting
Common Issues
"Mailgun API key is required"
- Ensure
MAILGUN_API_KEYis set in your.envfile - Verify the API key is correct in your Mailgun dashboard
"No valid leads found"
- Check your CSV file format
- Ensure required columns (
FirstName,Company) are present - Verify at least one email field (
WorkEmailorPersonalEmail) has valid data
"Rate limit exceeded"
- Increase the delay between batches with
--delayoption - Reduce batch size with
--batch-sizeoption - Check your Mailgun sending limits
AI personalization fails
- Verify
OPENAI_API_KEYis set correctly - Check your OpenAI account has sufficient credits
- Use
--ai-personalization falseto disable AI features
Debug Mode
Enable verbose logging:
lead-generator send leads.csv --verboseLicense
MIT License - see LICENSE file for details.
Support
- 📧 Email: [email protected]
- 🐛 Issues: GitHub Issues
- 📖 Documentation: Full Documentation
Roadmap
- [ ] Voice AI implementation with Twilio
- [ ] CRM integrations (Salesforce, HubSpot)
- [ ] Advanced analytics and reporting
- [ ] A/B testing for templates
- [ ] Webhook support for email events
- [ ] Template builder UI
- [ ] Multi-language support
