Reference one task from another in a contact flow - amazon-web-services

I'm building a contact flow which creates a block of tasks in pairs. Ideally, one task in a pair should include a reference to its partner in its description.
I've almost achieved this: When creating the second task, I add a reference type URL and I'm using the $.Task.ContactId attribute, prefixed with the access URL for my instance, i.e.
https://<myurl>.my.connect.aws/connect/contact-trace-records/details/$.Task.ContactID
I'd like to deploy this in more than one Connect instance without having to keep manually editing the contact flow. Is there any way I can specify the access URL as a parameter?

For dynamic attributes like this, you need to call a lambda. The lambda can return the appropriate value and then you can use that returned value to set your reference URL attribute.
If I was writing the lambda I'd send through the $.Task.ContactID then use Details.ContactData.InstanceARN from the event that gets passed to the lambda to lookup the instance alias via the Connect API DescribeInstance function. You can then build the url in the lambda and send it back.
More info about using lambdas in a contact flow can be found here

Related

Can I create temporary users through Amazon Cognito?

Does Amazon Cognito support temporary users? For my use case, I want to be able to give access to external users, but limited to a time period (e.g. 7 days)
Currently, my solution is something like:
Create User in User Group
Schedule cron job to run in x days
Job will disable/remove User from User Group
This all seems to be quite manual and I was hoping Cognito provides something similar automatically.
Unfortunately there is no functionality used to automate this workflow so you would need to devise your own solution.
I would suggest the below approach to handling this:
Create a Lambda function that is able to post process a user sign up. This Lambda function would create a CloudWatch Event with a schedule for 7 days in the future. Using the SDK you would create the event and assign a target of another Lambda function. When you specify the target in the put_targets function use the Input parameter to pass in your own JSON, this should contain a metadata item related to the user.
You would then create a post confirmation Lambda trigger which would trigger the Lambda you created in the above step. This would allow you to schedule an event every time a user signs up.
Finally create the target Lambda for the CloudWatch event, this will access the input passed in from the trigger and can use the AWS SDK to perform any cognito functions you might want to use such as deleting the user.
The benefit to using these services rather a cron, is that you can perform the most optimal processing only when it is required. If you have many users in this temporary group you would need to loop through every user and compare if its ready to be removed for a one time script (and perhaps sometimes never remove users).
My solution for this is the following: Instead of creating a post confirmation lambda trigger you can also create a pre authentication lambda trigger. This trigger will check for the user attribute "valid_until" which contains a unix timestamp. The pre authentication lambda trigger will only let the user in if the value of the "valid_until" attribute is in the future. Main benefit of this solution is that you don't need any cron-jobs.

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

Consuming RSS feed with AWS Lambda and API Gateway

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

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"]

Can I parameterize AWS lambda functions differently for staging and release resources?

I have a Lambda function invoked by S3 put events, which in turn needs to process the objects and write to a database on RDS. I want to test things out in my staging stack, which means I have a separate bucket, different database endpoint on RDS, and separate IAM roles.
I know how to configure the lambda function's event source and IAM stuff manually (in the Console), and I've read about lambda aliases and versions, but I don't see any support for providing operational parameters (like the name of the destination database) on a per-alias basis. So when I make a change to the function, right now it looks like I need a separate copy of the function for staging and production, and I would have to keep them in sync manually. All of the logic in the code would be the same, and while I get the source bucket and key as a parameter to the function when it's invoked, I don't currently have a way to pass in the destination stuff.
For the destination DB information, I could have a switch statement in the function body that checks the originating S3 bucket and makes a decision, but I hate making every function have to keep that mapping internally. That wouldn't work for the DB credentials or IAM policies, though.
I suppose I could automate all or most of this with the SDK. Has anyone set something like this up for a continuous integration-style deployment with Lambda, or is there a simpler way to do it that I've missed?
I found a workaround using Lambda function aliases. Given the context object, I can get the invoked_function_arn property, which has the alias (if any) at the end.
arn_string = context.invoked_function_arn
alias = arn_string.split(':')[-1]
Then I just use the alias as an index into a dict in my config.py module, and I'm good to go.
config[alias].host
config[alias].database
One thing I'm not crazy about is that I have to invoke my function from an alias every time, and now I can't use aliases for any other purpose without affecting this scheme. It would be nice to have explicit support for user parameters in the context object.