I am trying to create a ticket in Freshdesk along with attachments, but I am getting an error.
The Error is:
TypeError: source.on is not a function
at Function.DelayedStream.create (/usr/local/lib/node_modules/fdk/node_modules/delayed-stream/lib/delayed_stream.js:33:10)
at FormData.CombinedStream.append (/usr/local/lib/node_modules/fdk/node_modules/combined-stream/lib/combined_stream.js:45:37)
at FormData.append (/usr/local/lib/node_modules/fdk/node_modules/request/node_modules/form-data/lib/form_data.js:74:3)
at appendFormValue (/usr/local/lib/node_modules/fdk/node_modules/request/request.js:326:21)
at Request.init (/usr/local/lib/node_modules/fdk/node_modules/request/request.js:337:11)
at new Request (/usr/local/lib/node_modules/fdk/node_modules/request/request.js:127:8)
at Function.request (/usr/local/lib/node_modules/fdk/node_modules/request/index.js:53:10)
at Request._tryUntilFail (/usr/local/lib/node_modules/fdk/node_modules/requestretry/index.js:124:23)
at Factory (/usr/local/lib/node_modules/fdk/node_modules/requestretry/index.js:178:7)
at Object.execute (/usr/local/lib/node_modules/fdk/lib/api/proxy.js:171:12)
My code:
var base64 = require('base-64');
exports = {
events: [{
event: 'onConversationCreate',
callback: 'onConversationCreateHandler'
onConversationCreateHandler: function (args) {
console.log('onConversationCreateHandler event');
test();
function test() {
console.log("in testttttttttttttt");
var url = "https://xxxxxxxxxxx.freshdesk.com/api/v2/tickets";
var apiKEY = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
var headers = {
"Content-Type": "multipart/form-data",
"Authorization": "Basic " + base64.encode(apiKEY)
var a = {
"file": "/home/artis/Music/ask"
var formData = {
"description": "support ticket....",
"subject": "support ticket...",
"email": "[email protected]",
"attachments[]": a
var options = {
formData: formData,
headers: headers
console.log(url);
console.log(options);
$request.post(url, options).then(function (data) {
console.log("sssssssssssssssssssssssssss", data);
}, function (error) {
console.log(error);
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": "[email protected]",
"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: image1612×1096 72.9 KB
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.
Did learn that the new request template (2.3) doesn not support attachment…
This is my code:
async function createPrivateNoteAttachment(user, args) {
try {
console.log('hi from createPrivateNoteAttachment ');
var domain = args.iparams.domain;
var api_key = args.iparams.api_key;
var payload = {};
var body = {};
body.body = args.data.conversation.body;
body.private = true;
body.user_id = user;
payload.body = body;
var url = `https://${domain}.freshdesk.com/api/tickets/${args.data.conversation.ticket_id}`;
var headersOpt = {
Authorization: 'Basic ' + base64.encode(`${api_key}:x`),
headersOpt['Content-Type'] = 'multipart/form-data';
var httpcall = unirest.post(url);
httpcall.headers(headersOpt);
httpcall.field(payload.body);
for (var i = 0; i < args.data.conversation.attachments.length; i++) {
httpcall.attach(
'attachments[]',
args.data.conversation.attachments[i].attachment_url,
filename: args.data.conversation.attachments[i].name,
contentType: args.data.conversation.attachments[i].content_type,
return await httpcall;
} catch (error) {
console.error(‘Error in [createPrivateNoteAttachment]’, JSON.parse(error));
Get this error:
statusCode: 415
statusMessage: Unsupported Media Type