CrazyCoder
CrazyCoder

Reputation: 219

call external API from aws lambda and get respose as callback in lambda funtion

I'm trying to call external API inside aws Lambda function using node request Module. so far I'm success of calling API and get the data within lambda execution. only problem i'm having is getting my userInfo data with response.even my userInfo has data in Giving me empty Object in client side

var AWS = require('aws-sdk');
AWS.config.region = 'us-east-1';
var request = require('request');
const encode = require('nodejs-base64-encode');
var lambda = new AWS.Lambda();
import { Handler, Context, Callback } from "aws-lambda";
import { PayPalLinkDetails } from "../../View/PayPalLinkDetails";
import { PayPalLinkResponse, PayPalLinkResponseBody } from "../../View/PayPalLinkResponseBody";

const PAYPAL_CLIENT = process.env.PayPalClientID;
const PAYPAL_SECRET = process.env.PayPalSecretKEY;
const PAYPAL_OAUTH_API = process.env.PayPalAuthAPI;
const PAYPAL_IDENTITY_API = process.env.PayPalIdentityAPI;

const LinkPayPal: Handler = async (paypalRequest : PayPalLinkDetails, context: Context, callback: Callback) => {

    var userInfo = new PayPalLinkResponse();     
    var paypalresponse = new PayPalLinkResponseBody();
    const basicAuth = encode.encode(PAYPAL_CLIENT+":"+PAYPAL_SECRET, 'base64');      
      var options = {
        'method': 'POST',
        'url': PAYPAL_OAUTH_API,
        'headers': {
          'Authorization': 'Basic '+basicAuth,
          'Content-Type': 'application/x-www-form-urlencoded'
        },
        form: {
          'grant_type': 'authorization_code',
          'code': paypalRequest.code
        }
      };

      await request(options, async function (error : any, response :any) { 
        if (error)
        {
           console.log(error);
        }
        else
        {
            paypalresponse = response.body;
           // save data to DB here
        }

      });

      var getIdentity = {'method': 'get','url': PAYPAL_IDENTITY_API,'headers': {'Authorization': 'Basic '+basicAuth,'Content-Type': 'application/x-www-form-urlencoded'},form: {'grant_type': 'authorization_code','code': paypalresponse.access_token}};

       await request(getIdentity, function (err : any, res :any)
                                {
                                    if (err)
                                    {
                                        console.log(err);
                                    }
                                    else
                                    {        
                                        userInfo = res.body; // this Print the values as expected
                                        console.log(userInfo);

                                    }
                                });


 callback(null,userInfo); // This Giving me Empty value      
}

export {LinkPayPal}  

i think i'm calling callback in wrong way. is there any suggestions for solve this issue ..?

Upvotes: 0

Views: 4321

Answers (1)

Ashish Modi
Ashish Modi

Reputation: 7770

The problem is that you have mixed up callback and async/await style which wouldn't work the way you expect it to be. You have couple of choices here

  • [Not Recommended]: Do a nested callback and on response of first callback, call second request and so on.

  • [Not Recommended]: Use a promise version of the request package which is called request-promise as this is now being deprected.

  • [Not Recommended]: Convert request's callback style to promise based by wraping up in promise. Again request module is being deperecated. See here for more details.

  • [Recommended]: Use some modern day packages which supports promises out of the box and maintained properly. Like got, axios etc. You can see the list here.

This is how the code will look if you use let's say got pacakge to make http calls.

var AWS = require("aws-sdk");
AWS.config.region = "us-east-1";
var got = require("got");
const encode = require("nodejs-base64-encode");
var lambda = new AWS.Lambda();
import { Handler, Context, Callback } from "aws-lambda";
import { PayPalLinkDetails } from "../../View/PayPalLinkDetails";
import {
  PayPalLinkResponse,
  PayPalLinkResponseBody
} from "../../View/PayPalLinkResponseBody";

const PAYPAL_CLIENT = process.env.PayPalClientID;
const PAYPAL_SECRET = process.env.PayPalSecretKEY;
const PAYPAL_OAUTH_API = process.env.PayPalAuthAPI;
const PAYPAL_IDENTITY_API = process.env.PayPalIdentityAPI;

const LinkPayPal: Handler = async (
  paypalRequest: PayPalLinkDetails,
  context: Context,
  callback: Callback
) => {
  var userInfo = new PayPalLinkResponse();
  var paypalresponse = new PayPalLinkResponseBody();
  const basicAuth = encode.encode(
    PAYPAL_CLIENT + ":" + PAYPAL_SECRET,
    "base64"
  );
  var options = {
    method: "POST",
    url: PAYPAL_OAUTH_API,
    headers: {
      Authorization: "Basic " + basicAuth,
      "Content-Type": "application/x-www-form-urlencoded"
    },
    form: {
      grant_type: "authorization_code",
      code: paypalRequest.code
    }
  };

  const paypalresponse = await got(options);

  var getIdentity = {
    method: "get",
    url: PAYPAL_IDENTITY_API,
    headers: {
      Authorization: "Basic " + basicAuth,
      "Content-Type": "application/x-www-form-urlencoded"
    },
    form: {
      grant_type: "authorization_code",
      code: paypalresponse.access_token
    }
  };

  const userInfo = await got(getIdentity);

  return userInfo;
};

export { LinkPayPal };

You might need to tweak the options as per the got style but you will get an idea.

Upvotes: 1

Related Questions