How to send SMS using Amazon SNS from a AWS lambda function - node.js

Amazon SNS provides a facility to send SMS globally.
I want to send SMS from a Lambda function were we provide the mobile number and text message and use SNS to deliver that message but I didn't find a helpful documentation or example code for NodeJS or java.
Can any one suggest a solution?
Code:
var params = {
Message: 'Hi this is message from AWS_SNS', /* required */
MessageAttributes: {
someKey: {
DataType: 'String' ,
StringValue: 'String'
},
},
MessageStructure: 'String',
PhoneNumber: '+91MyNUMBER',
Subject: 'MYSubject',
//TargetArn: 'arn:aws:sns:us-west-2:798298080689:SMS',
//TopicArn: 'arn:aws:sqs:us-west-2:798298080689:SendSMS'
};
sns.publish(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log(data); // successful response
});
};

So, you need to write Lambda function which is invoked somehow, let's say via HTTP request so you'll also need to setup API Gateway to route connections to your Lambda function.
Next, your Lambda function will push that data to "SNS Topic" while SMS Subscription will "poll" for any new data in this "Topic". As soon as any data gets into this topic, it will be consumed by subscription and SMS will be sent.
Few days ago I wrote a post about SNS & Lambda which might help you. Flow you wanted to achieve is pretty similar to one described in this article.
https://medium.com/#rafalwilinski/use-aws-lambda-sns-and-node-js-to-automatically-deploy-your-static-site-from-github-to-s3-9e0987a073ec#.3x6wbrz91
Documentation pages that might help:
Pushing to SNS: http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/SNS.html#publish-property
Subscribing to SNS:
http://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html

Please try with setting the region explicitly to "us-east-1". I managed to send SMS to India by explicitly setting this region. I also tried with "ap-south-1", but was not successful.

Based on latest AWS SNS > SMS documenration, When you don't have any topicArn and you need to send a text message directly to a phone number, you need to send following params:
const AWS = require('aws-sdk');
AWS.config.update({region: 'eu-west-1'});
const sns = new AWS.SNS();
const publish = (phone, text, subject) => {
// Create publish parameters
var params = {
Message: text,
Subject: subject,
PhoneNumber: phone,
MessageAttributes: {
'AWS.SNS.SMS.SMSType' : {
DataType : 'String',
StringValue: 'Transactional'
},
},
};
console.log('------------- text message param before sending------------');
console.log(params);
console.log('----------------------------------------------------');
// Create promise and SNS service object
var publishTextPromise = sns.publish(params).promise();
// Handle promise's fulfilled/rejected states
publishTextPromise.then(
function(data) {
console.log("MessageID is " + data.MessageId);
}).catch(
function(err) {
console.error(err, err.stack);
});
}
exports.publish = publish;

Here's what I did
Create a new Lambda function Author from scratch with your Runtime of choice. (I went to latest, Node.js 12.x)
For execution role, choose Create a new role from AWS policy templates.
Type in your Role name and because you want to send SMS to any mobile number, you must set Resource to *.
Type this as your IAM Role Template.
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"sns:Publish"
],
"Effect": "Allow",
"Resource": "*"
}
]
}
Use this code snippet
const AWS = require('aws-sdk');
const SNS = new AWS.SNS();
exports.handler = async (event) => {
let params = {
PhoneNumber: '+123xxxxxxx',
Message: 'You are receiving this from AWS Lambda'
};
return new Promise((resolve, reject) => {
SNS.publish(params, function(err, data) {
if(err) {
reject(err);
}
else {
resolve(data);
}
})
})
}
That's all. Click Deploy then Test and you should receive an SMS.

Here is a link to a tutorial for building an Alexa skill that connects with AWS SNS to send a text message.

It works fine if can make sure you have the right access to publish to SNS.
const smsParams = ()=>({
Message: getUpdateMessage(order),
PhoneNumber: `+91${order.contactNo}`,
MessageAttributes: {
'AWS.SNS.SMS.SMSType' : {
DataType : 'String',
StringValue: 'Transactional'
},
},
})
Permissions to my lambda:
- Effect: 'Allow'
Action:
- "sns:Publish"
Resource:
- '*'
Note that you have to allow all the resources to send SMS using PhoneNumber
Here is a link to all the supported SNS regions

Related

AWS-SNS publish() method not sending any messages to phone number

I have used aws-sdk in node express to send the verification code to the phone number I referred this docs to implement it. here I get the response but do not get any messages on the phone.
const AWS = require("aws-sdk");
AWS.config.update({
region: "region",
accessKeyId: "ACCESS_KEY",
secretAccessKey: "SECRET_KEY",
});
router.post("/", async (req, res) => {
let phone_no = "+91876214****";
let random = Math.floor(100000 + Math.random() * 900000);
const YOUR_MESSAGE = `Your verification code is ${random}`;
let params = {
Message: YOUR_MESSAGE,
PhoneNumber: phone_no,
MessageAttributes: {
"AWS.SNS.SMS.SMSType": {
DataType: "String",
StringValue: "Transactional",
},
};
let publishTextPromise = new AWS.SNS({ apiVersion: "2010-03-31" })
.publish(params)
.promise();
publishTextPromise
.then(function (data) {
return res.json({ id: data.MessageId, otp: random });
})
.catch(function (err) {
return res.send(err.stack);
});
});
is anything I'm doing wrong, new to this aws-sns concept.
here i logged the publishTextPromise i get response as Promise { <pending> }
If you get Success result from api but message is not received. You need to check SNS logs.
On SNS console, you can see Text messaging (SMS) under Mobile section. If you don't enable status logging, firstly edit preferences on Delivery status logs section then on new page create an IAM Role (SNSSuccessFeedback) with Success sample rate 100%.
You can find error on cloudwatch.
Potential problem. You account is in the SMS sandbox in the region which you used.
If you see any message like ☝️, You can add your phone number on sandbox destination phone number.
Then sandbox will send you a verify code, when you put it on AWS console. Then you will be able to receive messages from SNS.

Nodejs - AWS SNS publish is called, but message is not being sent

I'm trying to publish a SNS message to a single user.
The message is working when I manually press the "Publish Endpoint" button in the AWS console, but I'm trying to send it programmatically using the SNS nodejs SDK.
I have made sure to create a single IAM role giving full access permissions to SNS.
I have made sure to configure it:
const AWS = require("aws-sdk");
AWS.config.update({
region: process.env.AWS_REGION,
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY
});
I first create a platform endpoint using sns.createPlatformEndpoint(endPointParams) and it works fine so my IAM role is not an issue.
Using the result from that call, I use the data to create publishParams to make a call right after creating the endpoint:
let payload = {
user : "Hihih test",
shopping_list : "shopping_item"
};
let endPointParams = {
PlatformApplicationArn: process.env.REACT_APP_SNS_ARN,
Token: req.body.device_token
}
const createEndPoint = sns.createPlatformEndpoint(endPointParams).promise();
createEndPoint.then(data => {
console.log(data.EndpointArn);
console.log(JSON.stringify(payload));
let publishParams = {
Message: JSON.stringify(payload),
MessageStructure: 'json',
TargetArn: data.EndpointArn
};
sns.publish(publishParams, (err, result1) =>{
console.log("Success");
});
return;
}).then(result => {
res.status(200).send("Success sending invite to user.");
}).catch(err => {
console.log(err);
res.status(500).send("Something went wrong sending the invite.");
});
});
The console.log("Success"); inside sns.publish() is being fired, but on the client side, the app does not receive a message. I have also tried multiple times to manually call "Publish Message" in the console and it works fine.
So what could my issue be? I think it's something wrong with my code.
When using SNS with GCM you need to structure your JSON payload with the keys GCM and default or it will throw an err.
var payload = {
default: 'Hello World',
GCM: {
notification: {
title: 'Hello World',
body: 'Notification Body'
// other configs can be put here
}
}
};

AWS SES service issue in sending mail using lambda

I have a Basic AWS account in which we have deployed a lambda function. Also we have configured AWS SES service within the lambda function to send email (also our SES service is moved out of the sandbox & limit increased).
Approximately we are sending two emails per minute but we found that rarely we are getting mail, but most of the time we are not getting any email.
Also we tried deploying the application in two region but we found none to be successful.
Sample code
const AWS = require('aws-sdk');
//AWS Options
const options = {
region: 'us-east-1',
// accessKeyId not required because of server less app (SWS policy added in role)
// secretAccessKey not required because of server less app (SWS policy added in role)
}
const ses = new AWS.SES(options);
const sendEmail = (sender, receivers, subject, content) => {
console.log("Sending From", sender);
console.log("REceiver Email", receivers);
const promise = new Promise((resolve, reject) => {
ses.sendEmail({
Source: sender,
Destination: {
ToAddresses: receivers
},
Message: {
Subject: {
Data: subject
},
Body: {
Html: {
Data: content
}
}
}
}, (err, data) => {
if (err) {
console.log(err)
reject(err)
}
resolve(data)
});
});
return promise
};
I think there are a couple of things going on here:
JavaScript functions that return promises need to be async
your Lambda function may be timing out (the default is 3 seconds)

Where are AWS SQS message built-in message attributes documented?

I'm sending messages to AWS SQS with the Node.js SDK. I cannot find the documentation that lists the various built-in attributes that can be specified in a message. The example in the documentation specifies an attribute called "DelaySeconds", but I don't see where that is documented anywhere??
Presumably that instructs the SDK to wait n seconds before sending the message? I'm trying to get the full list of Attributes I'm allowed to specify in a message. Note: I'm not referring to the MessageAttributes where I can specify my own message attributes, I'm referring to attributes that AWS looks at, such as MessageBody, QueueURL, DelaySeconds, etc.
Here is link to documentation I'm looking at:
https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/sqs-examples-send-receive-messages.html
Full Example code here:
// Load the AWS SDK for Node.js
var AWS = require('aws-sdk');
// Set the region
AWS.config.update({region: 'REGION'});
// Create an SQS service object
var sqs = new AWS.SQS({apiVersion: '2012-11-05'});
var params = {
DelaySeconds: 10, <--- where is this documented?
MessageAttributes: {
"Title": {
DataType: "String",
StringValue: "The Whistler"
},
"Author": {
DataType: "String",
StringValue: "John Grisham"
},
"WeeksOn": {
DataType: "Number",
StringValue: "6"
}
},
MessageBody: "Information about current NY Times fiction bestseller for week of 12/11/2016.",
// MessageDeduplicationId: "TheWhistler", // Required for FIFO queues
// MessageId: "Group1", // Required for FIFO queues
QueueUrl: "SQS_QUEUE_URL"
};
sqs.sendMessage(params, function(err, data) {
if (err) {
console.log("Error", err);
} else {
console.log("Success", data.MessageId);
}
});
I found documentation here, was linked from page, just didnt see it.
https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/SQS.html#sendMessage-property

AWS - SNS - how to set sender on a per call basis?

How to set a sender while sending sms from AWS SNS service?
Checking the docs for SNS about sending SMS
https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/sns-examples-sending-sms.html#sending-sms-getattributes
And also here
https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/SNS.html#publish-property
With these docs combined I can send a sms but the sender remains unset. Why?
var AWS = require('aws-sdk');
AWS.config.update({ region: 'eu-west-1' });
var params = {
Message: 'TEXT_MESSAGE',
PhoneNumber: '+44123456780',
MessageAttributes: {
'SenderID': {
DataType: "String",
StringValue: "Company1",
}
}
};
var publishTextPromise = new AWS.SNS().publish(params).promise();
publishTextPromise.then(
function (data) {
console.log("MessageID is " + data.MessageId);
}).catch(
function (err) {
console.error(err, err.stack);
});
I can send a sms except I cannot see a way to set a sender.
How do I set a sender for each message?
I added following section under params for Node.js code and sender id works
MessageAttributes:{
"AWS.SNS.SMS.SenderID" : {
DataType: "String",
StringValue: "abc"
}
},
Note that senderId works for countries/regions as defined in AWS documentation:
https://docs.aws.amazon.com/sns/latest/dg/sns-supported-regions-countries.html#sms-support-note-1

Resources