How do I post a test Kinesis event from Postman to a local Lambda function running on serverless? - aws-lambda

Sorry, wasn't sure how to make the question itself brief enough...
I can post data from Postman to my local Lambda function. The issue is that when running locally, I have use this line of code...
event = JSON.parse(event.body);
...so that I can do this...
event.Records.forEach(function(record)
{
// do some stuff
}
But when I deploy the function to AWS, parsing event.body is unnecessary. In fact it throws an error.
I was assuming that there is something different about the JSON (or other aspects of the request) that I'm posting from Postman to my local app when compared to what Kinesis actually sends. But the JSON blob I'm posting locally was logged directly from Lambda on AWS to Cloudwatch.
I'm missing something.
TBH, this only matters because having to comment out that line as a step in the deployment process is annoying and error-prone.
Here's the JSON (names have been changed to protect the innocent):
{
"Records": [
{
"kinesis": {
"kinesisSchemaVersion": "1.0",
"partitionKey": "Thursday, 11 April 2019",
"sequenceNumber": "49594660145138471912435706107712688932829223550684495922",
"data": "some base 64 stuff",
"approximateArrivalTimestamp": 1555045874.83
},
"eventSource": "aws:kinesis",
"eventVersion": "1.0",
"eventID": "shardId-000000000003:1234123412341234123412341234123412341234123412341234",
"eventName": "aws:kinesis:record",
"invokeIdentityArn": "arn:aws:iam::1234123412341234:role/lambda-kinesis-role",
"awsRegion": "us-west-2",
"eventSourceARN": "arn:aws:kinesis:us-west-2:1234123412341234:stream/front-end-requests"
}
]
}

Related

What comes with the AWS Lambda event and context

I've got AWS Lambda written in Ruby 2.7 and the Lambda is setup based on templates.yml. Since I'm not able to use debugger on AWS Lambda which is run locally (AWS SAM gives me an error: Ruby 2.7 is not supported at the moment - docs) I also can't check what's coming inside Event and Context.
My lambda uses the Gateway API, and I'm wondering what I should do to pull the entire payload (I assume it's in the body of the request) from the request that comes in at POST /quizzes, which looks like the following:
{
"quiz":
{
"first_name": "john",
"last_name": "doe",
"ssn": "1234",
"address":
{
"line1": "4444 NW ANYSTREET AVE",
"city": "anytown",
"state": "FL",
"zip_code": "33333"
},
"dob":
{
"day": 25,
"month": 12,
"year": 2000
}
}
}
From the entire Lambda Event I want to fetch and pass only the body that is attached to the request. In other words, what does the event look like with this type of request body?
If you want to know what an event in lambda looks like, you can use AWS SAM to generate the body of a fake event using the sam local generate-event command.

how can I compose a bot to iterate trough a xml json object?

I am using the composer to publish a bot to fetch data from an azure storage table.
In short, the bot composer needs to construct a bot to iterate through an XML deserialized JSON object returned by the azure storage rest API.
In my code generated by the composer, the bot does a "set property" step immediately following the successful return of the REST API (storage table query). Given the deserialized object returned by the storage REST API, how should the "set property" statement be constructed so the bot can print our the individual data field,
Another way to phrase the question: how can I use the composer to construct the bot to iterate through a returned deserialized object (coded in XML JSON format)?
Where can I find a document that can shed some light on this matter?
Is there any place I can find a good example? Can it be done via composer?
Thanks in advance.
Yes, it can be done. If the API returns XML, make sure you configure your api call to ask for content type application/xml.
Then you can use use the xPath built in function. Make note that it will return an array if results in more than value matches the expression, in which you can use the foreach function to iterate over it with. I needed to run the nightly build of Composer (with bot-builder 4.12.0) to get it to work for me. See here for some more info:
https://github.com/microsoft/botbuilder-js/pull/3093
Here's an example that worked for me:
"actions": [
{
"$kind": "Microsoft.SendActivity",
"$designer": {
"id": "rGv7XC"
},
"activity": "${SendActivity_rGv7XC()}"
},
{
"$kind": "Microsoft.HttpRequest",
"$designer": {
"id": "TDA1wO"
},
"method": "GET",
"url": "http://www.geoplugin.net/xml.gp?ip=157.54.54.128",
"resultProperty": "dialog.api_response",
"contentType": "application/xml"
},
{
"$kind": "Microsoft.SetProperty",
"$designer": {
"id": "ipNhfY"
},
"property": "dialog.timezone",
"value": "=xPath(dialog.api_response.content,'/geoPlugin/geoplugin_timezone/text()')"
},
{
"$kind": "Microsoft.SendActivity",
"$designer": {
"id": "DxohEx"
},
"activity": "${SendActivity_DxohEx()}"
}
]
You can (if needed/you wish) use the json and jPath built in functions to convert xml to json and then query with. Something like:
${json(user.testXml)} and then
${jPath(user.testJson , "automobiles")}

CORS error with AWS api gateway and java lambda function

Today I created one api gateway on aws and one java lambda function. Then finally integrated api gateway with lambda function.
So when I hit the api using postman then it returns the result which is basically a list of customer. Till now everything looks fine. Following is the
#Override
public TestResponse handleRequest(Request input, Context context) {
TestService testService = SingletonServiceManager.getInstance().getTestService();
TestListResponse response = (TestListResponse)productListService.executeRequest(input);
return response;
}
After executing it returns following output.
{
"status": 200,
"products": [
{
"name": "test1",
"code": "test1",
"status": true
},
{
"name": "test2",
"code": "test2",
"status": true
}
]
}
but when I started integrating this with api call with Angular from local machine it start throwing CORS issue. Angular client using it CORS setting to connect.
Can someone help me on this. Do I need to enable something special from lambda function.
You need to enable CORS in your API Gateway configuration.

Bot framework direct line using POST with JSON data

I now use bot framework with Azure functions.
it now works when the user sends his message its writes it to queue storage then picked up by Azure function and sends it back to the bot with direct line build in Azure function connector.
I want to change the functionality to LogicAppp and return the answer to the user with direct-line with http rest.
I have a key and have a json input that the function got like this:
{
"relatesTo": {
"user": {
"id": "default-user",
"name": "User"
},
"bot": {
"id": "b5023440-b1ce-11e8-9ad8-f5b615a4c6c3",
"name": "Bot"
},
"conversation": {
"id": "33cd0410-bf46-11e8-a228-a5c7cd21a798|livechat"
},
"channelId": "emulator",
"serviceUrl": "https://0a87dff1.ngrok.io"
},
"text": "example",
"isTrustedServiceUrl": true
}
I try to answer the chat using
https://directline.botframework.com/v3/directline/conversations/{conversationId}/activitie
I can't make it work, the conversation id looks different, it's like a guid instead of an id.
how can help me with the right POST syntax from the json provided?

Amazon Alexa Device Discovery for Smart Home API with Lambda Failing

I have setup an Alexa Smart Home Skill, all settings done, oauth2 processed done and skill is enabled on my Amazon Echo device. Lambda function is setup and linked to the skill. When I "Discover Devices" I can see the payload hit my Lambda function in the log. I am literally returning via the context.succeed() method the following JSON with a test appliance. However Echo tells me that it fails to find any devices.
{
"header": {
"messageId": "42e0bf9c-18e2-424f-bb11-f8a12df1a79e",
"name": "DiscoverAppliancesResponse",
"namespace": "Alexa.ConnectedHome.Discovery",
"payloadVersion": "2"
},
"payload": {
"discoveredAppliances": [
{
"actions": [
"incrementPercentage",
"decrementPercentage",
"setPercentage",
"turnOn",
"turnOff"
],
"applianceId": "0d6884ab-030e-8ff4-ffffaa15c06e0453",
"friendlyDescription": "Study Light connected to Loxone Kit",
"friendlyName": "Study Light",
"isReachable": true,
"manufacturerName": "Loxone",
"modelName": "Spot"
}
]
}
}
Does the above payload look correct?
According to https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/smart-home-skill-api-reference#discovery-messages the version attribute is required. Your response seems to be missing that attribute.
In my (very short) experience with this, even the smallest mistake in the response would generate a silent error like the one you are experiencing.
I had the same problem. If you are creating discovery for "Entertainment Device", make sure you have wrapped the output in 'event' key for context.succeed
var payload = {
endpoints:
[
{
"endpointId": "My-id",
"manufacturerName": "Manufacturer",
"friendlyName": "Living room TV",
"description": "65in LED TV from Demo AV Company",
"displayCategories": [ ],
"cookie": {
"data": "e.g. ip address",
},
"capabilities":
[
{
"interface": "Alexa.Speaker",
"version": "1.0",
"type": "AlexaInterface"
},
]
}
]
};
var header = request.directive.header;
header.name = "Discover.Response";
context.succeed({ event: {
header: header, payload: payload
} });
Although, in the sample code, this is never mentioned and an incorrect example is given (https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/steps-to-create-a-smart-home-skill). However, the response body provided includes the "event" key.
Recreating lambda function helped me fix the issue. I also set "Enable trigger" check button while creating, though I'm not sure if that matters. After that my device provided by skill was found successfully.
Edit: Answer was wrong. Only useful information was this
This context.fail syntax is actually deprecated. Look up the Lambda context object properties, it should look more like "callback(null, resultObj)" now.
Did you include the return statement in your function?
return {
"header": header,
"payload": payload
}
It was missing in the example and after adding it, I was able to 'discover' my device.

Resources