Alexa Skill SDK : Requested skill's response error - amazon-web-services

I have followed a tutorial to get this working.
My Alexa skill is built with invocation, intents and utterances set up.
My Lambda function is set up.
My endpoints default region is:
arn:aws:lambda:us-east-1:(myID found in AWS Support Center ):function:myLearn
myLearn function in Lambda is set with Alexa Skills Kit which has my correct Skill ID copied from the skill.
My HelloIntent doesn't have a slot. I'm just trying to get a response from the invocation.
My code running node.js 6.10 with a handler called index.handler follows as this:
var Alexa = require("alexa-sdk");
var handlers = {
"HelloIntent": function () {
this.response.speak("Hello, It's Me.");
this.emit(':responseReady');
},
"LaunchRequest": function () {
this.response.speak("Welcome to my thing I got going on.");
this.emit(':responseReady');
}
};
exports.handler = function(event, context, callback){
var alexa = Alexa.handler(event, context);
alexa.registerHandlers(handlers);
alexa.execute();
};
I've read that there are issues with zips but I didn't upload anything - I just changed the default index.js file...and my handler isn't named anything different - it's index.handler.
When I run the test in the alexa console I get the ol:
"There was a problem with the requested skill's response"
My json output is null.
And when I go to my logs in Cloud Watch:
Unable to import module 'index': Error at Function.Module._resolveFilename
I did a search for this and many of the errors were how users uploaded the zips and there was a conflict with the handler name and js file.

It looks like you might have created the Lambda function from the AWS Console and not included the alexa-sdk. To fix this you can start by using one of the provided 'Alexa blueprints' that include the alexa-sdk then overwrite the code in the Lambda with your code. Or you can package your code in a .zip file that includes the alexa-sdk module and upload the package through the web console. Here is a video I did a while back that explains the issue https://youtu.be/cFzAIhsldbs - I'm pretty sure that's your problem. I hope this helps.

You can try using "speechOutput" variable to store your response and then use the emit function.

Related

Lex: The server encountered an error processing lambda

I'm developing a chatbot on AWS Lex and I want to use Lambda function to branch my intent.
In order to do so, I created a Lambda as follows:
exports.handler = async (event) => {
console.log(event); //capture Lex params
/*
let { name, slots } = event.currentIntent
if(slots.MeetingType.toLowerCase() === 'on-line') {
return {
dialogAction: {
type: "ElicitSlot",
intentName: name,
slotToElicit: "InvitationLink",
slots
}
}
}
return {
dialogAction: {
type: "Delegate",
slots
}
}
*/
};
But as you can see, even when the function does nothing but log Lex output, I'm getting this error message in Lex:
An error has occurred: The server encountered an error processing the
Lambda response
Any help would be appreciated.
Because you are trying to build a Lex chatbot using JavaScript, please refer to this use case in the AWS SDK for JavaScript DEV Guide. It will walk you through this use case:
Building an Amazon Lex chatbot
Once you get this working, you can port the logic to a Lambda function.
Amazon Lex is giving you this error message because the Lambda function has failed during execution.
Enable CloudWatch logging for your Lambda function and check the logs after Lex has called it. The logs should provide you with more specific details about what's caused the code to break/fail. From there you should have a better idea of how to resolve the issue.
Feel free to post the output from the logs if you need more assistance with debugging the issue.

GCP cloud build VIEW RAW logs link

I have written a small cloud function in GCP which is subscribed to Pub/Sub event. When any cloud builds triggered function post message into the slack channel over webook.
In response, we get lots of details to trigger name, branch name, variables details but i am more interested in Build logs URL.
Currently getting build logs URL in response is like : logUrl: https://console.cloud.google.com/cloud-build/builds/899-08sdf-4412b-e3-bd52872?project=125205252525252
which requires GCP console access to check logs.
While in the console there an option View Raw. Is it possible to get that direct URL in the event response? so that i can directly sent it to slack and anyone can access direct logs without having GCP console access.
In your Cloud Build event message, you need to extract 2 values from the JSON message:
logsBucket
id
The raw file is stored here
<logsBucket>/log-<id>.txt
So, you can get it easily in your function with Cloud Storage client library (preferred solution) or with a simple HTTP Get call to the storage API.
If you need more guidance, let me know your dev language, I will send you a piece of code.
as #guillaume blaquiere helped.
Just sharing the piece of code used in cloud function to generate the singedURL of cloud build logs.
var filename ='log-' + build.id + '.txt';
var file = gcs.bucket(BUCKET_NAME).file(filename);
const getURL = async () => {
return new Promise((resolve, reject) => {
file.getSignedUrl({
action: 'read',
expires: Date.now() + 76000000
}, (err, url) => {
if (err) {
console.error(err);
reject(err);
}
console.log("URL");
resolve(url);
});
})
}
const singedUrl = await getURL();
if anyone looking for the whole code please follow this link : https://github.com/harsh4870/Cloud-build-slack-notification/blob/master/singedURL.js

AWS IoT - Failed to invoke lambda function

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.

Api Gateway: AWS Subdomain for Lambda Integration

I'm attempting to integrate my lambda function, which must run async because it takes too long, with API gateway. I believe I must, instead of choosing the "Lambda" integration type, choose "AWS Service" and specify Lambda. (e.g. this and this seem to imply that.)
However, I get the message "AWS ARN for integration must contain path or action" when I attempt to set the AWS Subdomain to the ARN of my Lambda function. If I set the subdomain to just the name of my Lambda function, when attempting to deploy I get "AWS ARN for integration contains invalid path".
What is the proper AWS Subdomain for this type of integration?
Note that I could also take the advice of this post and set up a Kinesis stream, but that seems excessive for my simple use case. If that's the proper way to resolve my problem, happy to try that.
Edit: Included screen shot
Edit: Please see comment below for an incomplete resolution.
So it's pretty annoying to set up, but here are two ways:
Set up a regular Lambda integration and then add the InvocationType header described here http://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html. The value should be 'Event'.
This is annoying because the console won't let you add headers when you have a Lambda function as the Integration type. You'll have to use the SDK or the CLI, or use Swagger where you can add the header easily.
Set the whole thing up as an AWS integration in the console (this is what you're doing in the question), just so you can set the InvocationType header in the console
Leave subdomain blank
"Use path override" and set it to /2015-03-31/functions/<FunctionARN>/invocations where <FunctionARN> is the full ARN of your lambda function
HTTP method is POST
Add a static header X-Amz-Invocation-Type with value 'Event'
http://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html
The other option, which I did, was to still use the Lambda configuration and use two lambdas. The first (code below) runs in under a second and returns immediately. But, what it really does is fire off a second lambda (your primary one) that can be long running (up to the 15 minute limit) as an Event. I found this more straightforward.
/**
* Note: Step Functions, which are called out in many answers online, do NOT actually work in this case. The reason
* being that if you use Sequential or even Parallel steps they both require everything to complete before a response
* is sent. That means that this one will execute quickly but Step Functions will still wait on the other one to
* complete, thus defeating the purpose.
*
* #param {Object} event The Event from Lambda
*/
exports.handler = async (event) => {
let params = {
FunctionName: "<YOUR FUNCTION NAME OR ARN>",
InvocationType: "Event", // <--- This is KEY as it tells Lambda to start execution but immediately return / not wait.
Payload: JSON.stringify( event )
};
// we have to wait for it to at least be submitted. Otherwise Lambda runs too fast and will return before
// the Lambda can be submitted to the backend queue for execution
await new Promise((resolve, reject) => {
Lambda.invoke(params, function(err, data) {
if (err) {
reject(err, err.stack);
}
else {
resolve('Lambda invoked: '+data) ;
}
});
});
// Always return 200 not matter what
return {
statusCode : 200,
body: "Event Handled"
};
};

Lambda function not working upon Alexa Skill invocation

I've just created my first (custom) still. I've set the function up in Lambda by uploading a zip file containing my index.js and all the necessary code required, including node_modules and the base Alexa skill that mine is a child of (as per the tutorials). I made sure I zipped up the files and sub-folders, not the folder itself (as I can see this is a common cause of similar errors) but when I create the skill and test in the web harness with a sample utterance I get:
remote endpoint could not be called, or the response it returned was
invalid.
I'm not sure how to debug this as there's nothing logged in CloudWatch.
I can see in the Lambda request that my slot value is translated/parsed successfully and the intentname is correct.
In AWS Lambda I can invoke the function successfully both with a LaunchRequest and another named intent. From the developer console though, I get nothing.
I've tried copying the JSON from the lambda test (that works) to the developer portal and I get the same error. Here is a sample of the JSON I'm putting in the dev portal (that works in Lambda)
{
"session": {
"new": true,
"sessionId": "session1234",
"attributes": {},
"user": {
"userId": null
},
"application": {
"applicationId": "amzn1.echo-sdk-ams.app.149e75a3-9a64-4224-8bcq-30666e8fd464"
}
},
"version": "1.0",
"request": {
"type": "LaunchRequest",
"requestId": "request5678"
}
}
The first step in pursuing this problem is probably to test your lambda separate from your skill configuration.
When looking at your lambda function in the AWS console, note the 'test' button at the top, and next to it there is a drop down with an option to configure a test event. If you select that option you will find that there are preset test events for Alexa. Choose 'alexa start session' and then choose 'save and test' button.
This will give you more detailed feedback about the execution of your lambda.
If your lambda works fine here then the problem probably lies in your skill configuration, so I would go back through whatever tutorial and documentation you were using to configuration your skill and make sure you did it right.
When you write that the lambda request looks fine I assume you are talking about the service simulator, so that's a good start, but there could still be a problem on the configuration tab.
We built a tool for local skill development and testing.
BST Tools
Requests and responses from Alexa will be sent directly to your local server, so that you can quickly code and debug without having to do any deployments. I have found this to be very useful for our own development.
Let me know if you have any questions.
It's open source: https://github.com/bespoken/bst