Email PDF attachment content missing image - node.js

I call Gmail API using a nodejs script using the request library (not the google one).
When I write the attachment response into a pdf file, I can see that the content is incomplete (missing images, missing styles, etc...).
Code:
const attachment: IGoogleMailUserMessageAttachmentResource = await this.call(
'GET',
`/${message.id}/attachments/${part.body.attachmentId}`,
);
writeFileSync('/tmp/test.pdf', attachment.content, { flag: 'w+' });
Received file :
instead of :
Any idea ?
Thanks

Related

Add attachments to Invoices in Xero using node js SDK or API

I am trying to add attachments to existing invoices in xero.
I am using xero-node sdk (https://github.com/XeroAPI/xero-node#readme) for this integration and they provide a method for adding attachment as follows:
this.xero.accountingApi.createInvoiceAttachmentByFileName(tenantId, invoiceid, filenameInvoice,includeOnline,readStream )
The issue here is it requires an fs.ReadStream object for readStream.
The file I am trying to upload is present in cloud and I cannot download it and store it in file system before sending to Xero. I want to send the file present in azure cloud directly to xero. I have the url of file so I can get the content as a variable by making http request but there is no option to send this content to Xero.
There is an API available for this as well (here https://developer.xero.com/documentation/api/attachments) apart from the sdk. But I am not sure how I can send the file that I have to this API in body as it expects RAW data. Are there any specific headers or encodings required to call this API with file content in body? Because this is also not working for me if I just pass the body of the response I got from azure file url, as body to this Xero Attachment API. It tries for a long time and gives timeout error.
yes you are correct. There are additional headers/manipulation you need to do to upload files.
Please checkout the sample app - we've got it queued up to show exactly how to upload files: https://github.com/XeroAPI/xero-node-oauth2-app/blob/master/src/app.ts#L1188
Something like the following should get you sorted:
import * as fs from "fs";
const path = require("path");
const mime = require("mime-types");
const totalInvoices = await xero.accountingApi.getInvoices('your-tenantId-uuid', undefined, undefined, undefined, undefined, undefined, undefined, ['PAID']);
// Attachments need to be uploaded to associated objects https://developer.xero.com/documentation/api/attachments
// CREATE ATTACHMENT
const filename = "xero-dev.png";
const pathToUpload = path.resolve(__dirname, "../path-to-your.png");
const readStream = fs.createReadStream(pathToUpload);
const contentType = mime.lookup(filename);
const fileAttached = await xero.accountingApi.createInvoiceAttachmentByFileName(req.session.activeTenant.tenantId, totalInvoices.body.invoices[0].invoiceID, filename, true, readStream, {
headers: {
"Content-Type": contentType,
},
});
I ended up adding the link to file in History and Notes section of the invoice. Even though this is not the best solution, It serves the purpose of showing invoices to the customer.
Thanks to #SerKnight for your answer.

Node buffer doesn't properly download file?

I'm successfully sending a get request that generates a pdf on the server, which I now want to send back to client and download it on their browser. The npm pdf generating library I'm using is called html-pdf and has the following options:
pdf.create(html).toFile([filepath, ]function(err, res){
console.log(res.filename);
});
pdf.create('<h1>Hi</h1>').toBuffer(function(err, buffer){
console.log('This is a buffer:', Buffer.isBuffer(buffer));
});
When I use the toFile option, the file gets correctly generated, however, when I use the toBuffer option and send that back to the user, the resulting pdf is blank.
I send the buffer to the user from my ajax handler like this:
module.exports = function(req, res) {
pdf.create(html).toBuffer(function(err, buffer){
res.setHeader('Content-Disposition', 'attachment; filename=panda.pdf');
res.setHeader('Content-Type', 'application/pdf');
res.send(buffer)
});
};
which gets received on the client here:
$.get('generatePdf', function(data, status) {
const url = window.URL.createObjectURL(new Blob([data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', 'file.pdf');
document.body.appendChild(link);
link.click();
})
For some reason though the pdf that is downloaded is blank. Does anyone know what I might be doing wrong?
My downloaded file is corrupt according to this online pdf validator with the following errors:
Result Document does not conform to PDF/A. Details Validating file
"file (8).pdf" for conformance level pdf1.4
The 'xref' keyword was not found or the xref table is malformed. The
file trailer dictionary is missing or invalid. The "Length" key of the
stream object is wrong. Error in Flate stream: data error. The
document does not conform to the requested standard. The file format
(header, trailer, objects, xref, streams) is corrupted. The document
does not conform to the PDF 1.4 standard.

Slack Attachment error : private_url is undefined

I have a simple code that's supposed to download images from slack messages.
var url = message.file.private_url;
var destination_path = './tmp/uploaded';
var opts = {
method: 'GET',
url: url,
headers: {
Authorization: 'Bearer ' + process.env.botToken,
}
};
request(opts, function(err, res, body) {
console.log('FILE RETRIEVE STATUS',res.statusCode);
}).pipe(fs.createWriteStream(destination_path));
The code worked fine for a while, but now I'm getting this error:
An error occured in the receive middleware: TypeError: Cannot read property 'private_url' of undefined
Any help would be appreciated!
Are you using the events API?
Several changes have been made to the API recently (both Events and Web APIs). See here: https://api.slack.com/changelog/2018-05-file-threads-soon-tread
If you describe the API you're using, I might be able to provide more specific help but I suspect the issue (as described in the link above) is that the file attribute attached to messages has been replaced with a new files field (an array). The files in the array are also in a different format.
Check the JSON payload. It probably contains a files array.

POST request to retrieve pdf in node.js

I am making a POST request to retrieve a pdf. The request works fine if I do it in postman, but I get an empty pdf if I do it through node.js using the request package. Here's my request using the request package:
let body = {
attr1: "attr1",
attr2: "attr2"
}
let opts = {
url: "some_url",
method: "post",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body
}
request(requestOpts).then(pdf => {
console.log(pdf) // prints out the binary version of the pdf file
fs.writeFileSync("testing.pdf", pdf);
});
I use the exact same request parameters when I use postman but it returns the pdf w/ the correct content.
Can someone help? Or is the way I am saving my pdf incorrect?
Thanks in advance!
Solution - i had to set encoding: false in the request options.
Try
fs.writeFileSync("testing.pdf", pdf, 'binary');
The third argument here tells fs to write binary rather than trying to UTF-8 encode it.
According to the docs the third paramter should be a string that represents the encoding.
For pdf files the encoding is 'application/pdf'
So this should work for you : fs.writeFileSync("testing.pdf", pdf, 'application/psf');

How to Send Pdf as MMS by Twilo Using Nodejs?

I have a Test Twilio Number which is capable to send SMS,MMS,Voice Call . I am Successful in sending SMS and Voice call .
I am facing a challenge to send PDF as MMS .. As per the TwilioDocs Accepted-mime-types PDF is a Supported Type.
While am trying to Send by using the Syntax :-
var accountSid = '<accountSid >';
var authToken = '<authToken>';
var client = require('twilio')(accountSid, authToken);
client.messages.create({
to: "<validnum>",
from: "<validFrom>",
body: "Test Message ",
mediaUrl: "http://docdro.id/GAak2pV"
mediaContentType:"pdf"
}, function(err, message) {
if(err){
console.log('Error Alert For Message '+JSON.stringify(err));
}else{
console.log(message.sid);
}
});
With the Above Code i can able to send JPG/PNG but PDF is being Failed by an Error:-
(Error: 30008) Unknown error. None
I have no clue Totally !! Somebody help me with a Saving Suggestion
Thanks,
Prasad.
Twilio developer evangelist here.
As Andy is pointing out in the comments, the URL to DropBox that you are using is actually pointing towards an HTML page that contains your PDF. You need the direct link to the PDF file itself, Twilio does not do any work to discover the PDF file within pages.
If you can host the file on S3, or anywhere else publicly, yourself then you will have more luck with this.

Resources