I'm using Xero's createInvoiceAttachmentByFileName function to attach a file to an invoice. The file is stored in S3, so I first generate a pre-signed URL, fetch the file using that URL, convert the response into a buffer, and then pass that buffer into the Xero function.
The upload completes without errors, but when I download the attachment from Xero, the file is corrupted—it either fails to open or displays as raw buffer data.
Has anyone encountered this? Is there a specific encoding or buffer handling step I might be missing when working with signed S3 URLs and Xero's API?
My Code as below:
const downloadFileFromS3 = async (url) => {
const res = await axios.get(url, { responseType: 'arraybuffer' });
return Buffer.from(res.data);
};
const uploadSingleAttachment = async (tenantId, invoiceId, s3Url) => {
await getTokenSet();
const includeOnline = true;
const idempotencyKey = uuidv4();
const parsedUrl = new URL(s3Url?.file);
const pathname = parsedUrl.pathname;
const fileName = pathname.substring(pathname.lastIndexOf('/') + 1);
const fileBuffer = await downloadFileFromS3(s3Url?.file);
const mimeType = s3Url?.mimType;
return await xero.accountingApi.createInvoiceAttachmentByFileName(
tenantId,
invoiceId,
fileName,
fileBuffer,
includeOnline,
idempotencyKey,
{
headers: {
"Content-Type": mimeType
}
}
);
};
Attachment has been uploaded using my above code but it's corrupted. It's should not corrupted.