A Node.js backend API that automates tender eligibility analysis using Google Gemini 2.5 Flash AI. The system processes multiple tender PDFs, analyzes company eligibility, performs SKU matching, calculates pricing, and sends automated email notifications with detailed reports.
- π Extract text from PDF and DOCX documents
- π€ AI-powered summarization using Google Gemini 2.5 Flash
- π Comprehensive eligibility analysis and table generation
- π Advanced 9-step workflow for Tender 2 processing
- π― SKU matching with intelligent scoring algorithm
- π° Automated pricing calculations with real value extraction
- βοΈ Automated email notifications with DOCX/CSV reports
- π RESTful API with 6 main endpoints
- π Multi-key API rotation (supports up to 4 Gemini API keys)
- π¦ Postman collection for easy testing
- Node.js (v14 or higher)
- npm or yarn
- Google Gemini API keys (1-4 keys recommended for better rate limit handling)
- SendGrid account with API key (free tier: 100 emails/day)
-
Clone or download this project
-
Install dependencies
npm install
-
Set up environment variables
Create a
.envfile in the root directory (or copy from.env.example):PORT=3000 GEMINI_API_KEY_1=your_first_gemini_api_key GEMINI_API_KEY_2=your_second_gemini_api_key GEMINI_API_KEY_3=your_third_gemini_api_key GEMINI_API_KEY_4=your_fourth_gemini_api_key SENDGRID_API_KEY=your_sendgrid_api_key SENDGRID_FROM_EMAIL=your_verified_sender@example.com EMAIL_TO=recipient@example.comAPI Key Rotation (Aggressive Strategy):
- The system supports up to 4 Gemini API keys for optimal performance
- Aggressive rotation: Switches to next key on EVERY error (not just rate limits)
- Maximum retries: 3x the number of configured keys
- Automatic exponential backoff with jitter for single-key setups
- You can use 1-4 keys; more keys = better reliability and throughput
Important:
- Get your Gemini API keys from Google AI Studio
- Configure 2-4 API keys for optimal performance and rate limit handling
- For SendGrid:
- Sign up at SendGrid (free tier: 100 emails/day)
- Create an API key from Settings β API Keys
- Verify a sender email address from Settings β Sender Authentication
- Use the API key for
SENDGRID_API_KEYand verified email forSENDGRID_FROM_EMAIL
-
Start the server
npm start
Or for development with auto-reload:
npm run dev
The server will start on http://localhost:3000
POST /api/upload-tender/:tenderId
Upload up to 5 tender PDFs. The system will:
- Extract text from each PDF
- Generate detailed summaries using AI
- Save summaries in
summaries/tenderId/
Example:
curl -X POST http://localhost:3000/api/upload-tender/tender1 \
-F "pdfs=@document1.pdf" \
-F "pdfs=@document2.pdf"Parameters:
tenderId: tender1 or tender2pdfs: Array of PDF files (multipart/form-data)
POST /api/upload-company
Upload company information document (PDF or DOCX).
Example:
curl -X POST http://localhost:3000/api/upload-company \
-F "document=@company_info.docx"Parameters:
document: PDF or DOCX file (multipart/form-data)
POST /api/analyze-tender/:tenderId
Analyzes tender eligibility by:
- Concatenating all 5 PDF summaries
- Cross-referencing with company info
- Generating eligibility analysis table
Example:
curl -X POST http://localhost:3000/api/analyze-tender/tender1Response:
{
"success": true,
"message": "Eligibility analysis completed for tender1",
"tenderId": "tender1",
"tablePath": "analysis/tender1/table.txt",
"summary": {
"totalSummaries": 5,
"comprehensiveSummaryLength": 15234,
"companyInfoLength": 8921,
"eligibilityTableLength": 3456
}
}POST /api/check-eligibility/:tenderId
Checks final eligibility (YES/NO) and:
- If NO: Generates DOCX report and sends email
- If YES: Returns eligibility status
Example:
curl -X POST http://localhost:3000/api/check-eligibility/tender1Response:
{
"success": true,
"message": "Company is NOT eligible for tender1",
"tenderId": "tender1",
"eligible": false,
"decision": "NO",
"emailSent": true,
"docxPath": "analysis/tender1/eligibility_report.docx"
}POST /api/process-all
Automates the entire workflow for both tenders sequentially.
Example:
curl -X POST http://localhost:3000/api/process-allResponse:
{
"success": true,
"message": "All tenders processed",
"summary": {
"eligible": 0,
"notEligible": 2,
"total": 2
},
"results": {
"tender1": {
"success": true,
"eligible": false,
"decision": "NO",
"emailSent": true
},
"tender2": {
"success": true,
"eligible": false,
"decision": "NO",
"emailSent": true
}
}
}POST /api/process-tender2-workflow
Complete automated workflow for Tender 2 with advanced features:
- Process 5 PDFs β Generate individual summaries
- Concatenate summaries β Combine all summaries
- Generate comprehensive summary β Create unified analysis
- Eligibility check β YES/NO decision
- Build Table B1 β Matching operations table (if eligible)
- Match SKUs β Intelligent SKU matching with scoring
- Calculate pricing β Real value extraction and pricing
- Generate holistic table β Combined summary table
- Email result β Send appropriate report
Example:
curl -X POST http://localhost:3000/api/process-tender2-workflowResponse (Eligible):
{
"success": true,
"message": "Tender 2 workflow completed successfully",
"eligibility": "YES",
"emailSent": true,
"workflowDir": "workflows/tender2",
"outputs": {
"summary1": "workflows/tender2/summary_1.txt",
"comprehensiveSummary": "workflows/tender2/comprehensive_summary.txt",
"eligibilityResult": "workflows/tender2/eligibility_result.txt",
"tableB1": "workflows/tender2/table_b1.csv",
"matchedSKUs": "workflows/tender2/matched_skus.txt",
"pricingTable": "workflows/tender2/pricing_table.csv",
"holisticTable": "workflows/tender2/holistic_summary_table.csv"
}
}Response (Not Eligible):
{
"success": true,
"message": "Tender 2 workflow completed - Company NOT eligible",
"eligibility": "NO",
"emailSent": true,
"docxPath": "analysis/tender2/eligibility_report.docx",
"workflowDir": "workflows/tender2"
}Required Input Files:
- 5 PDFs in
Tendor-2/directory Tender_SKU_Matching_Descriptions.txt(SKU master file)company_profile.json(company information)
Key Features:
- Conditional execution: Steps 5-9 only run if eligible
- Real value extraction from documents (no placeholders)
- CSV table outputs for structured data
- Intelligent SKU matching with weighted scoring
- Automated pricing calculations
- Import
postman_collection.jsoninto Postman - Configure environment variables if needed
- Start testing the endpoints
project-root/
βββ src/
β βββ controllers/
β β βββ tenderController.js # Tender PDF upload handling
β β βββ companyController.js # Company info upload handling
β β βββ analysisController.js # Eligibility analysis logic
β β βββ eligibilityController.js # Final eligibility check & email
β β βββ tender2WorkflowController.js # 9-step Tender 2 workflow
β βββ services/
β β βββ pdfService.js # PDF text extraction
β β βββ docxService.js # DOCX text extraction
β β βββ groqService.js # Gemini AI integration (all prompts)
β β βββ emailService.js # Email sending with attachments
β β βββ docService.js # DOCX report generation
β βββ utils/
β β βββ csvUtils.js # CSV conversion utilities
β β βββ distanceUtils.js # Distance calculation utilities
β β βββ docxTableUtils.js # DOCX table formatting
β βββ routes/
β β βββ apiRoutes.js # API endpoint definitions
β βββ config/
β βββ groqClient.js # Gemini client with key rotation
βββ uploads/ # Uploaded files (auto-generated)
β βββ tender1/
β βββ tender2/
β βββ company/
βββ summaries/ # Generated summaries (auto-generated)
β βββ tender1/
β βββ tender2/
βββ analysis/ # Analysis results (auto-generated)
β βββ tender1/
β βββ tender2/
βββ workflows/ # Tender 2 workflow outputs (auto-generated)
β βββ tender2/
βββ Tendor-1/ # Tender 1 input PDFs
βββ Tendor-2/ # Tender 2 input PDFs
βββ server.js # Express server entry point
βββ package.json # Dependencies and scripts
βββ .env # Environment variables (create from template)
βββ env.template # Environment variables template
βββ .gitignore # Git ignore rules
βββ README.md # Main documentation (this file)
βββ TENDER2_WORKFLOW_README.md # Detailed Tender 2 workflow docs
βββ QUICK_START.md # Quick start guide
βββ INSTALL.md # Installation guide
βββ POSTMAN_SETUP_GUIDE.md # Postman testing guide
βββ postman_collection.json # Postman API collection
βββ Tender_SKU_Matching_Descriptions.txt # SKU master file for matching
- Upload Tender PDFs β System extracts text and generates summaries
- Upload Company Info β System extracts and saves text
- Analyze Tender β System creates eligibility analysis table
- Check Eligibility β System decides YES/NO and emails if NO
- Process All β Automated workflow for both tenders
- Process 5 PDFs β Individual summaries generated
- Concatenate Summaries β Combined into single document
- Comprehensive Summary β Unified analysis created
- Eligibility Check β YES/NO decision made
- Build Table B1 β Matching operations table (if YES)
- Match SKUs β Intelligent matching with scoring (if YES)
- Calculate Pricing β Real value extraction and pricing (if YES)
- Generate Holistic Table β Combined summary table (if YES)
- Email Result β Appropriate report sent based on eligibility
The system uses Google's Gemini 2.5 Flash model with:
- Ultra-large context window (2M tokens support)
- Fast and efficient inference
- Cost-effective for large documents
- Excellent for summarization, analysis, and complex reasoning tasks
- Enhanced capabilities over previous versions
Current Model: gemini-2.5-flash (configured in src/config/groqClient.js)
Model Configuration:
- Default max output tokens: 65,536
- Adaptive timeout: 7 minutes for all requests
- Temperature: 0.3-0.7 (depending on task)
- Safety settings: Configured to BLOCK_NONE for all categories
Note: You can change the model in src/config/groqClient.js line 140.
- Subject: "Tender Eligibility Analysis Result - NOT ELIGIBLE - {TENDER_ID}"
- Body: "Please find attached the detailed eligibility analysis report."
- Attachment: DOCX file with eligibility table
- Subject: "Tender 2 - Holistic Summary Table - ELIGIBLE"
- Body: "Company is eligible for Tender 2. Please find attached the holistic summary table."
- Attachment: CSV file with holistic summary table
- Subject: "Tender 2 Eligibility Analysis Result - NOT ELIGIBLE"
- Body: "Please find attached the detailed eligibility analysis report."
- Attachment: DOCX file with eligibility analysis
The system implements an aggressive rotation strategy for optimal reliability:
- Multi-key support: Configure 1-4 Gemini API keys
- Aggressive rotation: Switches to next key on EVERY error (not just rate limits)
- Smart retry logic: Maximum retries = 3x number of configured keys
- Exponential backoff: For single-key setups with jitter
- Automatic recovery: Seamlessly handles quota exhaustion and rate limits
- System starts with API key #1
- On any error (rate limit, quota, timeout, etc.), immediately rotates to next key
- Tracks which keys have been attempted to avoid infinite loops
- After trying all keys, throws error with detailed message
- Short delay (1 second) after rotation to avoid cascading rate limits
GEMINI_API_KEY_1=your_first_key # Required
GEMINI_API_KEY_2=your_second_key # Optional
GEMINI_API_KEY_3=your_third_key # Optional
GEMINI_API_KEY_4=your_fourth_key # OptionalRecommendation: Use all 4 keys for maximum reliability and throughput.
All endpoints include comprehensive error handling and logging:
console.logfor successful operationsconsole.errorfor errors with detailed stack traces- Structured JSON error responses
- Automatic API key rotation on failures
- Graceful degradation with fallback mechanisms
- express: Web framework
- multer: File upload handling
- @google/generative-ai: Google Gemini AI API integration
- nodemailer: Email functionality with attachment support
- pdf-parse: PDF text extraction
- mammoth: DOCX text extraction
- docx: Generate DOCX reports with tables
- fs-extra: Enhanced file system operations
- dotenv: Environment variables management
- nodemon: Auto-reload during development
For more detailed information, refer to these guides:
- TENDER2_WORKFLOW_README.md - Detailed Tender 2 workflow documentation
- QUICK_START.md - Quick start guide
- INSTALL.md - Detailed installation instructions
- POSTMAN_SETUP_GUIDE.md - Postman testing guide
- Standard workflow: Upload β Analyze β Check β Email
- Tender 2 workflow: 9-step pipeline with SKU matching and pricing
- Comprehensive tender summarization
- Eligibility criteria extraction and matching
- Intelligent SKU matching with weighted scoring
- Real value extraction from documents
- Support for up to 4 Gemini API keys
- Aggressive rotation on every error
- Automatic retry with exponential backoff
- Maximum reliability and throughput
- PDF and DOCX text extraction
- CSV table generation
- DOCX report creation with formatted tables
- Real-time distance and pricing calculations
- Email reports for eligible and non-eligible cases
- DOCX and CSV attachments
- Customizable email templates
API Key Errors:
- Ensure all API keys are valid and active
- Check quota limits on Google AI Studio
- Verify
.envfile is properly configured
File Upload Issues:
- Check file size limits (default: no limit set)
- Ensure directories have write permissions
- Verify file formats (PDF, DOCX supported)
Email Not Sending:
- Verify SendGrid API key is correct and active
- Check sender email is verified in SendGrid dashboard
- Ensure SENDGRID_API_KEY and SENDGRID_FROM_EMAIL are set correctly
- Check SendGrid dashboard for delivery logs and errors
Workflow Failures:
- Check all required input files exist
- Review console logs for detailed error messages
- Verify API keys have sufficient quota
- Throughput: ~4x higher than single key
- Reliability: Automatic failover on errors
- Rate Limits: Distributed across multiple keys
- Recommended for: Production environments
- Throughput: Standard rate limits apply
- Reliability: Exponential backoff on errors
- Rate Limits: Single key quota
- Recommended for: Development/testing
For issues or questions:
- Check console logs for detailed error messages
- Review output files in respective directories
- Verify API response messages
- Check the additional documentation files
PORT=3000
GEMINI_API_KEY_1=your_first_gemini_api_key
GEMINI_API_KEY_2=your_second_gemini_api_key
GEMINI_API_KEY_3=your_third_gemini_api_key
GEMINI_API_KEY_4=your_fourth_gemini_api_key
SENDGRID_API_KEY=your_sendgrid_api_key
SENDGRID_FROM_EMAIL=your_verified_sender@example.com
EMAIL_TO=recipient@example.com# Install dependencies
npm install
# Start server
npm start
# Development mode (auto-reload)
npm run dev
# Test Gemini API
curl http://localhost:3000/api/test-gemini
# Health check
curl http://localhost:3000/health| Endpoint | Method | Description |
|---|---|---|
/api/upload-tender/:tenderId |
POST | Upload tender PDFs |
/api/upload-company |
POST | Upload company info |
/api/analyze-tender/:tenderId |
POST | Analyze eligibility |
/api/check-eligibility/:tenderId |
POST | Check & email result |
/api/process-all |
POST | Process all tenders |
/api/process-tender2-workflow |
POST | Run Tender 2 pipeline |
/api/test-gemini |
GET | Test Gemini API |
/health |
GET | Health check |
uploads/ β Uploaded PDFs and documents
summaries/ β AI-generated summaries
analysis/ β Eligibility analysis results
workflows/ β Tender 2 workflow outputs
Tendor-1/ β Tender 1 input PDFs
Tendor-2/ β Tender 2 input PDFs
ISC