Where are AWS SQS message built-in message attributes documented? - node.js

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

Related

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)

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

AWS SES Nodejs SDK - email with dash bounces

I'm using the aws nodejs SES sdk and emails with to address with something like 'email#host-name.com' appear to all be bouncing even though they exist. Works for other emails without the dash.
I looked and the emails do look like they end up as query parameters, do I just need to individually url encode them? I dont get an error anymore, but I dont have any email address to test with.
var params = {
Destination: {
ToAddresses: [
'email#host-name.com'
]
},
Message: {
Body: {
Html: {
Data: body
}
},
Subject: {
Data: subject
}
},
Source: fromAddress
};
ses.sendEmail(params, function (err, data) {
if (err){
console.log(err, err.stack);
} else {
//sent
}
});
This ended up not having to do with the dash. The emails were bouncing because an AWS email service IP was blacklisted.

How to send SMS using Amazon SNS from a AWS lambda function

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

Inserting Google Analytics Content Experiments using the Node.JS Client Library

I'm trying to configure a content experiment using the Node.js Client Library, and have not been able to work out the syntax. Where do I put the body (an Experiment resource) as described here?
https://developers.google.com/analytics/devguides/config/mgmt/v3/mgmtExperimentsGuide#insert
This code, for listing existing experiments, works as expected:
var listExperiments = function(){
googleapis
.discover('analytics', 'v3')
.execute(function(err, client) {
var request = client
.analytics.management.experiments.list({
accountId : accountId,
webPropertyId : webPropertyId,
profileId : profileId
})
.withApiKey(browserAPIKey)
.withAuthClient(oauth2Client)
request.execute(function(err,result){
if (err){
console.log(err);
res.send(402);
} else {
console.log(result);
res.send(200);
}
});
});
}
However, when I try to insert a new experiment thusly, I receive a "Field resource is required" error.
var body = {
"name": "myExperimentName",
"status": "READY_TO_RUN",
"objectiveMetric":"ga:bounces",
"variations": [
{ "name": "text1", "url":"http://www.asite.net", "status":"ACTIVE" },
{ "name": "text2", "url":"http://www.asite.net", "status":"ACTIVE" }
]
};
var insertExperiment = function(){
googleapis
.discover('analytics', 'v3')
.execute(function(err, client) {
var request = client
.analytics.management.experiments.insert({
accountId : accountId,
webPropertyId : webPropertyId,
profileId : profileId,
resource : body
})
.withApiKey(browserAPIKey)
.withAuthClient(oauth2Client)
request.execute(function(err,result){
if (err){
console.log(err);
res.send(402);
} else {
console.log(result);
res.send(200);
}
});
});
}
I've tried a few configurations. Management API writes are in limited beta, but I have beta access, so that's not the problem. I've tried inserting the new experiment information directly into the insert() object, calling the experiment info object "body : body " instead of "resource : body", JSON.stringifying the body, and a few other configurations. No luck.
Any help would be great!
I'm aware of this answer, but it uses the Javascript Client Library and makes RESTful requests, whereas I'd like to use the Node Library.
EDIT: Thanks to Burcu Dogan at Google. Here's the correct syntax:
.analytics.management.experiments.insert({
accountId : accountId,
webPropertyId : webPropertyId,
profileId : profileId
}, body)

Resources