AWS Lambda SNS两次发送主题 [英] AWS Lambda SNS sending topic twice
问题描述
编写lambda函数来执行一些数据库查询,然后通过电子邮件发送给某些用户组.
Writing a lambda function to perform some DB queries and then email certain groups of users.
- 针对共享歌曲的每个组发布SNS消息
- 每个组都有自己的成员,因此是自己的一组电子邮件
- 每个组的SNS主题发送两次.
会员两次收到电子邮件.
Members are receiving the email twice.
该应用程序是一种音乐流应用程序,用户可以在其中创建歌曲.他们还可以创建组,邀请成员加入这些组,并在这些组中分享他们的歌曲.
The app is a music streaming app where users can create songs. They can also create groups, invite members to those groups and share their songs to these groups.
这是通过API调用的lambda:
Here is the lambda called via API:
const shareWithGroup = async event => {
const { songCuid, groupCuids } = JSON.parse(event.body);
const shareSongDB = await query(
sql.queryShareWithGroup(songCuid, groupCuids),
); //share to group in DB
if (!shareSongDB) {
return corsUtil.failureWithCors("Couldn't Share Song with group");
}
const song = await query(sql.queryRead(songCuid));
if (!song) {
return corsUtil.failureWithCors('Song doesnt exist');
}
const songTitle = song.rows[0].songTitle; //retrieve songTitle
const promises = groupCuids.map(async groupCuid => {
console.log('GROUP_CUID', groupCuid);
const emailResults = await query(sql.queryReadGroupEmails(groupCuid)); // get emails for group + groupName
const results = emailResults.rows;
const groupName = results[0].groupName;
let emails = [];
results.map(row => {
emails.push(row.email); //push email address into array
});
const payload = JSON.stringify({ groupName, emails, songTitle }); //send groupName, emails list and songTitle to SNS to trigger email
console.log(payload);
await publishSNS(payload)
//send the topic
});
//Resolve all promises
await Promise.all(promises);
console.log(promises);
return corsUtil.successWithCors('Success');
};
const publishSNS = async payload => {
console.log('publishing sns topic');
//SEND EMAILS
const params = {
Message: payload,
TopicArn: `arn:aws:sns:eu-west-1:${process.env.AWS_ACC_ID}:${process.env.STAGE}-songShareTrigger`,
};
return await sns
.publish(params, async error => {
if (error) {
console.error(error);
//TODO: Actually fail the function - can't do with lambdaFactory
}
})
.promise();
};
和一个示例请求(将歌曲共享给1组):
And a sample request (share a song to 1 group):
{"songCuid":"XXX","groupCuids":["XXX"]}
问题是,即使它只发送1个SNS主题,它也会发送2个.当我将歌曲共享给2个组时,它也会发送4个SNS主题.
The issue is, that somehow, even though it should only send 1 SNS topic, it sends 2. When I share a song to 2 groups, it sends 4 SNS topics.
以下是由SNS主题触发的lambda:
Here is the lambda that is triggered by the SNS topic:
const aws = require('aws-sdk');
const ses = new aws.SES();
const corsUtil = require('../utils/corsUtil');
exports.songShareEmail = (event, context) => {
console.log('EVENT : ', event.Records[0].Sns); // LOG SNS
const body = JSON.parse(event.Records[0].Sns.Message);
const { groupName, emails, songTitle } = body;
console.log('Body : ', body);
const groupInviteEmailData = `
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
</head>
<body>
<div class="email-body" style="max-width:900px; margin:auto;" >
<div class="content" style="background-color:white; margin:0 auto;
display:block;">
<p>Hello<p>
</br>
A new song has been shared to the group : <u>${groupName}</u><br>
<h3>Song Title: ${songTitle}</h3>
</div>
</div>
</body>
</html>
`;
var params = {
Destination: {
ToAddresses: emails,
},
Message: {
Body: {
Html: {
Charset: 'UTF-8',
Data: groupInviteEmailData,
},
},
Subject: {
Charset: 'UTF-8',
Data: `New song shared to ${groupName}`,
},
},
Source: 'xxx',
};
console.log('sendingEmail');
ses.sendEmail(params, function(err) {
if (err) {
console.log(err);
const response = corsUtil.failureWithCors(err);
context.fail(response);
} else {
context.succeed('Done');
}
});
};
我已经从事件中记录了SNS对象,并且可以看到每次它都是一个新的MessageId,这意味着它实际上每次都发送2个主题,而不是lambda从同一事件中被触发了两次SNS.
I have logged the SNS object from the event, and I can see that it is a new MessageId each time meaning that it is in fact sending 2 topics each time, and it's not that the lambda is getting triggered twice from the same SNS.
有什么办法解决吗?
推荐答案
我知道这个问题很旧,但是我发现自己也遇到了同样的问题.我解决了我的错误,并且我相信您也有同样的问题.
I know this issue is old, but I found myself having the same problem. I solved my mistake and I believe you have the same exact problem.
不需要 publishSNS
方法中的 .promise()
,只需将其删除(注释如下).
The .promise()
in your publishSNS
method is not needed, just remove it (commented out below).
const publishSNS = async payload => {
console.log('publishing sns topic');
//SEND EMAILS
const params = {
Message: payload,
TopicArn: `arn:aws:sns:eu-west-1:${process.env.AWS_ACC_ID}:${process.env.STAGE}-songShareTrigger`,
};
return await sns
.publish(params, async error => {
if (error) {
console.error(error);
//TODO: Actually fail the function - can't do with lambdaFactory
}
});
//.promise();
};
这篇关于AWS Lambda SNS两次发送主题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!