Search code examples
javascriptfile-uploadbackand

In Backand how do I upload a file from node.js action?


I'm experiencing problems with the Upload feature. Here's my case. I have: a SQL query, a node.js action that generates .xlsx report using that query, and an upload action to store generated report. My problem is that if I invoke upload action from the node.js code (using BackandSdk), the file content is written in octets rather than actual binary data. But when I invoke it from browser with exactly the same JSON body, everything works just fine. Here's an excerpt from the downloaded file:

504b 0304 0a00 0000 0000 0000 2100 3b48
8e40 c404 0000 c404 0000 1300 0000 5b43
6f6e 7465 6e74 5f54 7970 6573 5d2e 786d
6c3c 3f78 6d6c 2076 6572 7369 6f6e 3...

Any ideas on what I'm doing wrong?

UPDATE: The code of node.js action (only the code related to this question):

var BackandSdk = require('./backand');
var backand = new BackandSdk();

var masterToken = "<master token>"; //<put here the master token that you run in the action init>;
var userToken = "<user token>"; //<put here the user token that you run in the action init>;
var token = masterToken + ":" + userToken;

exports.generateMonthlyReport = generateMonthlyReport;

function generateMonthlyReport(month, userId) {    
    return backand.basicAuth(token)
        .then(function () {
            return backand.get('/1/query/data/monthlyReport', {
                month: month
            });
        })
        .then(function (result) {
            // build xlsx report using xlsx-template
            // returns promise that resolves with binary data
            return generateXls('monthly-timelog.xlsx', {
                data: result,
                total: sumTotal(result)
            });
        })
        .then(function (reportData) {
            var name = 'timelog-' + month.toLowerCase() + '.xlsx';
            return deleteReport(name).then(function () {
                return uploadReport(name, reportData);
            });
        })
        .catch(function (err) {
            console.log(err.stack);
            return q.reject(err);
        });

    function sumTotal(rows) {
        return rows.reduce(function (total, row) {
            return total + row.total;
        }, 0);
    }
}

uploadReport function that performs the actual upload:

function uploadReport(reportName, reportData) {
    var base64 = new Buffer(reportData).toString('base64');
    return backand.api.post('/1/objects/action/timeEntries?name=uploadReport', {
        filename: reportName,
        filedata: base64
    }).then(function (res) {
        console.log(res);
        return res;
    });
}

Solution

  • Problem is solved, thank you. It was caused by 'utf8' encoding used in Buffer by default. Specifying it as new Buffer(reportData, 'binary') has solved the problem.