I need to only deliver a message to a standard (not FIFO, but is not related to the question) SQS queue, once with one call.
However, the code below is sending 2 messages with 1 call.
const AWS = require('aws-sdk')
AWS.config.update({region: process.env.AWS_REGION})
const sqs = new AWS.SQS({apiVersion: '2012-11-05'});
async function sendToSQSEvent(body,attributes=null){
var m_body
if (attributes != null)
{
m_body = {
body : body,
attributes : attributes
};
}
else{
m_body = body;
}
m_body = JSON.stringify(m_body);
var params = {
// DelaySeconds: 0, <-- i try but only delay reception
MessageAttributes: {
"Title": {
DataType: "String",
StringValue: "TIME_OUT"
},
"Author": {
DataType: "String",
StringValue: "LAMBDA_IN"
},
},
MessageBody: m_body,
QueueUrl: "https://my_url/sqs"
};
console.log('_________CALL_______________');
var r = await sqs.sendMessage(params, function(err, data) {
if (err) {
console.log("Error", err);
} else {
console.log("Success", data.MessageId ,data);
}
}).promise(console.log("_________in promise___________"));
console.log("___end")
}
exports.handler = async (event, context) => {
await sendToSQSEvent(event)
};
Console output is:
START RequestId: RequestId Version: $LATEST
2021-10-11T06:23:52.992Z RequestId INFO _________CALL_______________
2021-10-11T06:23:53.425Z RequestId INFO _________in promise___________
2021-10-11T06:23:53.728Z RequestId INFO Success ********-****-****-****-*********b4f {
ResponseMetadata: { RequestId: '********-****-****-****-*********89d' },
MD5OfMessageBody: '********************************8f',
MD5OfMessageAttributes: '***********************1b0',
MessageId: '********-****-****-****-*********b4f'
}
2021-10-11T06:23:53.786Z RequestId INFO ___end
2021-10-11T06:23:53.807Z RequestId INFO Success ********-****-****-****-*********665 {
ResponseMetadata: { RequestId: '********-****-****-****-********835' },
MD5OfMessageBody: '***********************28f',
MD5OfMessageAttributes: '***********************1b0',
MessageId: '********-****-****-****-*********665'
}
END RequestId: RequestId
What is the issue?
CodePudding user response:
It's sending a message twice as you're mixing synchronous callbacks (function(err, data)
) with asynchronous promises (await
, async function sendToSQSEvent(...)
).
You can see this as CloudWatch is logging 2 sqs.sendMessage(...)
responses.
I would recommend sticking with the latter.
This should be your SQS sendMessage
logic, which returns a promise object for your handler.
return sqs.sendMessage(params).promise();
You can then check the response in your handler:
exports.handler = async (event, context) => {
try {
var data = await sendToSQSEvent(event)
console.log("Success", data.MessageId ,data);
}
catch (err){
console.log("Error", err);
}
};
This should be the final working result:
const AWS = require('aws-sdk')
AWS.config.update({
region: process.env.AWS_REGION
})
const sqs = new AWS.SQS({
apiVersion: '2012-11-05'
});
async function sendToSQSEvent(body, attributes = null) {
var m_body
if (attributes != null) {
m_body = {
body: body,
attributes: attributes
};
} else {
m_body = body;
}
m_body = JSON.stringify(m_body);
var params = {
MessageAttributes: {
"Title": {
DataType: "String",
StringValue: "TIME_OUT"
},
"Author": {
DataType: "String",
StringValue: "LAMBDA_IN"
},
},
MessageBody: m_body,
QueueUrl: "https://my_url/sqs"
};
return sqs.sendMessage(params).promise();
}
exports.handler = async (event, context) => {
try {
var data = await sendToSQSEvent(event)
console.log("Success", data.MessageId ,data);
}
catch (err){
console.log("Error", err);
}
};