4

I'm trying to create an Azure function using nodeJS, but when I make a call to an https API I get an error message.

Is it possible to make a HTTPS call from azure function?

Here is my code

const https = require('https');
const querystring = require('querystring');

module.exports = async function (context, req) {

    if (req.query.accessCode || (req.body && req.body.accessCode)) {

        var options = {
            host: 'api.mysite.com',
            port: 443,
            path: '/oauth/access_token',
            method: 'POST'
        };

        var postData = querystring.stringify({
            client_id : '1234',
            client_secret: 'xyz',
            code: req.query.accessCode
        });


        var req = https.request(options, function(res) {
            context.log('STATUS: ' + res.statusCode);
            context.log('HEADERS: ' + JSON.stringify(res.headers));

            res.on('data', function (chunk) {
                context.log('BODY: ' + chunk);
            });
        });

        req.on('error', function(e) {
            context.log('problem with request: ' + e.message);
        });

        req.write(postData);
        req.end();

        context.res = {
            status: 200,
            body: "Hello " + (req.query.accessCode)
        };
    } else {
       context.res = {
            status: 400,
           body: "Please pass a name on the query string or in the request body"
      };
    }

    context.done();
};

I get an error but I do not see any error on the console, also if I comment all the https call it works fine and I can see the Hello message on the screen.

Jerry Liu
  • 17,282
  • 4
  • 40
  • 61
Ennio
  • 1,147
  • 2
  • 17
  • 34

2 Answers2

4

Two points to fix

  1. Delete context.done();. See Azure document.

    If your function uses the JavaScript async function declaration (available using Node 8+ in Functions version 2.x), you do not need to use context.done(). The context.done callback is implicitly called.

  2. Rename your https.request like var myReq = https.request(options, function(res).

    There's a name conflict causing error as function has a built-in req object declared.

Community
  • 1
  • 1
Jerry Liu
  • 17,282
  • 4
  • 40
  • 61
  • would love your assistance on a similar q https://stackoverflow.com/questions/57631020/making-an-https-request-inside-of-an-azure-function – Alex Gordon Aug 23 '19 at 18:45
0

It's possible, here is an example of how to make a request to an Azure AD v2 token endpoint (I'd assume you are trying to do something similar):

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: '/ZZZ920d8-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();
};

The difference is - the function is not async module.exports = function

I believe your issue is:

You should use the Node.js utility function util.promisify to turn error-first callback-style functions into awaitable functions.

link

aderesh
  • 927
  • 10
  • 22