У меня проблема, которую я не могу решить сам. Моя лямбда-функция работает должным образом при локальном вызове, но не отправляет текстовое сообщение при вызове из AWS Lambda. Он также не регистрирует никаких ошибок.
Вот мой код, я пометил только личные вещи:
import request from 'request';
import AWS from "aws-sdk";
const options = {***};
const sentAlert = async msg => {
const sns = new AWS.SNS();
await sns.publish({
Message: msg,
PhoneNumber: '***',
MessageAttributes: {
'AWS.SNS.SMS.SenderID': {
'DataType': 'String',
'StringValue': '***'
}
}
}, function (err, data) {
if (err) {
console.info(err.stack);
return;
}
});
console.info('sms sent');
};
export const getAlert = async (event, context, callback) => {
request(options, (err, res, body) => {
if (err) { return console.info('error: ', err); }
if (body.length === 0 ) { return }
console.info(`***`);
const optionsId = {*** };
request(optionsId, (err, res, body) => {
const msg = body.current.indexes[0].description;
console.info('msg: ', msg);
sentAlert(msg);
});
});
};
Я тестирую его локально с помощью serverless invoke local --function getSmogAlert
, и он работает так, как ожидалось, я получаю sms от AWS, но когда я вызываю его с помощью serverless invoke --function getSmogAlert
, он возвращает null и не отправляет никаких текстовых сообщений.
У меня были аналогичные проблемы с Nexmo, и я подумал, что, возможно, AWS.SNS мне поможет, но нет.
Любая помощь, пожалуйста?
Это только такие штуки, как START RequestId: 824ea951-d6e8-11e8-a428-77d70245b74d Version: $LATEST END RequestId: 824ea951-d6e8-11e8-a428-77d70245b74d REPORT RequestId: 824ea951-d6e8-11e8-a428-77d70245b74d Duration: 8.84 ms Billed Duration: 100 ms Memory Size: 1856 MB Max Memory Used: 45 MB
Проверьте разрешения IAM, есть ли у вашей роли Lambda sns:publish
?
В вашем вызове sns.publish
я пропускаю параметр TopicArn
. Но, судя по протоколу, до казни не доходит. В вашем обработчике getAlert
я пропускаю вызов callback(...)
, поэтому исполнитель лямбда, вероятно, проигнорирует обещание, сделанное вызовом request(...)
, и завершится до того, как исполнение дойдет до публикации в SNS ...
Как я писал в своем комментарии, я думаю, вы путаете обещания и обратные вызовы при выполнении. Попробуйте это изменить:
const options = {***};
const sentAlert = (msg, callback) => {
const sns = new AWS.SNS();
await sns.publish({
TopicArn: ***
Message: msg,
PhoneNumber: '***',
MessageAttributes: {
'AWS.SNS.SMS.SenderID': {
'DataType': 'String',
'StringValue': '***'
}
}
}, function (err, data) {
if (err) {
console.info(err.stack);
callback(err);
}
});
console.info('sms sent');
callback(null)
};
export const getAlert = (event, context, callback) => {
request(options, (err, res, body) => {
if (err) {
console.info('error: ', err);
callback(err);
}
if (body.length === 0 ) {
console.info('Got no body!')
callback(null)
}
console.info(`***`);
const optionsId = {*** };
request(optionsId, (err, res, body) => {
if (err) {
console.info(err.stack);
callback(err);
}
const msg = body.current.indexes[0].description;
console.info('msg: ', msg);
sentAlert(msg, callback);
});
});
};
Но в целом я бы предпочел использовать механизм async / await, поддерживаемый изображением AWS Lambda nodejs8.10. Это сделало бы ваш код простым и понятным.
Я добавил разрешение на использование sns, внес предлагаемые изменения, а также удалил ожидание из SentAlert
- и все равно, он работает при локальном вызове, а не из лямбда ...
Попробуйте отследить выполнение через Cloud9 или просто с помощью логов - посмотрите, где остановится выполнение.
Еще одна вещь, которую я упустил: попробуйте удалить async
из функции-обработчика. Отредактирую свой ответ так.
Хорошо, у меня есть кое-что: полезный журнал в CloudWatch: User: arn:aws:sts::***:assumed-role/sns/***Alert is not authorized to perform: SNS:Publish on resource: PHONE_NUMBER
.
Это означает, что у вашей лямбда-роли нет разрешения на выполнение "sns: publish".
Добавление роли полного доступа к sns решило проблему, спасибо, ребята!
@chris Тогда вы можете принять ответ. Тем не менее, я думаю, вам следует рассмотреть стиль async / await вместо обратных вызовов. См. medium.com/@ThatGuyTinus/…
Проверьте журналы AWS CloudWatch на наличие функции Lambda и включите любой вывод журнала из вызова функции.