In AWS IoT core, I set up a rule with a republish action to update a thing's shadow (TestThing's shadow) like this
(I created new IAM role for the action in case you are wondering)
What I was expecting was that the thing's shadow should be updated and nothing should be published to 'testthing/error' when I publish a message to 'testthing/message'. But when I published the following message to 'testthing/message' with AWS IoT MQTT client
{
"state":
{
"reported":
{
"Info":"Hello AWS IoT!"
}
}
}
I got this error from 'testthing/error':
...
"failedAction": "RepublishAction",
"failedResource": "/things/TestThing/shadow/update",
"errorMessage": "Failed to republish to topic. Received Server error. The error code is 403. Message arrived on: testthing/message, Topic: /things/TestThing/shadow/update"
...
If I change the topic to which the message should be republished into 'testthing/destination', everything works fine, no error message was published to 'testthing/error'.
Am I missing something?
$aws/# is a reserved topic.
As per AWS Documentation here:
If you are republishing to a reserved topic, one that begins with $ use $$ instead.
Please replace $ with $$ and try again!
cheers,
ram
Related
While using AWS AppSync SDK to add subscription its returning this error, but I got the result in AWS console.
errorType: "BadRequestException"
message: "Subscriptions over MQTT is not supported."
I have seen this similar question and tried the answers that doesn't worked for me.
Is there any way to solve this error? looking forward to the suggestions
Thank you
This happens due to de deprecation of MQTT
So instead of configuring
createSubscriptionHandshakeLink as createSubscriptionHandshakeLink(url, httpLink)
you must use createSubscriptionHandshakeLink({ url, region, auth }) or it will result to using MQTT
ref:
https://github.com/awslabs/aws-mobile-appsync-sdk-js/issues/628
It seems impossible to use the AWS command line API (or Java SDK) to opt-in a phone number that has opted out of SMS (by sending a STOP message). Here's a command line example (with phone number redacted):
> aws sns check-if-phone-number-is-opted-out --phone-number "612XXXYYYY"
{ "isOptedOut": false }
So a country code is required. Adding that, I see the opt out with either a "+" or not:
> aws sns check-if-phone-number-is-opted-out --phone-number "+1612XXXYYYY"
{ "isOptedOut": true }
> aws sns check-if-phone-number-is-opted-out --phone-number "1612XXXYYYY"
{ "isOptedOut": true }
So then I try to opt that number back in:
> aws sns opt-in-phone-number --phone-number "+1612XXXYYYY"
An error occurred (InvalidParameter) when calling the OptInPhoneNumber operation: Invalid parameter:
> aws sns opt-in-phone-number --phone-number "1612XXXYYYY"
An error occurred (InvalidParameter) when calling the OptInPhoneNumber operation: Invalid parameter:
> aws sns opt-in-phone-number --phone-number "612XXXYYYY"
That last one without a country code doesn't return an error, but it also doesn't do anything:
> aws sns check-if-phone-number-is-opted-out --phone-number "1612XXXYYYY"
{ "isOptedOut": true }
For fun, here is the Java SDK version, which also doesn't work:
SnsClient snsClient = SnsClient.builder().region(Region.US_WEST_2).build();
OptInPhoneNumberResponse response = snsClient.optInPhoneNumber(b -> b.phoneNumber("1612XXXYYYY"));
Is there a way to programmatically remove a phone number from the SMS opt-out list? I can do it manually using the web console, but this doesn't help.
According to the Amazon SNS documentation for OptInPhoneNumber:
You can opt in a phone number only once every 30 days.
The above commands/code will work for reversing a STOP request, but only once. Apparently after sending the second STOP reply, AWS will no longer allow you to opt in to receiving SMS messages again with that phone number. So if you want to support more than one STOP->START sequence if you have to "Enable self-managed opt-outs" in Pinpoint and take care of handling it all yourself.
I'm trying to get my IoT device to fire off a Lambda function. Been trying for a few hours to no avail.
My lambda function is simple:
exports.handler = async (event) => {
// TODO implement
const response = {
statusCode: 200,
body: JSON.stringify(event.message),
};
return response;
};
I've setup my IoT rule to trigger the lambda function with SELECT * FROM 'iot/trigger-lambda'. When I publish a message to the iot/trigger-lambda topic from AWS IoT's Test functionality, the lambda function triggers successfully. But, when I publish my message from my device, I get the following error:
{
"ruleName": "ruleTriggerLambda",
"topic": "iot/trigger-lambda",
"cloudwatchTraceId": "xxx-yyy-zzz",
"clientId": "ABC123",
"base64OriginalPayload": "eydvcGVyYGTpb24nOiAncHV0T2JqZWN0JywgJ2J1Y2tldCc6ICdyZWR3YXZlLWFwcC1kZXYnLCAna2V5JzogJ3JlYWNoYmFjay56aXAnLQWncmVwbHlUbyc6ICdpb3QvdGhyGHT0aWQtMDAwMS9wcmUtc2lnbmVkLBNzLXVybC1yBBNwb25zZXMnfSBbMV0=",
"failures": [
{
"failedAction": "LambdaAction",
"failedResource": "arn:aws:lambda:us-east-1:xxx:function:lambdaTriggerLambda",
"errorMessage": "Failed to invoke lambda function. Received Server error from Lambda. The error code is 400"
}
]
}
When I added the lambda function to my rule, AWS indicated it would create the correction permissions. I've also tried updating the permissions of the lambda function.
Any suggestions on how to fix this? Any help/information is much appreciated.
Edit: after 4 hours or ripping my hair out
It turned out to be the format of the data that I was sending as a payload from my IoT device. Let me explain, if someone can tell me why this is, I'd love to know.
I was using my mac as my device and I implemented this code from the AWS IoT Python SDK. My message looked like this:
message = {"message": "test message"}
It seems like pretty straight forward json.
The code that is publishing the message looks like this:
mqtt_connection.publish(
topic=args.topic,
payload=args.message,
qos=mqtt.QoS.AT_LEAST_ONCE)
The payload being received at AWS IoT Core looked like this:
{'message': 'test message'} [1]
And was accompanied by an error message like so: We cannot display the message as JSON, and are instead displaying it as UTF-8 String.
I guess I'm a little dense for not connecting the dots but it turns out I had to do the following to my code:
mqtt_connection.publish(
topic=args.topic,
payload=json.dumps(args.message).replace("\"", '').replace("[1]", '').replace("'", '"'),
qos=mqtt.QoS.AT_LEAST_ONCE)
Hopefully this explanation will help someone in the future.
I am using AWS resources for my android project, I am planning to add push notification service for my project with AWS SNS.there are few questions bothering me much. I did not find any questions regarding these, except one or two but with unclear explanations.
1.Does AWS support FCM? SNS work with GCM. But Google recommends to use FCM instead of GCM. I did not find AWS supporting FCM.
2.Do AWS store messages (or data) into their databases even after sending push notifications?
3.I tried putting FCM api key in SNS application platform, it is showing invalid parameters why?
FCM is backwards compatible with GCM. The steps for setting up FCM on AWS are identical to the GCM set up procedure and (at least for the moment) FCM works transparently with GCM and SNS with respect to server-side configuration.
However, if you are sending data payloads to the Android device they will not be processed unless you implement a client side service that extends FirebaseMessagingService. The default JSON message generator in the AWS console sends data messages, which will be ignored by your app unless the aforementioned service is implemented. To get around this for initial testing you can provide a custom notification payload which will be received by your device (as long as your app is not in the foreground)
There are GCM-FCM migration instructions provided by Google however the changes you need to make are predominantly on the App side.
The steps you need to follow to test GCM/FCM on your app with SNS are:
Create a Platform Application in SNS, selecting Google Cloud Messaging (GCM) as the Push Notification Platform, and providing your Server API key in the API key field.
Select the Platform Application and click the Create platform endpoint button.
Provide the InstanceID (Device Token) generated by your app. You must extend the FirebaseInstanceIDService and override the onTokenRefresh method to see this within your Android App. Once you have done this, uninstall and reinstall your app and your token should be printed to the Debug console in Android Studio on first boot.
Click the Add endpoint button.
Click on the ARN link for your platform application.
Select the newly created Endpoint for your device and click the Publish to endpoint button.
Select the JSON Message Format, and click the JSON message generator button.
Enter a test message and click the Generate JSON button
Now comes the "gotcha part".
The message that is generated by SNS will be of the form:
{
"GCM": "{ \"data\": { \"message\": \"test message\" } }"
}
As we mentioned earlier, data payloads will be ignored if no service to receive them has been implemented. We would like to test without writing too much code, so instead we should send a notification payload. To do this, simply change the JSON message to read:
{
"GCM": "{ \"notification\": { \"title\": \"test title\", \"body\": \"test body\" } }"
}
(For more information about the JSON format of an FCM message, see the FCM documentation.)
Once you have done this, make sure your app is not running on the device, and hit the Publish Message button. You should now see a notification pop up on your device.
You can of course do all this programmatically through the Amazon SNS API, however all the examples seem to use the data payload so you need to keep that in mind and generate a payload appropriate to your use case.
Now you can go to your firebase console (https://console.firebase.google.com/) select your project, click the gear icon and choose project settings, then click on the cloud messaging tab...
You'll see the legacy Server Key which is the GCM API Key and you'll have the option to generate new Server Keys which are the FCM versions
SNS will accept both versions but their menu option is still categorizing it under GCM
Here is picture for your reference:
Note that you can "accidentally" remove your Server Keys but the Legacy server key is not deletable. Also, if you click the add server key button, you'll get a new server key BELOW the first one, WITH NO WARNING! ...Nice job Google ;)
One more additional note to Nathan Dunn's great answer.
How to send data with the notification from SNS to Firebase.
We need to add data to the Json (inside the notification):
{
"default": “any value",
"GCM": "{ \"notification\": { \"body\": \”message body\”, \”title\”: \”message title \”, \"sound\":\"default\" } , \"data\" : {\”key\" : \”value\", \”key2\" : \”value\” } }”
}
In your FirebaseMessagingService implementation (Xamarin example)
public override void OnMessageReceived(RemoteMessage message)
{
try
{
var body = message?.GetNotification()?.Body;
var title = message?.GetNotification()?.Title;
var tag = message?.GetNotification()?.Tag;
var sound = message?.GetNotification()?.Sound;
var data = message?.Data
foreach (string key in data.Keys)
{
// get your data values here
}
}
catch (Exception e)
{
}
}
I tried to use solution with notification payload instead of data, but I did not receive push notifications on the mobile device. I found this tutorial https://youtu.be/iBTFLu30dSg with English subtitles of how to use FCM with AWS SNS step by step and example of how to send push notifications from AWS console and implement it on php with aws php sdk. It helped me a lot.
Just an additional note to Nathan Dunn's Answer: to add sound use the following JSON message
{
"GCM": "{ \"notification\": { \"text\": \"test message\",\"sound\":\"default\" } }"
}
It took me a while to figure out how to send the notification with the right payload (publish to topic). So I will put it here.
private void PublishToTopic(string topicArn)
{
AmazonSimpleNotificationServiceClient snsClient =
new AmazonSimpleNotificationServiceClient(Amazon.RegionEndpoint.EUWest1);
PublishRequest publishRequest = new PublishRequest();
publishRequest.TopicArn = topicArn;
publishRequest.MessageStructure = "json";
string payload = "\\\"data\\\":{\\\"text\\\":\\\"Test \\\"}";
publishRequest.Message = "{\"default\": \"default\",\"GCM\":\"{" + payload + "}\"}";
PublishResponse publishResult = snsClient.Publish(publishRequest);
}
Amazon does support FCM as all previous code has been migrated from GCM to FCM. Below article explains in detail.
Article Published by Amazon
To answer the questions:
AWS SNS does support FCM.
No AWS does not store messages after sending push notifications.
For a detailed tutorial on setting up FCM with SNS please read this article.
I have configured a data pipeline which executes a SQL statement and dumps data into a S3 bucket. Everything in the pipeline is working fine. The data is being dumped successfully. Today I added an SNSAlarm to the OnSuccess event on my Activity and subscribed a SQS queue to that SNS topic. However, I do not get any message in the queue even though the Activity succeeds and neither do I see any sort of log related to SNS success or failure.
Has anyone used SnsAlarm in AWS Datapipeline before? Any help would be great.
Yes, you can attach snsAlarms (they are an action of a datapipeline) to Activities as well as the pipeline itself.
{
"id" : "SuccessNotify",
"name" : "SuccessNotify",
"type" : "SnsAlarm",
"topicArn" : "arn:aws:sns:us-east-1:28619EXAMPLE:ExampleTopic",
"subject" : "COPY SUCCESS: #{node.#scheduledStartTime}",
"message" : "Files were copied from #{node.input} to #{node.output}."
}
Be sure to update topicArn with the Arn of the SNS topic you wish to receive alerts at.
More Info: http://docs.aws.amazon.com/datapipeline/latest/DeveloperGuide/dp-object-snsalarm.html
More Info on Datapipeline Objects: http://docs.aws.amazon.com/datapipeline/latest/DeveloperGuide/dp-pipeline-objects.html