For some context, I am writing a Telegram bot using NodeJS (node-telegram-bot-api) and AWS Lambda functions to handle requests from users and respond. We are using an API gateway and a webhook to hit an initial lambda function, which has some logic to determine which other lambda function to call to respond to the user. Occasionally, I'll send a message to the bot and several of our lambdas will just fail to respond. Checking the logs in Cloudwatch nets me this error.
INFO Error sending message:
INFO Error: ETELEGRAM: 400 Bad Request: message text is empty
Now, I initially thought that the actual message text was empty, and I was generating a random message on the fly during the response to the user, so instead I am assigning this to a variable prior (and logging it to ensure not undefined) and I am still getting the error. Then I thought that maybe it had something to do with the function timing out, so I increased the window to 30 seconds and gave it 512MB of RAM, and I am still getting this issue. I am also logging the incoming message from the initial lambda JUST TO MAKE SURE, and above every error message I can see the data in plain text from the initial function. Is a 400 from Telegram stating message text is empty more of a generic catch-all error message for anything that goes wrong relating to sending a message? I would hope not, as it seems pretty specific, but I am at a loss of where to go from here to troubleshoot. I just don't see how the message text could ever be empty. Is it possible I introduced a race condition of some sort? I thought I was getting fairly good with JavaScript, but I welcome an education.
Also, just to clarify, the error messages are only ever about sending a message. Never about a failure to invoke another lambda function.
Here is a somewhat redacted version of the body of one of the Lambda functions that is throwing this intermittent error.
const TelegramBot = require("node-telegram-bot-api");
const AWS = require("aws-sdk");
const lambda = new AWS.Lambda();
const getRandomMessage = (arr) => {
return arr[Math.floor(Math.random() * arr.length - 1)];
};
exports.handler = async function (event) {
console.log(event.message);
let message = event.message;
if (message && !message.from.is_bot) {
const MESSAGE_CAROUSEL = [
"MESSAGE_1",
"MESSAGE_2",
"MESSAGE_3",
"MESSAGE_4",
"MESSAGE_5",
];
let params = {
FunctionName: "next-lambda",
InvocationType: "Event",
LogType: "Tail",
Payload: `{"message": ${JSON.stringify(message)}}`,
};
let randomMessage = getRandomMessage(MESSAGE_CAROUSEL);
console.log(randomMessage);
try {
await bot.sendMessage(message.chat.id, randomMessage);
await lambda.invoke(params).promise();
} catch (error) {
console.log("Error sending message:");
console.log(error.toString());
}
}
};
I appreciate anyone that takes the time to read this and give any insight. An answer would be great, but I would honestly settle just for a direction with which to continue troubleshooting.
Embarrassingly enough, my helper function was the culprit.
const getRandomMessage = (arr) => {
return arr[Math.floor(Math.random() * arr.length - 1)];
};
Can sometimes return undefined due to me subtracting 1. The fix (as per @Anon Coward) was to remove - 1.