0

I'm attempting to send information to an external API. To quote their support:

"The file should be encoded in Base64 and inserted into the image parameter. "

I'm not sure if I'm misunderstanding something fundamental, but I am getting a 414-URI Too Large when I try to do so.

I wrote a short node.js script to do it:

var fs = require('fs');
var request = require('request');

var host = "api.xxxxx.com";
var app_id = "xxxxxxxx";
var app_key = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
var sessionID = null;

function base64_encode(filename) {
    // read binary data
    var data = fs.readFileSync('./images/' + filename);
    // convert binary data to base 64 encoded string
    return new Buffer(data).toString('base64');
}

function start() {
    fs.readdir('./images/', function(err, files) {
        if (err) {
            console.log("Error in fs.readdir: ", err);
        }
        else {
            files.forEach(function(file) {
                var base = base64_encode(file);
                request.post({
                    url: 'https://api.xxxxxxx.com/media?source=' + base,
                    headers: {
                        'app_id': app_id,
                        'app_key': app_key
                    }}, function (error, response, body) {
                    if (response) {
                        console.log('Status:', response.statusCode);
                        console.log('Headers:', JSON.stringify(response.headers));
                        console.log('Response:', body);
                    }
                    else {
                        console.log("No response.");
                    }
                });
            });
        }
    })
}

start();

I've also tried putting the encoded image in form: {}, qs: {}, and moved it basically all over the place - i either get a "Required source parameter missing" error, or if I seem to get it right, I get the 414. Any advice on sending an image this way? It is a 144KB image.

Edit:

I changed the meat of the code to this:

        files.forEach(function(file) {
            var data = base64_encode(file);
            var options = {
                host: host,
                port: 443,
                path: '/media',
                method: 'POST',
                headers: {
                    'app_id': app_id,
                    'app_key': app_key,
                    'Content-Type': 'image/jpg',
                    'Content-Length': data.length   
                }

            };
            var req = https.request(options, function(res) {
                res.setEncoding('utf8');
                res.on('data', function (chunk) {
                    console.log("body: " + chunk);
                });
            });
            req.write(data);
            req.end();
        });

But I am still getting "required source parameter missing" as a response. How do I specify it as the "source" parameter?

Chris Burrus
  • 327
  • 2
  • 11
  • You will need to send it in the body of the request instead of the url, that's why you use _POST_, not _GET_. If [this](https://github.com/request/request) is the library you use, add `form:{source:base}` to the object you are sending as request.post() argument – kecer Feb 02 '16 at 22:21

1 Answers1

0

It is hard to say without seeing the documentation for the API you are trying to use; but are you sure it doesn't mean put the image in the post parameters? This is a different way of sending data using HTTP. Please see this question/answer to see how this is done using node.js.

Community
  • 1
  • 1
adampolar
  • 46
  • 6
  • I think I understand what you mean, but I am still getting the "Required source parameter missing." I changed my code to reflect the changes, let me know what you think. The API I'm trying to use is https://www.kairos.com/docs/api/#emotion-analysis (trying to post an image by uploading it, not by direct image link) – Chris Burrus Feb 02 '16 at 23:58
  • Their documentation is actually not very obvious, but in your new code you are just passing the base64 encoding of the file in the body of the post request rather than specifying that it is the value of the source parameter. As far as I can tell (although it is by no means clear from their documentation)The body of the post request should be something like source=AE3452EED...... In the example i linked it does this by using querystring.stringify though i think you might be able to get away with just making the string as above yourself (not very neat). Or do as kecer says in an above comment. – adampolar Feb 03 '16 at 13:58