async function getPdfFromEmail(sender, recipient, emailSubject, emailContent, saveDir = './Downloads/') {
let attempts = 0;
let targetEmail = null;
// Get auth token
const token = await fetchAuthToken(
clientConfig.ID,
clientConfig.SECRET,
clientConfig.REFRESH
);
// Search for email
while (!targetEmail && attempts < 5) {
targetEmail = await searchGmail({
auth: token,
searchParams: `from:${sender} to:${recipient} subject:${emailSubject} ${emailContent} has:attachment`,
detailLevel: 'complete'
});
if (!targetEmail) {
attempts++;
console.log(`Email not found. Trying again (${attempts}/5)`);
await delay(5000);
}
}
if (!targetEmail) {
console.log('Email search failed after 5 attempts');
return null;
}
// Ensure save directory exists
if (!fs.existsSync(saveDir)) {
fs.mkdirSync(saveDir, { recursive: true });
}
try {
// Find PDF attachment
const findPdf = (part) => {
if (part.mimeType === 'application/pdf' && part.body?.attachmentId) {
return part;
}
return part.parts?.find(findPdf) || null;
};
const pdfAttachment = findPdf(targetEmail.payload);
if (!pdfAttachment) {
console.log('No PDF found in email');
return null;
}
// Get attachment content
const pdfContent = await searchGmail({
auth: token,
emailId: targetEmail.id,
attachmentId: pdfAttachment.body.attachmentId
});
if (!pdfContent?.data) {
console.log('Failed to get PDF content');
return null;
}
// Save PDF
const fileName = pdfAttachment.filename || 'download.pdf';
const filePath = path.join(saveDir, fileName);
fs.writeFileSync(filePath, Buffer.from(pdfContent.data, 'base64'));
console.log(`PDF saved: ${filePath}`);
return filePath;
} catch (err) {
console.error(`Error: ${err.message}`);
return null;
}
}
I’m trying to get PDF attachments from Gmail but I’m running into issues with nested MIME structures. The current code finds the PDF part but gets stuck in a loop when trying to fetch the data. How can I fix this to properly handle nested structures and avoid infinite loops? Any tips on simplifying the attachment retrieval process would be great too.