Alex Gordon
Alex Gordon

Reputation: 60751

making an https request inside of an azure function

I'm attempting a simple request:

var options = {
                host: 'hookb.in',
                path: '/8PMoEa9kbaCXgXYxOmdr5',
                method: 'POST'
            };

            var req = http.request(options, (res) => {
                var body = context.bindingData.name;

                res.on("data", (chunk) => {
                    body += chunk;
                });

                res.on("end", () => {
                    context.res = body;
                });
            }).on("error", (error1) => {
                context.log('error');
                context.res = {
                    status: 500,
                    body: error1
                };
            });
            req.end();
            context.done();

However, there's no response (and no request received by the target here https://hookbin.com/8PMoEa9kbaCXgXYxOmdr).

What am I doing wrong? Is there a special way to create an https request inside of an azure function?

var Jimp = require("jimp");
var http = require('https');

module.exports = async function (context, myBlob) {
    context.log("JavaScript blob trigger function processed blob \n Name:", context.bindingData.name, "\n Blob Size:", myBlob.length, "Bytes");
    context.log(process.env.ImageConvertedWebHook);
    Jimp.read(myBlob, function (err, image) {
        image.getBufferAsync(Jimp.MIME_TIFF, function (error, imageData) {
            context.log('Node.JS blob trigger function resized ' + context.bindingData.name + ' to ' + image.bitmap.width + 'x' + image.bitmap.height);
            context.bindings.outputBlob = imageData;

            var options = {
                host: 'hookb.in',
                path: '/8PMoEa9kbaCXgXYxOmdr5',
                method: 'POST'
            };

            var req = http.request(options, (res) => {
                var body = context.bindingData.name;

                res.on("data", (chunk) => {
                    body += chunk;
                });

                res.on("end", () => {
                    context.res = body;
                });
            }).on("error", (error1) => {
                context.log('error');
                context.res = {
                    status: 500,
                    body: error1
                };
            });
            req.end();
            context.done();
        });
    });
};

I've also attempted this way:

    const data = 'buy milk biotch';
    var options = {
        host: 'hookb.in',
        path: '/8PMoEa9kbaCXgXYxOmdr',
        method: 'POST',
        port: 443,
        headers: {
            'Content-Type': 'application/json',
            'Content-Length': data.length
        }
    };
    const req = https.request(options, res => {
        context.log(`statusCode: ${res.statusCode}`)

        res.on('data', d => {
            context.log(d)
        })
    })

    req.on('error', error1 => {
        context.log(error1)
    })

    req.write(data)
    req.end()

Upvotes: 3

Views: 4657

Answers (3)

Sashini Hettiarachchi
Sashini Hettiarachchi

Reputation: 1708

I had the same issue but after removing async from module.exports = async function (context, myBlob), this should be work. If you want to treat this as a async function, this might be helpful.

Upvotes: 1

aderesh
aderesh

Reputation: 947

This is a working example of how to request Azure AD v2 endpoint to get access token inside of your Azure Function V3 (node runtime)

var http = require('https');

module.exports = function (context, req) {
    var body = "";
    body += 'grant_type=' + req.query['grant_type'];
    body += '&client_id=' + req.query['client_id'];
    body += '&client_secret=' + req.query['client_secret'];
    body += '&code=' + req.query['code'];

    const options = {
        hostname: 'login.microsoftonline.com',
        port: 443,
        path: '/ZZZZZZZZ-bc69-4c8b-8e91-11f3a181c2bb/oauth2/v2.0/token',
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Content-Length': body.length
        }
    }

    var response = '';
    const request = http.request(options, (res) => {
        context.log(`statusCode: ${res.statusCode}`)

        res.on('data', (d) => {
            response += d;
        })

        res.on('end', (d) => {
            context.res = {
                body: response
            }
            context.done();
        })
    })

    request.on('error', (error) => {
        context.log.error(error)
        context.done();
    })

    request.write(body);
    request.end();
};

Differences between this and OP's: function is not marked as async (module.exports = function) and I'm using context.done(); to let the runtime know when an async action (https request in our case) is done. context.done(); is in two places: 'end' and 'error' callbacks.

I believe async/await + promises should be used instead of callbacks if you want to use an async function - link

Using the async and await keywords helps avoid both of these errors. You should use the Node.js utility function util.promisify to turn error-first callback-style functions into awaitable functions.

Not a JS dev.

Upvotes: 3

Mohit Verma
Mohit Verma

Reputation: 5294

Seems like naming conflict issue .Couple of variables to change in your code:

  • Change below

var http = require('https');

To

var httpMod = require('https');
  • Change below

const req = https.request(options, res => {
            context.log(`statusCode: ${res.statusCode}`)
    
            res.on('data', d => {
                context.log(d)
            })
        })

To

 const customReq = httpMod.request(options, res => {
            context.log(`statusCode: ${res.statusCode}`)
    
            res.on('data', d => {
                context.log(d)
            })
        })

Hope it helps.

Upvotes: 0

Related Questions