Cannot send aps to iOS using aws-sdk-js - amazon-web-services

I am trying to use aws-sdk-js to send push notification to iOS and Android device. It can send the notification message, but it is not the one I wanted. If i put badge and sound in the aps dictionary, the app should have a badge and play a sound. But it did not.
Xcode console output:
[aps: {
alert = "Test Message";
}]
javascript code:
var AWS = require('aws-sdk');
AWS.config.update({accessKeyId: '<key>', secretAccessKey: '<secrect>'});
AWS.config.update({region: 'ap-southeast-2'});
var sns = new AWS.SNS();
var payload = {
default: 'Test Message',
APNS: {
aps: {
alert: 'Test Message on iPhone',
badge: 1,
sound: "default"
},
}
};
payload.APNS = JSON.stringify(payload.APNS);
payload = JSON.stringify(payload);
var params = {
MessageStructure: 'json',
Message: payload,
Subject: 'Test push',
TargetArn: '<arn of the endpoint>'
};
sns.publish(params, function(err, data) {
if (err) console.log(err, err.stack);
else console.log(data);
});
code in application:didfinishlaunch,
let acceptAction = UIMutableUserNotificationAction()
acceptAction.identifier = "ACCEPT_IDENTIFIER"
acceptAction.title = NSLocalizedString("Accept", comment: "Accept")
acceptAction.activationMode = .Foreground
acceptAction.destructive = false
acceptAction.authenticationRequired = false
let deleteAction = UIMutableUserNotificationAction()
deleteAction.identifier = "DELETE_IDENTIFIER"
deleteAction.title = NSLocalizedString("Delete", comment: "Delete")
deleteAction.activationMode = .Foreground
deleteAction.destructive = true
deleteAction.authenticationRequired = false
let ignoreAction = UIMutableUserNotificationAction()
ignoreAction.identifier = "IGNORE_IDENTIFIER"
ignoreAction.title = NSLocalizedString("Ignore", comment: "Ignore")
deleteAction.activationMode = .Foreground
deleteAction.destructive = false
deleteAction.authenticationRequired = false
let messageCategory = UIMutableUserNotificationCategory()
messageCategory.identifier = "MESSAGE_CATEGORY"
messageCategory.setActions([acceptAction, deleteAction], forContext: .Minimal)
messageCategory.setActions([acceptAction, deleteAction, ignoreAction], forContext: .Default)
let notificationSettings = UIUserNotificationSettings(forTypes: [.Badge, .Sound, .Alert], categories: (NSSet(array: [messageCategory])) as? Set<UIUserNotificationCategory>)
UIApplication.sharedApplication().registerForRemoteNotifications()
UIApplication.sharedApplication().registerUserNotificationSettings(notificationSettings)
and implement the protocol:
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
print(userInfo)
}
func application(application: UIApplication, handleActionWithIdentifier identifier: String?, forRemoteNotification userInfo: [NSObject : AnyObject], withResponseInfo responseInfo: [NSObject : AnyObject], completionHandler: () -> Void) {
print(identifier)
completionHandler()
}

If you are using a developer profile for apns you should write APNS_SANDBOX instead of APNS
var payload = {
default: 'Test Message',
APNS_SANDBOX: {
aps: {
alert: 'Test Message on iPhone',
badge: 1,
sound: "default"
},
}
};

Related

Description field is coming as [ARRAY] instead of the actual array([1,2,3]) in dynamodb when I try to get data using query

Items: [
{
Continent: 'Continent#Antarctica',
SKCountry: 'Country#Chile',
CreatedAt: 1668579154424,
description: [Array],
PKContinent: 'PKContinent',
id: 16,
UpdatedAt: 1668579154424
},
{
Continent: 'Continent#Antarctica',
SKCountry: 'Country#France',
CreatedAt: 1668579154424,
description: [Array],
PKContinent: 'PKContinent',
id: 15,
UpdatedAt: 1668579154424
}]
, this is what I am getting but instead of "description: [Array],", I want this, description: [value1, value2, value3]. Also, I am getting this data in console but in browser I am getting an error in console (Uncaught TypeError: Cannot read properties of undefined (reading 'tagName')).
this is the code snippet in getAllItems.
var AWS = require("aws-sdk");
AWS.config.update({
region: "local",
endpoint: "http://localhost:8000"
});
var docClient = new AWS.DynamoDB.DocumentClient()
var table = "Tourism";
const getAllItems = async ()=> {
var PKContinent = "PKContinent";
//console.log("check",PKContinent)
const params = {
TableName: table,
KeyConditionExpression: "PKContinent = :pkUpdate AND begins_with(SKCountry, :SKCountry)",
ExpressionAttributeValues: {
":pkUpdate": PKContinent,
":SKCountry": "Country#"
}
}
docClient.query(params, function (error, data) {
if (error) {
console.log(error)
} else {
var viewArray = [];
if (data.Items.length === 0) {
console.log("data doesn't exists.")
}
else {
console.log(data);
}
}
})
}
module.exports = {
docClient,
getAllItems
};
this is the code in getAll
var express = require('express');
var router = express.Router();
const { getAllItems} = require('../getAllItems');
router.get('/', async (req, res, next) => {
try {
const getData = await getAllItems();
res.json(getData);
} catch (err) {
console.error(err);
res.status(500).json({ err: 'Something went wrong with get' });
}
});
module.exports = router;
For me I believe the issue is when saving the data, not reading it.
You mention you cannot read the data in tbe console? Can you share a screenshot of how that looks in your question.
And can you also share the output of the console which you stated worked, I'll be able to guide you to the issue then.

Lambda used SNS to send SMS but stopped working

I was just having fun in sending me SMS from a Lambda called via API Gateway (REST API). No problem at all until it suddendly stopped sending SMS. I'm actually using a free tier level on my AWS account, but in no way I have reached the maximum sendable SMS limit.
Permissions and roles have not been modified from yesterday when text messages still were arriving to my verified mobile number.
As you can see, inside my code, I used a "test2" variable to return the result for SMS sending but it's barely useless.
Is there any way to better undestand the error behind this problem? And why am I getting it all of a sudden?
My lambda code:
const AWS = require("aws-sdk");
const dynamo = new AWS.DynamoDB.DocumentClient();
const SNS = new AWS.SNS();
const tableName = "Testing";
const smsMessage = {
PhoneNumber: '+39#mynumber#',
Message: 'Someone called your api!'
};
const httpMethodConverter = 'http-method';
const pathRequestConverter = "resource-path";
const headers = {
"Access-Control-Allow-Origin":"https://#myaccount#.github.io",
"Content-Type": "application/json",
"Access-Control-Allow-Methods": "GET, POST, PATCH, PUT, DELETE, OPTIONS",
"Access-Control-Allow-Headers": "Origin, Content-Type, X-Auth-Token"
};
let body;
let statusCode = 200;
let test2;
exports.handler = async (event, context) => {
try {
let test = JSON.stringify(event);
let callContext = event.context;
let httpMethod = callContext[httpMethodConverter];
let path = callContext[pathRequestConverter];
let methodAndPath = httpMethod + " "+ path;
test2= await SNS.publish(smsMessage).promise();
switch (methodAndPath) {
case "DELETE /items/{id}":
await dynamo
.delete({
TableName: tableName,
Key: {
Id: parseInt(JSON.parse(test).params.path.id)
}
})
.promise();
body = `Deleted item ${JSON.parse(test).params.path.id}`;
break;
case "GET /items/{id}":
body = await dynamo
.get({
TableName: tableName,
Key: {
Id: parseInt(JSON.parse(test).params.path.id)
}
})
.promise();
break;
case "GET /items":
body = await dynamo.scan({ TableName: tableName }).promise();
break;
case "POST /items":
var bodyParser = "body-json";
var bodyPassed = JSON.parse(test)[bodyParser];
await dynamo
.put({
TableName: tableName,
Item: {
Id: parseInt(bodyPassed.Id),
Type: bodyPassed.Type
}
})
.promise();
body = "Put item "+ bodyPassed.Type+ " id: " + parseInt(bodyPassed.Id);
break;
default:
throw new Error(`Unsupported route: "${event.context}"`);
}
} catch (err) {
statusCode = 400;
body = err.message;
} finally {
body = JSON.stringify(body);
}
return {
statusCode,
body,
headers,
test2
};
};
This is the answer for my SNS.publish(message).promise
"test2": {
"ResponseMetadata": {
"RequestId": "b2fbd9fc-4cc0-54e8-a660-82#########"
},
"MessageId": "c94393bf-cbb3-5cb9-8155-c#########"
}
If you enable delivery status logging through e.g. https://docs.aws.amazon.com/sns/latest/dg/sms_stats_cloudwatch.html, you should receive an error message detailing why the message could not be delivered. Most likely, you've hit the default monthly $1 spend limit quota.

AWS SES send email lambda not sending every time

I want to send emails using the ses from aws from lambda. The problem is that the email is only sent some times using the same code. We don't get errors.
Here's the code:
const AWS = require('aws-sdk');
var ses = new AWS.SES();
exports.handler = async (event, context, callback) => {
context.callbackWaitsForEmptyEventLoop = false;
await new Promise((resolve, reject) => {
var params = {
Destination: {
ToAddresses: [myEmail]
},
Message: {
Body: {
Text: { Data: "Test"
}
},
Subject: { Data: "Test Email"
}
},
Source: "sourceMail"
};
ses.sendEmail(params, function (err, data) {
if (err) {
console.log(err);
context.fail(err);
} else {
console.log(data);
context.succeed(event);
}
callback(null, {err: err, data: data});
});
});
}
I would be careful with using callbackWaitsForEmptyEventLoop as it can lead to unexpected results (If this is false, any outstanding events continue to run during the next invocation.).
Can you try using this simplified version:
const AWS = require('aws-sdk');
var ses = new AWS.SES();
exports.handler = async (event, context, callback) => {
const params = {
Destination: {
ToAddresses: [myEmail],
},
Message: {
Body: {
Text: { Data: 'Test' },
},
Subject: { Data: 'Test Email' },
},
Source: 'sourceMail',
};
await ses.sendEmail(params).promise();
return event;
};

MissingRequiredParameter: Missing required key 'Message' in params

I'm trying to invoke a code in AWS Lambda. This Lambda code has been configured with my IOT button. On running this code, I don't see any errors. Also,I don't really see the required push notification on my mobile device.
I can see this message in my console : MissingRequiredParameter: Missing required key 'Message' in params
This is my code:
'use strict';
console.log('Loading function');
var AWS = require('aws-sdk');
var sns = new AWS.SNS();
AWS.config.region = 'xxxxx';
const TopicArn = 'xxxxxxxxxxxxxxxxxxxxxxxxxx'
exports.handler = function(event, context) {
console.log("\n\nLoading handler\n\n");
console.log('Received event:', event);
const sin =
{
"default": "Start",
"APNS_SANDBOX":"{\"aps\":{\"alert\":\"Start\"}}",
"GCM": "{ \"notification\": { \"text\": \"Start\" } }"
} // for single click
const doub = {
"default": "Stop",
"APNS_SANDBOX":"{\"aps\":{\"alert\":\"Stop\"}}",
"GCM": "{ \"notification\": { \"text\": \"Stop\" } }"
} // for double click
const lon = {
"default": "SOS",
"APNS_SANDBOX":"{\"aps\":{\"alert\":\"SOS\"}}",
"GCM": "{ \"notification\": { \"text\": \"SOS\" } }"
} // for long click
var singleClick = sin[Math.floor(Math.random()*sin.length)];
var doubleClick = doub[Math.floor(Math.random()*doub.length)];
var longClick = lon[Math.floor(Math.random()*lon.length)];
var randomMessage = singleClick;
if(event.clickType == "DOUBLE")
{
randomMessage = doubleClick;
}
if(event.clickType == "LONG")
{
randomMessage = longClick;
}
sns.publish ({
Message: randomMessage,
TopicArn: TopicArn
},
function(err, data) {
if (err) {
console.log(err.stack);
return;
}
console.log('push sent');
console.log(data);
context.done(null, 'Function Finished!');
});
}
Can someone help me debug this error?
I found the answer. I had to define my variable too as a string using stringify() command or else JSON formatted message cannot be sent.

Parse Server - Missing Push Configuration?

I've been trying to get push notifications to work with my Parse application. I tried to do so my adding the below code into my Parse server.js file but my server does not start up again when this code is contained inside of the file. I have my p12 file available and linked in the code below (on my actual sever) as well so Im not sure what the issue is.
push: {
android: {
senderId: '...',
apiKey: '...'
},
ios: {
pfx: '/file/path/to/XXX.p12',
passphrase: '', // optional password to your p12/PFX
bundleId: '',
production: false
}
}
My server is running on an Amazon EC2 instance as well.
Are you using AWS SNS to use push notification? If so, you can try setting this in your server code:
function sendPhoneNotification() {
AWS = require('aws-sdk');
AWS.config.update({
accessKeyId: '***',
secretAccessKey: '***',
region: 'ap-southeast-1'
});
var sns = new AWS.SNS();
var promise = new Parse.Promise();
sns.createPlatformEndpoint({
PlatformApplicationArn: '***',
Token: "***"
}, function (err, data) {
if (err) {
console.log("Error in endpoint" + err.stack);
//res.error("error stack 1: " + err.stack);
promise.reject(err.stack);
return promise;
}
var endpointArn = data.EndpointArn;
var payload = {
GCM: {
data: {
title: "YOUR TITLE",
message: "HELLO PUSH NOTIFICATION"
}
}
/* APNS: {
aps: {
alert: 'Hello World',
sound: 'default',
badge: 1
}
}*/
};
// payload.APNS = JSON.stringify(payload.APNS);
payload.GCM = JSON.stringify(payload.GCM);
payload = JSON.stringify(payload);
var result = sns.publish({
Message: payload,
MessageStructure: 'json',
TargetArn: endpointArn
}, function (err, data) {
if (err) {
promise.reject(err.stack);
return promise;
}
res.success("push sent " + JSON.stringify(data));
});
});
return promise;
}