Hi,
We are trying to send a reply to a ticket that includes an attachment:
https://oursubdomain.freshdesk.com/api/v2/tickets/{ticketID}/reply
The example here: fresh-samples/create_ticket_custom_fields_and_attachements.js at master · freshworks/fresh-samples · GitHub shows the file being attached to the request using fs.createReadStream. Our file is stored in memory so we have tried to swap out the fs.createReadStream approach to use the equivalent for in memory files. This approach takes the file buffer and uses the Readable method from nodes stream api to create the stream:
var tmp = require("tmp");
const {Readable} = require('stream');
function bufferToStream(myBuffer) {
let stream = new Readable();
stream.push(myBuffer);
stream.push(null);
return stream;
}
var unirest = require('unirest');
var fs = require('fs');
exports.handler = async (event, context, callback) => {
var API_KEY = "ourkey";
var FD_ENDPOINT = "ourdomain";
var PATH = "/api/v2/tickets";
var enocoding_method = "base64";
var auth = `Basic ${Buffer.from(`${API_KEY}`).toString('base64')}`;
const ticketId = '79';
var URL = `https://${FD_ENDPOINT}.freshdesk.com/api/v2/tickets/${ticketId}/reply`;
const base64String = fs.readFileSync('base64.txt', 'utf8');
const binaryBuffer = Buffer.from(base64String, 'base64');
// create the stream from the buffer here
const stream = bufferToStream(binaryBuffer);
var fields = {
body: 'test',
}
var headers = {
'Authorization': auth
}
// fails with [ERR_HTTP_INVALID_HEADER_VALUE]: Invalid value "undefined" for header "Content-Length"
//caused by unirest are using the NPM module form-data, and the form-data module requires that if it received a stream that not fs.ReadStream
//https://github.com/Kong/unirest-nodejs/issues/126
unirest.post(URL)
.headers(headers)
.field(fields)
.attach('attachments[]', stream)
.end(function(response){
console.log(response.body)
console.log("Response Status : " + response.status)
if(response.status == 201){
console.log("Location Header : "+ response.headers['location'])
}
else{
console.log("X-Request-Id :" + response.headers['x-request-id']);
}
});
}
However executing this code results in an error: TypeError [ERR_HTTP_INVALID_HEADER_VALUE]: Invalid value "undefined" for header "Content-Length"
. This github issue explains why this happens. Passing a Buffer to .attach · Issue #126 · Kong/unirest-nodejs · GitHub
Because the example code could not be altered to work with our in memory files we wrote our own code using the FormData module. This code does create a multipart form and sends it to freshdesk but we receive an error: 502: Bad Gateway “Request failed with status code 502”.
const axios = require('axios');
const FormData = require('form-data');
const fs = require('fs');
const {Readable} = require('stream');
function bufferToStream(myBuffer) {
let stream = new Readable();
stream.push(myBuffer);
stream.push(null);
return stream;
}
const apiCall = async (url, method, headers, data = {}) => {
const config = {
method,
url,
headers,
data,
};
const response = await axios(config);
console.log(response);
return response;
};
exports.handler = async (event, context, callback) => {
const domain = 'ourdomain';
const key = 'ourkey';
const ticketId = '79';
const base64String = fs.readFileSync('base64.txt', 'utf8');
let success = false;
const url = `https://${domain}.freshdesk.com/api/v2/tickets/${ticketId}/reply`;
const headers = {
Authorization: `Basic ${Buffer.from(`${key}`).toString('base64')}`,
};
var fields = {
body: 'test',
}
const form = new FormData();
const binaryBuffer = Buffer.from(base64String, 'base64');
const stream = bufferToStream(binaryBuffer);
form.append('attachments[]', stream, {
filename: 'base64.txt',
});
// form.submit(url, function(err, res) { console.log(err); });
try {
// const test = await apiCall(showTicket, 'GET', testHeaders);
const response = await apiCall(url, 'POST', headers, form);
console.log(response.data);
} catch (error) {
console.log(error.response.data.errors);
console.log({ success, error: error.message });
}
};
Can anyone help us with this?