Consuming RSS feed with AWS Lambda and API Gateway - amazon-web-services

I'm a newbie rails programmer, and I have even less experience with all the AWS products. I'm trying to use lambda to subscribe to and consume an rss feed from youtube. I am able to send the subscription request just fine with HTTParty from my locally hosted rails app:
query = {'hub.mode':'subscribe', 'hub.verify':'sync', 'hub.topic': 'https://www.youtube.com/feeds/videos.xml?channel_id=CHANNELID', 'hub.callback':'API Endpoint for Lambda'}
subscribe = 'HTTParty.post(https://pubsubhubbub.appspot.com/subscribe, :query=>query)
and it will ping the lambda function with a get request. I know that I need to echo back a hub.challenge string, but I don't know how. The lambda event is empty, I didn't see anything useful in the context. I tried formatting the response in the API gateway but that didn't work either. So right now when I try to subscribe I get back a 'Challenge Mismatch' error.
I know this: https://pubsubhubbub.googlecode.come/git/pubsubhubbub-core-0.3.html#subscribing explains what I'm trying to do better than what I just did, and section 6.2.1 is where the breakdown is. How do I set up either the AWS Lambda function and/or the API Gateway to reflect back the 'hub.challenge' verification token string?

You need to use the parameter mapping functionality of API Gateway to map the parameters from the incoming query string to a parameter passed to your Lambda function. From the documentation link you provided, it looks like you'll at least need to map the hub.challenge query string parameter, but you may also need the other parameters (hub.mode, hub.topic, and hub.verify_token) depending on what validation logic (if any) that you're implementing.
The first step is to declare your query string parameters in the method request page. Once you have declared the parameters open the integration request page (where you specify which Lambda function API Gateway should call) and use the "+" icon to add a new template. In the template you will have to specify a content type (application/json), and then the body you want to send to Lambda. You can read both query string and header parameters using the params() function. In that input mapping field you are creating the event body that is posted to AWS Lambda. For example: { "challenge": "$input.params('hub.challenge')" }
Documentation for mapping query string parameters

Related

API Gateway not passing event to lambda from console?

I'm trying to call a basic lambda from my API Gateway console. The lambda has an input taken in by the event called filterBy.
I created a query string called filterBy however, when I try to invoke the lambda I get the error:
{errorMessage: {'statusCode': 500, 'body': '{"msg": "KeyError(\'filterBy\')"}'}}
Presumably because the piece of code in my lambda
event['filterBy'] is not finding a filterBy in the event. What do I need to do so that I can get the filterBy in the event from the API Gateway console? I understand this is probably quite simple but I surprisingly cannot find anything about this so any help would be appreciated.
Based on the integration type, approach can be vary.
1. Lambda custom integrations:
Looks like you are trying to use Lambda custom integrations. If that is the case you have to add a mapping template as below.
(under the Integration Request -> Mapping Templates --> Add mapping template)
{
"filterBy": "$input.params('filterBy')"
}
Please refer this article or this video for more info.
2. Lambda proxy integrations:
If you are using Lambada proxy integration (either as REST API or as HTTP APIs), then instead of event['filterBy'], you have to access the queryStringParameters first and then access the relevant query param.
event['queryStringParameters']['filterBy']
And another thing is: once you modify something in API GW, please make sure to deploy and wait some time before test. :)

Get all items in DynamoDB with API Gateway's Mapping Template

Is there a simple way to retrieve all items from a DynamoDB table using a mapping template in an API Gateway endpoint? I usually use a lambda to process the data before returning it but this is such a simple task that a Lambda seems like an overkill.
I have a table that contains data with the following format:
roleAttributeName roleHierarchyLevel roleIsActive roleName
"admin" 99 true "Admin"
"director" 90 true "Director"
"areaManager" 80 false "Area Manager"
I'm happy with getting the data, doesn't matter the representation as I can later transform it further down in my code.
I've been looking around but all tutorials explain how to get specific bits of data through queries and params like roles/{roleAttributeName} but I just want to hit roles/ and get all items.
All you need to do is
create a resource (without curly braces since we dont need a particular item)
create a get method
use Scan instead of Query in Action while configuring the integration request.
Configurations as follows :
enter image description here
now try test...you should get the response.
to try it out on postman deploy the api first and then use the provided link into postman followed by your resource name.
API Gateway allows you to Proxy DynamoDB as a service. Here you have an interesting tutorial on how to do it (you can ignore the part related to index to make it work).
To retrieve all the items from a table, you can use Scan as the action in API Gateway. Keep in mind that DynamoDB limits the query sizes to 1MB either for Scan and Query actions.
You can also limit your own query before it is automatically done by using the Limit parameter.
AWS DynamoDB Scan Reference

Google CDF: Can we set the value of a column as a runtime argument?

I am getting a value returned by hitting a HTTP endpoint which I am storing in a column. Now a want to trigger another Http Endpoint with the value in the column. But the HTTP endpoint takes hardcoded values or macros only. So I want to know if I can set a run-time argrument based on the column value
Please suggest How I can do this.
There are few ways of setting runtime arguments:
Using Argument Setter Plugin - type of Action plugin that allows one to create reusable pipelines by dynamically substituting the configurations that can be served by an HTTP Server.
Specifying runtime arguments as a JSON map in the request body, when starting an program.
CDAP Preferences HTTP RESTful API.
I recommend you check the official documentation for Datafusion, where you can find a way of setting variables/macros using the GCS bucket.
Additionally, have a look at the following thread on SO. It describes the method with specifying runtime arguments as a JSON map in the request body.

How to modify a query parameter in AWS API Gateway in the integration request for an HTTP Proxy

I have a client facing API that takes a query parameter Time. The format is 14:00:00. Originally it would pass through this query parameter to the back end endpoint. However the back end endpoint (that I do not control) is now expecting time in the format 0001-01-01T14:00:00.
Is it possible to to modify the value of the query param before passing it on in AWS API Gateway?
I know you can modify the request body with a mapping template, and in the template you can access the queryParameters, but can you change them so that it modifies the actual request made to the back end?
I saw this:
https://forums.aws.amazon.com/thread.jspa?messageID=696524&#696524
but the user said he gave up trying to modify
Potential workaround I can think of right now are pass the parameters to a lambda and have the lambda build and make the request with modified values, with the response as the return value for the lambda
For now one can overrides query string in Mapping Templates using velocity templates e.g:
$context.requestOverride.querystring.time="_your_transformed_data_"
There is docs
I think you basically answered your own question :)
There is no way to transform query or header request parameters. All transformations need to happen in the body mapping template.
Best workaround would be to forward request on to a Lambda function to massage the parameters into the expected shape

How do I pass GET parameters to my AWS Lambda function when using an HTTP endpoint?

I followed the example from here to set up a sample AWS Lambda function: http://docs.aws.amazon.com/lambda/latest/dg/get-started-step4-optional.html.
Then, I created an HTTP GET endpoint via AWS API Gateway. I can access the endpoint but I don't know how to pass that int myCount as a parameter.
I tried ?myCount=3 as a GET parameter but that didn't work.
Any help?
You need to setup a mapping template in API Gateway. If you know the name of your parameters ahead of time your template could look like this:
{
"myCount": "$input.params('myCount')",
"myUserId": "$input.params('myUserId')"
}
Where each $input.params('...') will get evaluated and the value in your query string will be put in its place when the event is passed to Lambda.
This is pretty much a duplicate of passing query params for aws lambda function
In order to send HTTP parameters to a lambda function, they need to be sent in the request body via a mapping template.
See this blog post for a simple example of how to do this.
This is another way to do it:
Open API Gateway, select your endpoint and click on Resources
Select Method Request in the settings
Under the URL Query String Parameters, you can add query string.
As an example, in my Python lambda function, I can retrieve the query parameter just with the following:
def endpoint(event, context):
my_parameter = event["queryStringParameters"]