0

I am currently trying to upload a Node.js file (titled 'index.js') to AWS Lambda that I want to automatically execute every day at midnight. I understand how to upload the file and everything of that nature, but for some reason, I cannot get the code to run multiple sequential functions.

Keep in mind that this function WORKS when I manually run it from my own command line (node index.js). However, when tested on Lambda, the only function that fires is the first one, getToken. I want this code to be able to first get the API access token, then update my DynamoDB table with the fetched information. Can anyone possibly help me reconfigure this function so that it works on Lambda?

var AWS = require('aws-sdk');
AWS.config.update({region: 'us-west-2'});


async function getToken (event, context) {

    artistRank = 0;
    console.log("GETTING TOKEN...")
  
    getToken = await fetch("https://api.chartmetric.com/api/token", {
        body: '{"refreshtoken":"*************************************"}',
        headers: {
          "Content-Type": "application/json"
        },
        method: "POST"
      })
      .then( res => res.json() )
      .then( data => {
        
        token = data.token;
        console.log(token)
        readTable(token);

})};

async function readTable (token) {

    // Create the DynamoDB service object
    var ddb = new AWS.DynamoDB({apiVersion: '2012-08-10'});

    for (let i = 0; i < 50; i++) {

        setTimeout(() => {

            var params = {
            TableName: 'popularCharts',
            Key: {
                'rank': {N: String(i)}
            },
            ProjectionExpression: 'currentRank, id'
            };

            ddb.getItem(params, function (err, data) {
                if (err) {
                    console.log("Error", err);
                } else {
                    artistId = data['Item'].id
                    idString = JSON.stringify(artistId);
                    idLength = idString.length;
                    idFinal = idString.slice(6, idLength - 2);
                
                    pointsScored(token, idFinal, i)
                }
            });

        }, i*2000);
    }


}


async function pointsScored (accessKey, id, rank) {

    fetch("https://api.chartmetric.com/api/artist/" + id + "/cpp?stat=score", {
        headers: {
            Authorization: "Bearer " + String(accessKey)
        }
    })
        .then( res => res.json() )
        .then( data => {

            length = data['obj'].length;

            change = (data['obj'][length-1].score - data['obj'][length-4].score)*1000000;

            console.log(change)

            var ddb2 = new AWS.DynamoDB({apiVersion: '2012-08-10'});
          
            var params2 = {
                TableName: 'pointsScored',
                Item: {
                  'rank' : {N: String(rank)},
                  'id' : {N: String(id)},
                  'playlistPoints' : {S: String(change)},
                  'currentRank' : {N: String(rank)}
                }
            }
            ddb2.putItem(params2, function(err, data) {
                if (err) {
                    console.log("Error", err);}
            });
        })

}

exports.handler = getToken();

Any help is much appreciated. Thank you!

  • Are you successfully receiving token? `console.log(token)` – Jatin Mehrotra Mar 07 '23 at 01:55
  • @JatinMehrotra the token is not being console logged, but the earlier "console.log('GETTING TOKEN...')" is working – Jack Eggert Mar 07 '23 at 02:00
  • Maybe that is the problem. Check whether you are getting token or not `token = data.token; console.log(token)`. And all check Lambda cloudwatch logs to see where error is happening. In my view its because your token fetching logic has some problem that is why readTable is not called. – Jatin Mehrotra Mar 07 '23 at 02:03
  • @JatinMehrotra the odd thing is, when I run the program via my own CLI the token is successfully logged. It only doesn't work when I run it via Lambda. When I run it via Lambda, I get a "success" message but it looks like it simply stops and doesn't run the .then() code. – Jack Eggert Mar 07 '23 at 02:11
  • What does cloudwatch logs tells? did you confirm your lambda logs?Also instead of using .then try using this https://stackoverflow.com/a/50047047/13126651 – Jatin Mehrotra Mar 07 '23 at 02:15
  • @JatinMehrotra the cloudwatch records the console.log("GETTING TOKEN..."), and then about 800ms later (which is about how long it takes to fetch the data), the END requestid is logged – Jack Eggert Mar 07 '23 at 02:17
  • If I was you I would done it this way . Dont complicate it with using that ugly promise syntax. :D `getToken = await fetch(link) const token = getToken.json() readTable(token) ` – Jatin Mehrotra Mar 07 '23 at 02:21
  • @JatinMehrotra I appreciate all of your help. I have managed to pinpoint the problem: the function stops when I call "ddb.getItem". Do you know how I could get it to work? Im confused why this instantly stops the function – Jack Eggert Mar 07 '23 at 02:55
  • What if you increase the timeout? DO you really new that timeout? – Jatin Mehrotra Mar 07 '23 at 03:19
  • @JatinMehrotra I ended up resolving the error by surrounding the function with a promise. I believe that AWS was ending the function prematurely for some reason but I fixed it. Thanks again for the help! – Jack Eggert Mar 07 '23 at 05:07

0 Answers0