Search code examples
javascripttypescriptamazon-web-serviceslambdatwitter

Difficulties while running a node function within an AWS Lambda


I'm noticing some weird behaviour with my AWS Lambda function.

This is the code of the Lambda:

import { TwitterApi } from 'twitter-api-v2';


const client = new TwitterApi({
    appKey: 'APP_KEY',
    appSecret: 'APP_SECRET',
    accessToken: 'ACCESS_TOKEN',
    accessSecret: 'ACCESS_SECRET',
});

const rwClient = client.readWrite


exports.handler = async function (event: any) {
    event.Records.forEach((record: any) => {
        console.log('Event Name: %s', record.eventName);
        console.log('DynamoDB Record: %j', record.dynamodb);

        switch (record.eventName) {
            case "INSERT":
                rwClient.v1.tweet('Hello, this is a test.');
                break;

            default:
                break;
        }
    });
};

If I inserting an element into the DynamoDb an EventHandler is triggered and will then call rwClient.v1.tweet('Hello, this is a test.');
Theoretically this should work. If a add a console.log() after and before the statement, both logs will be executed. But when I look into the twitter account I am connected to, no tweet is done.

If I run following code snippet on https://npm.runkit.com, the tweet is shown in the account:

const twitter_api_v2_1 = require("twitter-api-v2");
const client = new twitter_api_v2_1.TwitterApi({
    appKey: 'APP_KEY',
    appSecret: 'APP_SECRET',
    accessToken: 'ACCESS_TOKEN',
    accessSecret: 'ACCESS_SECRET',
});
const rwc = client.readWrite;
rwc.v1.tweet('Hello, this is a test.');

May someone know any solution how I will get the Lambda function work?


Solution

  • rwClient.v1.tweet() is probably an async method and your request is terminating before the async is executed.

    Try to await for the tasks (concurrent):

    exports.handler = async function (event: any) {
        const tasks = event.Records.map(async (record: any) => {
            console.log('Event Name: %s', record.eventName);
            console.log('DynamoDB Record: %j', record.dynamodb);
    
            switch (record.eventName) {
                case "INSERT":
                    await rwClient.v1.tweet('Hello, this is a test.');
                    break;
    
                default:
                    break;
            }
        });
        await Promise.all(tasks);
    };
    

    or await in for-of (sequential):

    exports.handler = async function (event: any) {
        for (const record of event.Records) {
            console.log('Event Name: %s', record.eventName);
            console.log('DynamoDB Record: %j', record.dynamodb);
    
            switch (record.eventName) {
                case "INSERT":
                    await rwClient.v1.tweet('Hello, this is a test.');
                    break;
    
                default:
                    break;
            }
        }
    };