The reason why TypeError: source.on...
error occurs in this context is primarily because formData
accepts only String / Buffer / Stream types for its properties. A straightforward solution would be to convert it to one of those types. However, that leads us to couple of other issues
-
JSON.stringify()
on file object is not going to work the way we expect and will technically result in an error
{"description":"Validation failed","errors":[{"field":"attachments",
"message":"It should contain elements of type valid file format only",
"code":"datatype_mismatch"}]}
- The right choice would be to create a readable file stream. However, since our app runs in AWS lambda, maintaining files/assets inside the app won’t scale and would be technically challenging. If it were a local machine or a secure middleware running the logic,
fs
would be handy in creating a stream and it can be appropriately passed while making the call
As I see from your code, the intent is to attach a specific file during ticket creation. I just gave a shot with unirest
NPM package - which has a simpler interface and also supports reading remote file streams. This also could keep the middleware lean. For example,
var unirest = require('unirest');
exports = {
events: [{
event: 'onAppInstall',
callback: 'aiHandler'
}],
aiHandler: function (args) {
/* Substitute with the right handler and event. This is just to demo */
logger('--Inside App Install Handler--');
logger(args);
attFile();
renderData();
}
};
function attFile(){
logger("--Let's attach a file --");
var url = "https://xxx.freshdesk.com/api/v2/tickets";
var apiKEY = "yyy";
var headers = {
"Content-Type": "multipart/form-data",
"Authorization": "Basic " + apiKEY
};
var fields = {
"description": "support ticket....",
"subject": "support ticket...",
"email": "example@example.com",
"status":"2", // certain fields are required during creation
"priority":"1"
};
// Lets make use of unirest to attach files from our secure file store/s3/...
unirest.post(url)
.headers(headers)
.field(fields)
.attach('attachments[]', 'https://i.imgur.com/lcB62xb.jpg')
.attach('attachments[]', 'https://gist.githubusercontent.com/hemchander23/6708ad5595dd56ef31087d47d4f96a44/raw/89ab0df9685cac94bbb88e1ebfd3655bcade6c9d/DarkS1E4_Script.txt#')
.attach('attachments[]', 'https://www.gstatic.com/covid19/mobility/2020-05-25_US_Mobility_Report_en.pdf')
.end(function(response){
logger(response.body)
logger("Response Status : " + response.status)
if(response.status == 201){
logger("Location Header : "+ response.headers['location'])
}
else{
logger("X-Request-Id :" + response.headers['x-request-id']);
}
});
}
function logger(dat){
console.log(dat);
}
will create a ticket like so:
It is very important to note that the file storage service that you use has to be secure and must generate short-lived (possibly signed as well) links that are only valid for the ticket creation session. Upon creation of the ticket, you will notice that the attachments have a link of their own.