Open ZuritaKelvin opened 1 week ago
Can I fix this Issue? I am a Full-Stack Software Developer and work with various Tech Stack like MERN , NEXT , REACT , FLUTTER, C#.
Of course! Below I will give more details about what I am trying to do and how I have been doing it. First in app/api/createInvoice/route.ts create the following endpoint to make the request to the API: `import axios from 'axios';
export async function POST(req: Request) { const apiKey = process.env.INVOICE_GENERATOR_API_KEY; if (!apiKey) { return Response.json({ error: 'Missing API key' }, { status: 401 }); }
try { const invoiceData = await req.json(); if (!invoiceData) { return Response.json({ error: 'Missing invoice data' }, { status: 400 }); }
const response = await axios.post('https://invoice-generator.com', invoiceData, {
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
});
if (!response || !response.data) {
return Response.json({ error: 'Failed to generate invoice' }, { status: 500 });
}
return Response.json({ blob: response.data });
} catch (error) {
return Response.json({ error: 'Failed to generate invoice' }, { status: 500 });
}
}
I make the request from the function that is responsible for calling this endpoint, obtaining the response and converting it to a File:
axios
.post('http://localhost:3000/api/createInvoice', invoice, {
headers: {
'Content-Type': 'application/json',
},
})
.then((response) => {
if (!response.data) return;
if (!data.crm) return;
const crm = data.crm as File;
const { blob } = response.data;
if (!blob) return;
const pdf = new File([blob], CRM_${invoice.number}_${invoice.date}.${fileTypeByUrl(crm.name)}
, {
type: 'application/pdf',
}); Then I send this file along with more data to another endpoint that is responsible for sending an email with the files:
formData.append('crm', data.crm);
formData.append('crmName', CRM_${invoice.number}_${invoice.date}.${fileTypeByUrl(crm.name)}
);
formData.append('inv', pdf);
formData.append('invName', Factura_${invoice.number}_${invoice.date}.pdf
);
formData.append('clientName', data.clientName);
formData.append('dealerName', data.dealerName);
formData.append('destination', data.destination);
formData.append('date', data.date);
formData.append('invoiceNumber', invoice.number);
axios
.post('http://localhost:3000/api/send', formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
})
.then((response) => {
console.log(response.data);
setNotify(alert.successAlert('Factura enviada con exito', setNotify));
})
.catch((error) => {
console.error(error);
setNotify(alert.errorAlert('Error al enviar la factura', setNotify));
});`
that endpoint use Resend.
The main problem is that when receiving the email, the generated PDF shows a blank page without information.
I made this issue here assuming that the problem is when generating the pdf file or when obtaining it.
any help is welcome.thx
Open this Issue I will solve this
Is this issue not already open? The status is open. What exactly do you mean? This is the first time I've made an issue. Could you explain?
okay let me check again. I was having a network glitch not refreshing the Page But All is ok
Your Issue : This issue is likely related to how the PDF is being generated or how the data is being fetched and sent. Issue: The generated PDF file is showing a blank page when received via email. let me fix this
Code with fixes for generating the PDF and sending it via email.
createInvoice/route.ts (Invoice Generation Endpoint) :
import axios from 'axios';
export async function POST(req: Request) { const apiKey = process.env.INVOICE_GENERATOR_API_KEY; if (!apiKey) { return new Response(JSON.stringify({ error: 'Missing API key' }), { status: 401 }); }
try { const invoiceData = await req.json();
console.log('Invoice Data:', invoiceData);
if (!invoiceData) {
return new Response(JSON.stringify({ error: 'Missing invoice data' }), { status: 400 });
}
const response = await axios.post('https://invoice-generator.com', invoiceData, {
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
});
console.log('API Response:', response.data);
if (!response || !response.data) {
return new Response(JSON.stringify({ error: 'Failed to generate invoice' }), { status: 500 });
}
return new Response(JSON.stringify({ blob: response.data }), { status: 200 });
} catch (error) { console.error('Error generating invoice:', error); return new Response(JSON.stringify({ error: 'Failed to generate invoice' }), { status: 500 }); } }
axios .post('http://localhost:3000/api/createInvoice', invoice, { headers: { 'Content-Type': 'application/json', }, }) .then((response) => { if (!response.data) return;
const { blob } = response.data;
console.log('Received Blob:', blob);
if (!blob) return;
const pdf = new File([blob], `CRM_${invoice.number}_${invoice.date}.pdf`, {
type: 'application/pdf',
});
sendEmailWithInvoice(pdf);
}) .catch((error) => { console.error('Error generating PDF:', error); });
Email Sending Function:
function sendEmailWithInvoice(pdf) {
const formData = new FormData();
formData.append('crm', data.crm);
formData.append('crmName', CRM_${invoice.number}_${invoice.date}.pdf
);
formData.append('inv', pdf);
formData.append('invName', Factura_${invoice.number}_${invoice.date}.pdf
);
formData.append('clientName', data.clientName);
formData.append('dealerName', data.dealerName);
formData.append('destination', data.destination);
formData.append('date', data.date);
formData.append('invoiceNumber', invoice.number);
axios .post('http://localhost:3000/api/send', formData, { headers: { 'Content-Type': 'multipart/form-data', }, }) .then((response) => { console.log('Invoice sent successfully:', response.data); setNotify(alert.successAlert('Factura enviada con exito', setNotify)); }) .catch((error) => { console.error('Error sending the invoice:', error); setNotify(alert.errorAlert('Error al enviar la factura', setNotify)); }); }
I have made the necessary fixes based on your requirements for generating the PDF and sending it via email. Check this and run this In Your Coding Environment. Copy this code and run it in your project. Let me know if this resolves the issue, or if you encounter any other problems.
Thank you very much for your contribution. I just found the solution on my own but I will check if this way works and I will let you know. In the meantime this has been the solution that worked for me to receive and be able to view the pdf correctly:
First the endpoint returns the file encrypted on base63 string: `import axios from 'axios';
export async function POST(req: Request) { const apiKey = process.env.INVOICE_GENERATOR_API_KEY; if (!apiKey) { return Response.json({ error: 'Missing API key' }, { status: 401 }); }
try { const invoiceData = await req.json(); if (!invoiceData) { return Response.json({ error: 'Missing invoice data' }, { status: 400 }); }
const response = await axios.post('https://invoice-generator.com', invoiceData, {
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
'Content-Disposition': 'attachment; filename="invoice.pdf"',
},
responseType: 'arraybuffer',
});
if (!response || !response.data) {
return Response.json({ error: 'Failed to generate invoice' }, { status: 500 });
}
const invoiceBuffer = Buffer.from(response.data);
const invoiceBase64 = invoiceBuffer.toString('base64');
return Response.json(invoiceBase64);
} catch (error) { return Response.json({ error: 'Failed to generate invoice' }, { status: 500 }); } } ` I directly pass the response to the other endpoint:
const file = response.data; formData.append('inv', file);
Finally i convert the stringBase64 to a Buffer and send it in the POST request:
const invoiceFile = formData.get('inv') as string; const pdfFile = Buffer.from(invoiceFile, 'base64');
I'm surprised that someone helped me so quickly after creating the issue. Many thanks to @syedmaazsaeed.
I m trying to build and proyect with Next.js and this invoice generator api but i cant found any example of an inplementation with Next.js or other framework.