Alexa SmartHome Skills : Issue with device discovery - amazon-web-services

I have written an Alexa smart home skills.
When I try to discover the device using the Alexa test or from the mobile app, the lambda is triggered.
The lambda is getting successfully executed, but I get below error in App or test in Alexa console.
I couldn't find any new Smart Home devices. If you’ve ‎n't already,
please enable the smart home skill for your device from the Alexa App.
What could be the possible issue?
Since the lambda is getting successfully executed, I don't think there is any issue with language (English(IN)) or AWS region (EU-WEST-1) , where the lambda is deployed.
I didn't see any logs on Alexa developer console
Any pointers?
Response from Lambda function -
header =
{
namespace: 'Alexa.Discovery',
name: 'Discover.Response',
payloadVersion: '3',
messageId: '785f0173-6ddb-41d8-a785-de7159c7f7ca'
}
payload =
{
"endpoints": [
{
"endpointId": "d4b87cbe6c8e490493733f260b8c2c25",
"friendlyName": "Kitchen",
"description": "Demo",
"manufacturerName": "Man1",
"displayCategories": [
"LIGHT"
],
"cookie": {
"owner": "Owner1"
},
"capabilities": [
{
"type": "AlexaInterface",
"version": "3",
"interface": "Alexa"
},
{
"type": "AlexaInterface",
"version": "3",
"interface": "Alexa.PowerController",
"properties": {
"supported": [
{
"name": "powerState"
}
],
"proactivelyReported": true,
"retrievable": true
}
},
{
"type": "AlexaInterface",
"version": "3",
"interface": "Alexa.BrightnessController",
"properties": {
"supported": [
{
"name": "brightness"
}
],
"proactivelyReported": true,
"retrievable": true
}
}
]
}
]
}
We are wrapping header and payload in the response event.
context.succeed({ event: { header: header, payload: payload } });

So far I haven't found a way to view the logs either.
I had the same problem and I realized that I was putting wrong values in some properties or schema entities like ids.
In the same way, another thing that solved me on some occasion was to place the scheme in the following way:
context.succeed({
"event": {
"header": {
"namespace": "Alexa.Discovery",
"name": "Discover.Response",
"payloadVersion": "3",
"messageId": header.messageId
},
"payload": {
"endpoints": [
{
"endpointId": "demo_id",
...
,
"cookie": {},
"capabilities": [
{
"type": "AlexaInterface",
"interface": "Alexa",
"version": "3"
},
...
]
}
]
}
}
});

Related

CodePipeline, CodeBuild, CloudFormation, Lambda: build multiple lambdas in a single build and assign their code correctly

I have a CD pipeline built with AWS CDK and CodePipeline. It compiles the code for 5 lambdas, each of which it pushes to a secondary artifact.
The S3 locations of each of the artifacts are assigned to the parameters of a CloudFormation template which are attached to the Code parts of the lambdas.
This is working fine!
My problem is, I cannot add a sixth secondary artifact to CodeBuild (hard limit). I also cannot combine all of my lambda code into a single artifact as (as far as I can see) CodePipeline is not smart enough to look inside an artifact when assigning Code to a lambda in CloudFormation.
What is the recommendation for deploying multiple lambdas from a CodeBuild/CodePipeline? How have other people solved this issue?
EDIT: Code pipeline CF template
note: I have only included 2 lambdas as an example
Lambda application template
{
"AWSTemplateFormatVersion": "2010-09-09",
"Resources": {
"Lambda1": {
"Type": "AWS::Lambda::Function",
"Properties": {
"Code": {
"S3Bucket": {
"Ref": "lambda1SourceBucketNameParameter3EE73025"
},
"S3Key": {
"Ref": "lambda1SourceObjectKeyParameter326E8288"
}
}
}
},
"Lambda2": {
"Type": "AWS::Lambda::Function",
"Properties": {
"Code": {
"S3Bucket": {
"Ref": "lambda2SourceBucketNameParameter3EE73025"
},
"S3Key": {
"Ref": "lambda2SourceObjectKeyParameter326E8288"
}
}
}
}
},
"Parameters": {
"lambda1SourceBucketNameParameter3EE73025": {
"Type": "String"
},
"lambda1SourceObjectKeyParameter326E8288": {
"Type": "String"
},
"lambda2SourceBucketNameParameterA0D2319B": {
"Type": "String"
},
"lambda2SourceObjectKeyParameterF3B3F2C2": {
"Type": "String"
}
}
}
Code Pipeline template:
{
"Resources": {
"Pipeline40CE5EDC": {
"Type": "AWS::CodePipeline::Pipeline",
"Properties": {
"Stages": [
{
"Actions": [
{
"ActionTypeId": {
"Provider": "CodeBuild"
},
"Name": "CDK_Build",
"OutputArtifacts": [
{
"Name": "CdkbuildOutput"
}
],
"RunOrder": 1
},
{
"ActionTypeId": {
"Provider": "CodeBuild"
},
"Name": "Lambda_Build",
"OutputArtifacts": [
{ "Name": "CompiledLambdaCode1" },
{ "Name": "CompiledLambdaCode2" }
],
"RunOrder": 1
}
],
"Name": "Build"
},
{
"Actions": [
{
"ActionTypeId": {
"Provider": "CloudFormation"
},
"Configuration": {
"StackName": "DeployLambdas",
"ParameterOverrides": "{\"lambda2SourceBucketNameParameterA0D2319B\":{\"Fn::GetArtifactAtt\":[\"CompiledLambdaCode1\",\"BucketName\"]},\"lambda2SourceObjectKeyParameterF3B3F2C2\":{\"Fn::GetArtifactAtt\":[\"CompiledLambdaCode1\",\"ObjectKey\"]},\"lambda1SourceBucketNameParameter3EE73025\":{\"Fn::GetArtifactAtt\":[\"CompiledLambdaCode2\",\"BucketName\"]},\"lambda1SourceObjectKeyParameter326E8288\":{\"Fn::GetArtifactAtt\":[\"CompiledLambdaCode2\",\"ObjectKey\"]}}",
"ActionMode": "CREATE_UPDATE",
"TemplatePath": "CdkbuildOutput::CFTemplate.template.json"
},
"InputArtifacts": [
{ "Name": "CompiledLambdaCode1" },
{ "Name": "CompiledLambdaCode2" },
{ "Name": "CdkbuildOutput" }
],
"Name": "Deploy",
"RunOrder": 1
}
],
"Name": "Deploy"
}
],
"ArtifactStore": {
"EncryptionKey": "the key",
"Location": "the bucket",
"Type": "S3"
},
"Name": "Pipeline"
}
}
}
}
Reviewed templates.
So, I don't see five inputs to a CodeBuild action, but I do see 2 inputs to a CloudFormation action (Deploy).
I assume your problem was a perceived limit of 5 input to the CloudFormation action. Is that assumption correct?
The limits for a CloudFormation action are actually 10. See "Action Type Constraints for Artifacts
" # https://docs.aws.amazon.com/codepipeline/latest/userguide/reference-pipeline-structure.html#reference-action-artifacts
So if you can use up to 10, will that suffice?
If not, I have other ideas that would take a lot longer to document.

Alexa smart home skill development: Device discovery not working

I am currently developing a smart home skill for my blinds, however I am unable to discover device. Is there a way for me to validate my Discovery response message? I'm thinking this is some logical error in the JSON.
I'm using a Lambda function to perform the requests to my API using node-fetch and async/await, thus I have tagged all JS function as async, this could be another potential cause of this issue. I don't get any errors in CloudWatch either.
This is the response my Lambda function is sending:
{
"event": {
"header": {
"namespace": "Alexa.Discovery",
"name": "Discover.Response",
"payloadVersion": "3",
"messageId": "0a58ace0-e6ab-47de-b6af-b600b5ab8a7a"
},
"payload": {
"endpoints": [
{
"endpointId": "com-tobisoft-rollos-1",
"manufacturerName": "tobisoft",
"description": "Office Blinds",
"friendlyName": "Office Blinds",
"displayCategories": [
"INTERIOR_BLIND"
],
"capabilities": [
{
"type": "AlexaInterface",
"interface": "Alexa.RangeController",
"instance": "Blind.Lift",
"version": "3",
"properties": {
"supported": [
{
"name": "rangeValue"
}
],
"proactivelyReported": true,
"retrievable": true
},
"capabilityResources": {
"friendlyNames": [
{
"#type": "asset",
"value": {
"assetId": "Alexa.Setting.Opening"
}
}
]
},
"configuration": {
"supportedRange": {
"minimumValue": 0,
"maximumValue": 100,
"precision": 1
},
"unitOfMeasure": "Alexa.Unit.Percent"
},
"semantics": {
"actionMappings": [
{
"#type": "ActionsToDirective",
"actions": [
"Alexa.Actions.Close"
],
"directive": {
"name": "SetRangeValue",
"payload": {
"rangeValue": 100
}
}
},
{
"#type": "ActionsToDirective",
"actions": [
"Alexa.Actions.Open"
],
"directive": {
"name": "SetRangeValue",
"payload": {
"rangeValue": 1
}
}
},
{
"#type": "ActionsToDirective",
"actions": [
"Alexa.Actions.Lower"
],
"directive": {
"name": "AdjustRangeValue",
"payload": {
"rangeValueDelta": 10,
"rangeValueDeltaDefault": false
}
}
},
{
"#type": "ActionsToDirective",
"actions": [
"Alexa.Actions.Raise"
],
"directive": {
"name": "AdjustRangeValue",
"payload": {
"rangeValueDelta": -10,
"rangeValueDeltaDefault": false
}
}
}
],
"stateMappings": [
{
"#type": "StatesToValue",
"states": [
"Alexa.States.Closed"
],
"value": 100
},
{
"#type": "StatesToRange",
"states": [
"Alexa.States.Open"
],
"range": {
"value": 0
}
}
]
}
},
{
"type": "AlexaInterface",
"interface": "Alexa",
"version": "3"
}
]
}
]
}
}
}
Thanks for any help.
Is there a way for me to validate my Discovery response message?
Yes, you could use the Alexa Smart Home Message JSON Schema. This schema can be used for message validation during skill development, it validates Smart Home skills (except the Video Skills API).
This is the response my Lambda function is sending
I've validated your response following this steps, the result: no errors found, the JSON validates against the schema. So, there's probably another thing going on. I suggest getting in touch with Alexa Developer Contact Us

Calling Webjob from Azure Data Factory pipeline throwing HTTP 409 conflict exception error

I have a OnDemand triggered webjob that I want to trigger through ADF copy activity using HTTP linked service. Here is the linked service:-
{
"name": "LS_WebJob",
"properties": {
"hubName": "yas-cdp-adf_hub",
"type": "Http",
"typeProperties": {
"url": "https://cust-app.scm.azurewebsites.net/api/triggeredwebjobs/ConsoleApplication1/run",
"authenticationType": "Basic",
"username": "$custdata-app",
"password": "**********"
}
}
}
Input Dataset
{
"name": "ZZ_Inp_Webjob",
"properties": {
"published": false,
"type": "Http",
"linkedServiceName": "LS_WebJob",
"typeProperties": {
"requestMethod": "Post",
"requestBody": "Hey Buddy"
},
"availability": {
"frequency": "Day",
"interval": 1,
"style": "StartOfInterval"
},
"external": true,
"policy": {}
}
}
Output Dataset
{
"name": "ZZ_Out_WebJob",
"properties": {
"published": false,
"type": "AzureBlob",
"linkedServiceName": "LS_ABLB",
"typeProperties": {
"fileName": "webjob.json",
"folderPath": "yc-cdp-container/Dummy/temp",
"format": {
"type": "TextFormat"
}
},
"availability": {
"frequency": "Day",
"interval": 1,
"style": "StartOfInterval"
}
}
}
Pipeline
{
"name": "ZZ-PL-WebJob",
"properties": {
"description": "This pipeline copies data from an HTTP Marina WiFi Source URL to Azure blob",
"activities": [
{
"type": "Copy",
"typeProperties": {
"source": {
"type": "HttpSource"
},
"sink": {
"type": "BlobSink",
"writeBatchSize": 0,
"writeBatchTimeout": "00:00:00"
}
},
"inputs": [
{
"name": "ZZ_Inp_Webjob"
}
],
"outputs": [
{
"name": "ZZ_Out_Webjob"
}
],
"policy": {
"timeout": "01:00:00",
"concurrency": 1
},
"scheduler": {
"frequency": "Day",
"interval": 1,
"style": "StartOfInterval"
},
"name": "WebjobSourceToAzureBlob",
"description": "Copy from an HTTP source to an Azure blob"
}
],
"start": "2017-04-10T01:00:00Z",
"end": "2017-04-10T01:00:00Z",
"isPaused": false,
"hubName": "yas-cdp-adf_hub",
"pipelineMode": "Scheduled"
}
}
My webjob is a simple C# application:-
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("My Team Rocks!");
}
}
}
When I am executing the pipeline, the webjob is being successfully triggered. However the pipeline fails with HTTP 409 conflict error.
Copy activity encountered a user error at Source side:
ErrorCode=UserErrorFailedToReadHttpFile,'Type=Microsoft.DataTransfer.Common.Shared.HybridDeliveryException,Message=Failed
to read data from http source
file.,Source=Microsoft.DataTransfer.ClientLibrary,''Type=System.Net.WebException,Message=The
remote server returned an error: (409) Conflict.,Source=System,'.
Try adding in the gateway name to the linked service json. Refer to this link How to integrate a WebJob within an Azure Data Factory Pipeline .

AWS API Gateway - HTTP Passthrough Path Parameters

I'm trying out the HTTP passthrough functionality in API gateway, passing through a resource method to another API. I want to pass through the path parameters from the API gateway URL to the backend API that also needs those path parameters.
I have the following simple Swagger document trying to test this out:
{
"swagger": "2.0",
"info": {
"version": "2017-09-15T03:33:48Z",
"title": "api-gateway-http-test"
},
"schemes": [
"https"
],
"paths": {
"/subresource/{name}": {
"get": {
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "200 response",
"schema": {
"$ref": "#/definitions/Empty"
}
}
},
"x-amazon-apigateway-integration": {
"uri": "http://my.web.service.url/subresource/{name}",
"passthroughBehavior": "when_no_match",
"httpMethod": "GET",
"type": "http_proxy",
"requestParameters": {
"integration.request.path.name": "method.request.path.name"
}
}
}
}
},
"definitions": {
"Empty": {
"type": "object",
"title": "Empty Schema"
}
}
}
When I try deploying this to API Gateway via CloudFormation, API Gateway gives me this error:
Unable to put integration on 'GET' for resource at path '/subresource/{name}':
Invalid mapping expression specified:
Validation Result:
warnings : [], errors : [Invalid mapping expression parameter specified: method.request.path.name]
I've looked at various sources online, and this way of configuring the "requestParameters" section seems to be the recommended way to pass through path parameters to the backend API.
What am I missing here that would cause this to not work?
It is missing parameter definitions.
Check it out with the below,
{
"swagger": "2.0",
"info": {
"version": "2017-09-15T03:33:48Z",
"title": "api-gateway-http-test"
},
"schemes": [
"https"
],
"paths": {
"/subresource/{name}": {
"get": {
"produces": [
"application/json"
],
"parameters": [
{
"name": "name",
"in": "path",
"required": true,
"type": "string"
}
],
"responses": {
"200": {
"description": "200 response",
"schema": {
"$ref": "#/definitions/Empty"
}
}
},
"x-amazon-apigateway-integration": {
"uri": "http://google.com/subresource/{name}",
"passthroughBehavior": "when_no_match",
"httpMethod": "GET",
"type": "http_proxy",
"requestParameters": {
"integration.request.path.name": "method.request.path.name"
}
}
}
}
},
"definitions": {
"Empty": {
"type": "object",
"title": "Empty Schema"
}
}
}

Unable to execute Lambda in Async mode via API Gateway POST request

Why currently there no way to execute AWS Lambda in asynchronous mode via Gateway API without involving intermediary Lambda just for calling invoke() method?
Even if i add integration like this:
r = client.put_integration(
restApiId=rest_api_id,
resourceId=resource_id,
httpMethod='POST',
type='AWS',
integrationHttpMethod='POST',
uri=uri,
requestParameters={
'integration.request.header.X-Amz-Invocation-Type': "'Event'",
'integration.request.header.Invocation-Type': "'Event'"
}
)
It still executed synchronously...
Are there some platform limitation or so?
I have an example Swagger document which you can switch invocation type to Lambda function. I guess you already got how to map the header to trigger the different invocation types, but I think you might forget to deploy the API.
Swagger
{
"swagger": "2.0",
"info": {
"version": "2016-02-11T22:00:31Z",
"title": "LambdaAsync"
},
"host": "<placeholder>",
"basePath": "<placeholder>",
"schemes": [
"https"
],
"paths": {
"/": {
"get": {
"produces": [
"application/json"
],
"parameters": [
{
"name": "X-Amz-Invocation-Type",
"in": "header",
"required": false,
"type": "string"
}
],
"responses": {
"200": {
"description": "200 response",
"schema": {
"$ref": "#/definitions/Empty"
}
}
},
"x-amazon-apigateway-integration": {
"passthroughBehavior": "when_no_match",
"httpMethod": "POST",
"uri": "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:<account>:function:<function_name>/invocations?Qualifier=$LATEST",
"responses": {
"default": {
"statusCode": "200"
}
},
"requestParameters": {
"integration.request.header.X-Amz-Invocation-Type": "method.request.header.X-Amz-Invocation-Type"
},
"type": "aws"
}
}
}
},
"definitions": {
"Empty": {
"type": "object",
"title": "Empty Schema"
}
}
}