🔍 Why Your Attachment Was Empty
Date: November 5, 2025
Issue: Email sent, but PDF attachment was empty
Root Cause: Missing base64 content in the request
📧 WHAT YOU SAW
Your .eml file showed:
--boundary
Content-Disposition: attachment; filename="attachment"
Content-Transfer-Encoding: base64
Content-Type: application/octet-stream; name="attachment"
← NOTHING HERE! Empty!
--boundary--
The attachment structure was there, but the PDF data was missing!
❌ WHAT WENT WRONG
Your Request Probably Looked Like This:
{
"businessId": "...",
"recipientContact": "luisrangelc@gmail.com",
"channel": "email",
"type": "invoice",
"subject": "Your Invoice #430",
"content": "Plain text or HTML",
"attachments": [
{
"filename": "invoice.pdf",
"fileUrl": "https://..." // ❌ fileUrl doesn't work!
}
]
}
OR:
{
"attachments": [
{
"filename": "invoice.pdf",
"content": "", // ❌ Empty!
"mimeType": "application/pdf"
}
]
}
OR:
{
"attachments": [
{
"filename": "invoice.pdf",
"mimeType": "application/pdf"
// ❌ Missing content entirely!
}
]
}
✅ WHAT IT SHOULD LOOK LIKE
Correct Request:
{
"businessId": "33b6db4b-51c5-45ee-8d04-c01c2d157f66",
"createdBy": "6c0c4f32-d74a-4a84-892f-3bead447d765",
"recipientContact": "luisrangelc@gmail.com",
"channel": "email",
"type": "invoice",
"subject": "Your Invoice #430",
"content": "<p>Invoice attached</p>",
"attachments": [
{
"filename": "invoice.pdf",
"content": "JVBERi0xLjQKJeLjz9MyCjYgMCBvYmoKPDwvTGluZWFyaXplZCAxL0wgMzQ2NzQvTyA4L0UgMjEzNjQvTiAxL1QgMzQzODUvSCBbIDUxNiAxNTRdPj4...",
"mimeType": "application/pdf"
}
]
}
See the content field? That's the base64-encoded PDF! It MUST be there!
🎯 THE CORRECT WORKFLOW
┌─────────────────────────────────────────┐
│ STEP 1: Generate PDF │
│ POST /communications/generate-pdf │
│ │
│ Request: │
│ { │
│ "templateType": "invoice", │
│ "templateData": { ... } │
│ } │
│ │
│ Response: │
│ { │
│ "filename": "invoice.pdf", │
│ "content": "JVBERi0x...", ← COPY! │
│ "mimeType": "application/pdf" │
│ } │
└─────────────────────────────────────────┘
↓
COPY THE BASE64 CONTENT
↓
┌─────────────────────────────────────────┐
│ STEP 2: Send Email with PDF │
│ POST /communications/send │
│ │
│ Request: │
│ { │
│ "recipientContact": "email@...", │
│ "channel": "email", │
│ "subject": "Invoice", │
│ "attachments": [ │
│ { │
│ "filename": "invoice.pdf", │
│ "content": "PASTE_HERE", ← PASTE│
│ "mimeType": "application/pdf" │
│ } │
│ ] │
│ } │
└─────────────────────────────────────────┘
↓
EMAIL SENT WITH PDF!
↓
┌─────────────────────────────────────────┐
│ Gmail Inbox: │
│ 📧 Subject: Invoice │
│ 📎 Attachment: invoice.pdf (12 KB) │
│ │
│ [Open] [Download] ✅ │
└─────────────────────────────────────────┘
🔧 WHY DID VALIDATION PASS?
The AttachmentDto allows content to be optional:
export class AttachmentDto {
@IsString()
@IsNotEmpty()
filename!: string; // Required
@IsString()
@IsOptional()
content?: string; // Optional ← This is why!
@IsString()
@IsOptional()
mimeType?: string; // Optional
}
So the validation passed even though content was empty!
Future improvement: We could make content required, but that would break the flexibility of supporting both file URLs and base64 content.
🚀 HOW TO FIX IT
Option 1: Use the Automated Test Script
# Run the complete workflow automatically
./docs/Multi-Channel-Communication-System/TEST-PDF-WORKFLOW.sh
This script:
- ✅ Generates the PDF
- ✅ Extracts the base64 content
- ✅ Sends the email with the PDF
- ✅ Verifies it worked
Option 2: Manual (2 Steps)
# Step 1: Generate PDF and save content
curl -X POST 'http://localhost:4000/communications/generate-pdf' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer YOUR_TOKEN' \
-d '{
"templateType": "invoice",
"templateData": {
"invoiceNumber": "INV-431",
"companyName": "RPA Solution",
"customerName": "John Doe",
"totalAmount": "$500.00"
}
}' | jq -r '.content' > pdf-base64.txt
# Step 2: Send with that content
PDF_CONTENT=$(cat pdf-base64.txt)
curl -X POST 'http://localhost:4000/communications/send' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer YOUR_TOKEN' \
-d '{
"businessId": "33b6db4b-51c5-45ee-8d04-c01c2d157f66",
"createdBy": "6c0c4f32-d74a-4a84-892f-3bead447d765",
"recipientContact": "luisrangelc@gmail.com",
"channel": "email",
"type": "invoice",
"subject": "Invoice #431 - WITH REAL PDF!",
"content": "<p>PDF is attached!</p>",
"attachments": [{
"filename": "invoice-431.pdf",
"content": "'"$PDF_CONTENT"'",
"mimeType": "application/pdf"
}]
}'
📋 VERIFICATION CHECKLIST
After sending, verify:
- Email received in Gmail
- Subject line is correct
- Attachment icon 📎 is visible
- Attachment has correct filename (invoice-431.pdf)
- Attachment has size (not 0 KB)
- Can click "Download" button
- PDF opens correctly
- PDF shows the invoice data
🎉 EXPECTED RESULT
In Gmail:
📧 From: RPA <info@rpasolution.com>
To: luisrangelc@gmail.com
Subject: Invoice #431 - WITH REAL PDF!
PDF is attached!
📎 invoice-431.pdf (15 KB) [Download]
When you click the PDF:
┌─────────────────────────────────┐
│ INVOICE │
│ #INV-431 │
│ │
│ RPA Solution │
│ Customer: John Doe │
│ │
│ Total: $500.00 │
│ │
│ [Invoice details here] │
└─────────────────────────────────┘
🔍 HOW TO DEBUG
Check if PDF was generated:
curl -X POST 'http://localhost:4000/communications/generate-pdf' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer YOUR_TOKEN' \
-d '{"templateType":"invoice","templateData":{"invoiceNumber":"TEST"}}' \
| jq '.content' | wc -c
Expected: Should show a large number (e.g., 15000+ characters)
If it shows 0 or "null": PDF generation failed!
Check attachment in database:
curl -X GET 'http://localhost:4000/communications/COMM_ID/attachments' \
-H 'Authorization: Bearer YOUR_TOKEN' | jq '.'
Expected: Should show attachment records
If empty: Attachments weren't saved to DB
✅ SUMMARY
Problem: Empty attachment
Cause: Missing base64 content in request
Solution: Call /generate-pdf first, then include the base64 in /send
Status: Fixed with new workflow and test script
Try the test script now! 🚀
./docs/Multi-Channel-Communication-System/TEST-PDF-WORKFLOW.sh
Document Version: 1.0
Last Updated: November 5, 2025, 12:30 PM
Status: ✅ Issue identified and resolved