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
}
}
};
Related
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.
The question is not regarding subscribing to SNS Topic via HTTP endpoint. I was successfully able to configure and also confirm the subscription. Also, I am able to receive messages at the endpoint.
The requirement is to have another subscriber of the topic in nodejs backend app. I tweaked the code in this article for setting up the application, however couldn't manage to do so.
const AWS = require('aws-sdk');
const credentials = new AWS.SharedIniFileCredentials({ profile: '<profile-name>' });
const sns = new AWS.SNS({ credentials: credentials, region: 'eu-central-1' });
let params = {
Protocol: 'HTTP',
TopicArn: 'arn:aws:sns:eu-central-1:TOPIC:NAME',
Endpoint: 'http://mockbin.org/bin/bin-id'
};
sns.subscribe(params, (err, data) => {
if (err) {
console.log(err);
} else {
console.log(data);
}
});
The response is
{
ResponseMetadata: { RequestId: '0af83f58-c562-592f-b493-65fef627ac28' },
SubscriptionArn: 'pending confirmation'
}
However, in the console, i see this endpoint as confirmed
Can someone suggest here.
My context is this: I am attempting to build a chat bot into my Mozilla Hubs client, which is a node js / React project. I have a lex bot created on AWS, and I have installed the client-lex-runtime-v2 package and can import it successfully, but I have no idea how to set up a StartConversationCommand, give it credentials, etc. Most of the javascript examples seem to go the other way, where Lex calls a lambda function after processing a request, but I have user input in my app and I need to send it to Lex, and then deliver the resulting text back to the user inside my application.
This seems like very basic Lex usage - if anyone could point me to a code example I would be most grateful.
John,
You need to make use of the LexRuntimeV2Client in the SDK as demonstrated here.
From the linked documentation, the below is how you import and instantiate a new client:
import { LexRuntimeV2Client, DeleteSessionCommand } from "#aws-sdk/client-lex-runtime-v2";
const client = new LexRuntimeV2Client({ region: "REGION" });
Once configured with your respective AWS environment details, credentials etc you will be able to invoke your Lex bot (again, from the linked documentation):
try {
const data = await client.send(command);
// process data.
} catch (error) {
// error handling.
} finally {
// finally.
}
Take a look at this sample repo on GitHub as well: aws-lex-web-ui
So for anyone else stuck where I was, I cannot say this is the right way to do it, because I never did get it working, but the closest I got to at least forming up my credentials and trying to make a connection was this:
const client = new LexRuntimeV2Client({
region: "us-east-1",
credentials: new AWS.Credentials({
accessKeyId: "my_IAM_access_key_id",
secretAccessKey: "my_secret_access_key"
})
});
const lexparams = {
"botAliasId": "my alias_id",
"botId": "bot_id_from_lex",
"localeId": "en_US",
"inputText": "hello, this is a test sample",
"sessionId": "some_session_id"
};
let cmd = new StartConversationCommand(lexparams);
try {
const data = await client.send(cmd);
console.log("Success. Response is: ", data.message);
} catch (err) {
console.log("Error responding to message. ", err);
}
As said, buyer beware, and best of luck out there! I hope this might help somebody in some slight way. We taking a momentary break on this problem until a member of our team with better aws fu can take a look at it. :-)
This is working for me:
var AWS = require('aws-sdk');
const { LexRuntimeV2 } = require("#aws-sdk/client-lex-runtime-v2");
const lexruntime = new LexRuntimeV2({
region: "us-west-2", // Set your Bot Region
credentials: new AWS.Credentials({
accessKeyId: "***", // Add your access IAM accessKeyId
secretAccessKey: "***" // Add your access IAM secretAccessKey
})
});
const lexparams = {
"botAliasId": "HG****", // Enter the botAliasId
"botId": "HG***", // Enter the botId
"localeId": "en_US",
"text": "Book Car",
"sessionId": "some_session_id"
};
lexruntime.recognizeText(lexparams, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log(data); // successful response
});
I am trying to send text messages from my Elastic Beanstalk server application, but I keep getting {"Error":{"message":null,"code":404,... }. I followed the code in the documentation, but I still can't get it to work.
I followed this YouTube tutorial and I am able to send messages from my local development environment, but can't seem to be able to replicate this for my server app. In that tutorial the presenter creates an IAM group and an IAM user and the keys are saved in an .env folder, which I imagine is what makes things work.
I have also granted my Elastic Beanstalk EC2 instances full access to SNS using IAM.
Can someone please explain to me how I can replicate this in my server app? Or how can I send transactional text messages from a node.js/express server?
This is my code:
//we have to use us-east-1 because sending texts is not allowed in us-east-2
AWS.config.update({region: 'us-east-1'});
var params = {
Message: "This is a test",
PhoneNumber: '+' + "phoneNumberGoesHere",
MessageAttributes: {
'AWS.SNS.SMS.SenderID': {
'DataType': 'String',
'StringValue': "app name goes here"
}
}
};
var publishTextPromise = new AWS.SNS({ apiVersion: '2010-03-31'}).publish(params).promise();
publishTextPromise.then(
function (data) {
console.log("Message sent successfully...... ", JSON.stringify({ MessageID: data.MessageId }))
}).catch(
function (err) {
console.log("Error sending Text Message...... ", JSON.stringify({ Error: err }))
});
All I had to do was add the right endpoint and region to this line, now it works perfectly!
var publishTextPromise = new AWS.SNS({ apiVersion: '2010-03-31', endpoint: 'http://sns.us-east-1.amazonaws.com', region: 'us-east-1' }).publish(params).promise();
and as #Raman Damodar Shahdadpuri mentioned, I needed to remove the .SenderID portion. This is the final code:
var params = {
Message: "This is a test of text messaging",
PhoneNumber: '+' + 'phone number goes here',
MessageAttributes: {
'AWS.SNS.SMS.SMSType': {
'DataType': 'String',
'StringValue': "Transactional"
}
}
};
var publishTextPromise = new AWS.SNS({ apiVersion: '2010-03-31', endpoint: 'http://sns.us-east-1.amazonaws.com', region: 'us-east-1' }).publish(params).promise();
publishTextPromise.then(
function (data) {
res.end(JSON.stringify({ MessageID: data.MessageId }));
}).catch(
function (err) {
res.end(JSON.stringify({ Error: err }));
});
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