How to troubleshoot ASK ChangeReport failing with INVALID_REQUEST_EXCEPTION - alexa

Summary: I am getting an INVALID_REQUEST_EXCEPTION response when attempting to submit a ChangeReport event.
I'm troubleshooting with postman.
POSTing to: https://api.amazonalexa.com/v3/events
One header: Authorization with my token (if this is wrong, I get the correct error)
My body:
{
"event":{
"header":{
"messageId":"06a6278a-0c38-47e5-90e9-12eef0205487",
"namespace":"Alexa",
"name":"ChangeReport",
"payloadVersion":"3"
},
"endpoint":{
"scope":{
"type":"BearerToken",
"token":"XXX My Token XXX"
},
"endpointId":"BedroomLight"
},
"payload":{
"change": {
"cause" : {
"type" : "PHYSICAL_INTERACTION"
},
"properties":[
{
"namespace": "Alexa.PowerController",
"name": "powerState",
"value": "ON",
"timeOfSample": "2019-03-09T15:22:48Z",
"uncertaintyInMilliseconds": 500
}]
}
}
}
}
The response:
{
"header": {
"namespace": "System",
"name": "Exception",
"messageId": "bb7a3bb7-5c2c-4568-8a31-ae24a075f15e"
},
"payload": {
"code": "INVALID_REQUEST_EXCEPTION",
"description": "The request was malformed."
}
}
My input passes the schema validation.
I've tried substituting known invalid values to see if I could shift the error message and narrow down the root cause.
I compared to other code examples in Github and I'm not seeing an obvious error.
I'm not sure how to narrow the problem scope.

Contrary to my understanding above, I was not using the correct BearerToken. I was using the original OAuth code provided in the grant response (I didn't understand the LoginWithAmazon/LWA portion of the security exchange).
The further mistake that made this difficult was the lack of a security error. When I created the Authorization header, I left out the type (Bearer) and just had my value in the value area of the header, which might have been the base reason for the format error.

Related

Alexa Smart Home "Failed to Retrieve State"

I am playing with a sample Alexa Smart Home skill - I am not talking to any real hardware or back-end, just trying to get message flow working. I have set up a simple switch/plug/light that can just support turning On/Off - and I have account linked working and the skill enabled. When I try looking at it via the Alexa app on phone or web (with debug enabled) it always says the device isn't responding, or it's "Failed to Retrieve State". I can definitely see the messages in Cloud Watch as follows.
Any idea why I'd be chronically getting such a response??
Request:
"directive": {
"endpoint": {
"cookie": {},
"endpointId": "endpoint-003",
"scope": {
"token": "<<<SUPRESSING>>",
"type": "BearerToken"
}
},
"header": {
"correlationToken": "<<SHORTENED>>",
"messageId": "50397414-bb9d-412f-8a2c-15669978ab64",
"name": "ReportState",
"namespace": "Alexa",
"payloadVersion": "3"
},
"payload": {}
}
}
Response:
{
"context": {
"properties": [
{
"name": "connectivity",
"namespace": "Alexa.EndpointHealth",
"timeOfSample": "2020-06-29T16:49:59.00Z",
"uncertaintyInMilliseconds": 0,
"value": "OK"
},
{
"name": "powerState",
"namespace": "Alexa.PowerController",
"timeOfSample": "2020-06-29T16:49:59.00Z",
"uncertaintyInMilliseconds": 0,
"value": "ON"
}
]
},
"event": {
"endpoint": {
"endpointId": "endpoint-003",
"scope": {
"token": "Alexa-access-token",
"type": "BearerToken"
}
},
"header": {
"correlationToken": "<<SHORTENED>>",
"messageId": "7a8b9a71-adda-41b8-acba-4d3855374845",
"name": "Response",
"namespace": "Alexa",
"payloadVersion": "3"
},
"payload": {}
}
}
Problem was: The "name" in my header response should have been "ReportState". "Response" is only used for things that set/change values.
My general advice is to always verify that THREE things are good:
Initial "Discovery"
"Response" messages
General "ReportState" queries.
By this - I mean that:
Anything you advertised as should be reported in "discovery" better be reported in other ("ReportState") messages. If you advertise a "PowerController" - if your ReportStates don't contain status for that, you'll either not see the status, or it'll keep retrying forever (continuing to look for it) - or you might get some sort of an error.
If you CHANGED your discovery stuff - make sure that you really removed, re-discovered, and that the states (above) for the new additions/removals are okay
Always make sure that "EndpointHealth" is being reported.

change the header Content-Type to application/cloudevents+json when publishing to event grid

I'm using the trigger "When a HTTP request is received" to then publish multiple events to the event grid using the "Publish Event" action. The For loop works fine to split up the JSON that gets in and create the event to publish but still that publish fails with
{
"error": {
"code": "UnsupportedMediaType",
"message": "The Content-Type header is either missing or it doesn't have a valid value. The content type header must either be application/cloudevents+json; charset=utf-8 or application/cloudevents-batch+json; charset=UTF-8. Report 'edf36bbd-9221-4882-8a29-2264ffb16d72:3:3/6/2020 2:18:20 PM (UTC)' to our forums for assistance or raise a support ticket.",
"details": [
{
"code": "InvalidContentType",
"message": "The Content-Type header is either missing or it doesn't have a valid value. The content type header must either be application/cloudevents+json; charset=utf-8 or application/cloudevents-batch+json; charset=UTF-8. Report 'edf36bbd-9221-4882-8a29-2264ffb16d72:3:3/6/2020 2:18:20 PM (UTC)' to our forums for assistance or raise a support ticket."
}
]
}
}
I assume that the header from the input is used when publishing so I tried to change the header when publishing by changing the header in the Publish_Event block as follows (directly in code view as it is not supported in the UI) so I get the following (headers part is added):
"Publish_Event": {
"inputs": {
"body": [
{
"data": "#items('For_each_2')",
"eventType": "company-location",
"id": "ID : #{items('For_each')['businessId']}",
"subject": "Company Location changed"
}
],
"headers": {
"Content-Type": "application/cloudevents+json; charset=utf-8"
},
"host": {
"connection": {
"name": "#parameters('$connections')['azureeventgridpublish']['connectionId']"
}
},
"method": "post",
"path": "/eventGrid/api/events"
},
"runAfter": {},
"type": "ApiConnection"
}
But this is not working neither. Didn't find an action to make the change.
My full flow looks like this :
and as test data I have the following JSON I use to send with postman (a bit simplified):
[
{
"id": 3603,
"businessId": "QQTADOSH",
"locations": [
{
"id": 5316,
"businessId": "A-yelr3g"
},
{
"id": 5127,
"businessId": "A-c7i8gd"
},
{
"id": 5403,
"businessId": "A-fjdd2y"
},
{
"id": 6064,
"businessId": "A-rqvhz8"
}
]
},
{
"id": 3118,
"businessId": "Cr11_Macan_111qa",
"locations": [
{
"id": 4563,
"businessId": "A-3bv860"
}
]
}
]
Looks like the Official Event Grid Publish Connector doesn't support Cloud Events Schema.
You can set the topic to accept Event Grid Schema but I believe this is possible only at the time of creation.
Its best to open a feature request on UserVoice to add support for this and in the meantime, a workaround would be to use an HTTP Action to Post to Custom Topic instead.
But do note that the workaround would involve building the event payload to send (and things like fetching the access key from Key Vault instead of storing it in your workflow directly).

Unable to debug "There was a problem with the requested skill's response"

Background: I am working through a flashcard Skill that enables Alexa to ask basic questions about a programming language. The user can choose between Ruby, Python or JS.
The progression goes:
LaunchRequest welcomes the user, then asks for their language preference
User responds, causing SetLanguageIntent to trigger
A question is then asked of the user
However, I am unable to get past the SetLanguageIntent without encountering "There was a problem with the requested skill's response".
Here is the dialogue:
As one can see from the response, SetLanguageIntent is activated properly with the slot ruby also matching correctly.
"request": {
"type": "IntentRequest",
"requestId": "amzn1.echo-api.request.743f750e-96d9-4ef9-aeba-e0aec2e45afb",
"timestamp": "2018-09-12T13:35:25Z",
"locale": "en-US",
"intent": {
"name": "SetMyLanguageIntent",
"confirmationStatus": "NONE",
"slots": {
"language": {
"name": "language",
"value": "ruby",
"resolutions": {
"resolutionsPerAuthority": [
{
"authority": "amzn1.er-authority.echo-sdk.amzn1.ask.skill.ee34487d-d343-4deb-ab6c-193777c92aa8.languages",
"status": {
"code": "ER_SUCCESS_MATCH"
},
"values": [
{
"value": {
"name": "ruby",
"id": "58e53d1324eef6265fdb97b08ed9aadf"
}
}
]
}
]
},
"confirmationStatus": "NONE"
}
}
}
However, at this point the error message "There was a problem with the requested skill's response" always appears. There are no errors reported on CloudWatch Logs.
For reference, here is the SetLanguageIntent code. As noted in the comment, the test "Okay" should at least have been said. However, it does not get executed.
'SetMyLanguageIntent': function() {
this.response.speak('Okay'); //this should at least have been said
this.attributes.flashcards.currentLanguage = this.event.request.intent.slots.languages.value;
var currentLanguage = this.attributes.flashcards.currentLanguage
this.response
.speak('Okay, I will ask you some questions about ' +
currentLanguage + '. Here is your first question. ' +
AskQuestion(this.attributes))
.listen(AskQuestion(this.attributes));
this.emit(':responseReady');
},
Any help is much appreciated!
Edit: updated with slot names
I see a problem with your code. This is why you're probably having an issue. You are trying to access an undefined property this.event.request.intent.slots.languages.value. The mistake is word languages. It should be language.
So the way to acces a slot value should be:
this.event.request.intent.slots.language.value
I fixed the same problem for myself by simply adding a cardRenderer() to my response. Like this:
this.response.speak("my text").cardRenderer("ttitle","some content","image");
In the test simulator's device log, I noticed the card renderer show up, saying the skill responded with a failure. So I took a shot and it worked. Hopefully this fixes it for you too!

Server side errors handling with angular-formly

I'm looking for solution on how I can display errors that the server respond, this is the respond for every invalid submission so I want to make the error handler in the app level and not in a controller.
I want to display the errors both on the FORM level and on the field level.
I have a REST API that in case of error return the following JSON object:
{
"message": "Validation error: Validation notEmpty failed,\nValidation error: Validation isEmail failed",
"errors": [
{
"field": "username",
"message": "Validation notEmpty failed"
},
{
"field": "email",
"message": "Validation isEmail failed"
}
]
}
How can I create a service that display the errors in case there is any?
Thanks
So, i created this for another answer. Let me know if this sort of a setup works for you. Here, the error is intended to be displayed on response from the server after button click. You can modify it accordingly.
I have given the field a custom template as follows:
formlyConfigProvider.setWrapper({
name: 'inputWrapper',
template: '<div ng-class="to.changeColor==\'red\'? \'redBorder\' : \'otherBorder\'"><formly-transclude></formly-transclude>{{to.keyVal}}</div>'
});
The form elements are defined through a schema format to allow each element to be individually accessed.
vm.schema={
"schema": {
"coolValue" : [{
"key": "coolValue",
"type": "input",
"wrapper": ['inputWrapper'],
"templateOptions": {
"type" : "text",
"label": 'Cool Value',
"keyVal":"",
"changeColor":"green"
}
}]
}
};
Finally, the onSubmit function
function onSubmit() {
//Do whatever you want here
//Let's say your server returns an error "iNVALID Credentials"
var response={
"error": {
"errors": [
{
"domain": "global",
"reason": "authError",
"message": "Invalid Credentials",
"locationType": "header",
"location": "Authorization",
}
],
"code": 401,
"message": "Invalid Credentials"
}
};
vm.schema.schema.coolValue[0].templateOptions.changeColor="red";
vm.schema.schema.coolValue[0].templateOptions.keyVal=response.error.message;
}
});
You can essentially pass any error message or response from the server here.
The CSS contains a class to add a red border to the field.You are free to disable this.Feel free to ping if you need anything in this area as well.
Here is a DEMO

In Camel sending the query params as part of the main url as against sending query params via Exchange.HTTP_QUERY

In camel 2.16.1 I am sending a HTTPS POST request via Camel's HTTP4 Component. The url looks like below:-
https4://debraj:debraj#example.com/oms-api/?Action=UpdateOrderInformation&ServiceName=OMS&Signature=25566099c0b6b6c5123bbfede4c91590512050668f957e2a43ef982a0dcf1c00&Timestamp=2016-04-14T12%3A44%3A17+0530&Version=1.0
The body looks something like below:-
{
"Request": {
"Orders": [
{
"id_sales_order": 397,
"address_billing": {
"first_name": "John",
"last_name": "Doe",
"phone": "1234567",
"phone2": "1234",
"address1": "Sesamestreet 123",
"city": "Berlin",
"postcode": "12345",
"country": "Germany"
}
}
]
}
}
It is returning me:-
{
"ErrorResponse": {
"Head": {
"RequestAction": "UpdateOrderInformation",
"ErrorType": "Sender",
"ErrorCode": "7",
"ErrorMessage": "E007: Login failed. Signature mismatch"
},
"Body": ""
}
}
If the same request is made by sending the query parameters under Exchange.HTTP_QUERY then it is giving me the correct response:-
headers.put(Exchange.HTTP_QUERY, "Action=UpdateOrderInformation&ServiceName=OMS&Signature=25566099c0b6b6c5123bbfede4c91590512050668f957e2a43ef982a0dcf1c00&Timestamp=2016-04-14T12%3A44%3A17+0530&Version=1.0")
{
"SuccessResponse": {
"Head": {
"RequestId": "",
"RequestAction": "UpdateOrderInformation",
"ResponseType": "",
"Timestamp": "2015-07-02T12:26:03+0200"
},
"Body": []
}
Can someone please let me know:-
Why the above two cases are behaving differently?
Is it always recommended to send query parameters under Exchange.HTTP_QUERY? I am asking this because sending the query parameters with the main url is not failing always.
If something is not clear about my question please ask for it I will try to explain.
That is because your query parameters are changing every time i.e. your signature changes. Your signature sometimes could simply be having a + sign or SPACE in it (or characters like that) and then http4 converts the sign to %20 (or something else, depending on the character). You can inspect the signature the times that it fails, and determine if this is the case. I can't remember how I solved this issue in the past, but it seems like you have a solution already in hand. Hope this clarifies.

Resources