π 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