How to invoke lambda when lex does not process the intent automatically? - amazon-web-services

My Lex bot has four intents. Suppose a user asks a question at the very beginning of the conversation and this question is not allotted to any of the four intents. Hence no intent will be established. When this happens, I want to call lambda to run an "intent suggestion model" (built using topic modeling) to suggest the user about what the intent of the question might be. Also, lambda will have to store such queries in a database (s3 or RDB) so that if such queries are repetitive, then that intent can eventually be added to the bot and for other analytical solutions.

What you need is a fallback intent but Lex does not support fallback intents as of now.
You can still achieve this if you use a bridge between your chat client and Lex.
Setup an API Gateway and Lambda function in between your chat-client and the Lex.
Your chat-client will send a request to API Gateway, API Gateway will forward this to Lambda function which will be used to call Lex and get response from it. Lex will have one more lambda function as a webhook.
In the Lambda function you used to call Lex, we can check if any intent was matched or we got an error message, if it's an error message and trigger some action like intent suggestion model.
You need to use boto library to call Lex and use post_text() method.
Hope it helps.

Related

AWS Lambda Custom Event Chatbot to Slack Integration

Before I waste to much time on this I was wondering is it technically possible to send from a Lambda a custom event to Event Bridge to SNS to Chatbot to Slack.
I have written all the infrastructure and I know that it works for non custom messages. So if I have a message with a source of aws.lambda in the rule then when I deploy the Lambda I get the eventual Slack notification.
However if I change the source to a custom source in the rule and use that in the code of the Lambda I get from the SDK call success but no Slack message. From turning on the Chatbot logging I get the following message Event received is not supported (see https://docs.aws.amazon.com/chatbot/latest/adminguide/related-services.html )
I am sort of hoping against hope that I am not sending something in on the SDK put events call that this integration although the api call only offers a limited amount of what you can change.
I did notice that the message sent to Slack from a standard event is much bigger that the one sent as a custom event.
Realistically its just looking that the Chatbox Slack integration is an extremely limited one confined to standard events on a subset of services.
Can someone confirm if this is possible or am I right in my conclusion about the limitations of the integration.

Send push notifications/emails when a query/mutation happends in AppSync/Aurora

I am using AppSync with Aurora/RDS.
I would like that in some cases, when a query/mutation is sent to the db, then, after that, I want to send an email and push notification, but this should be detached from the query/mutation, that is, it does not matter if it fails or works.
At the moment I see all these options:
Can you tell me which one I should use?
Create a query that calls a lambda function that sends the
push/email and call it from the client once the actual
query/mutation is done. I don't like this because the logic is in
the client rather than the server. Seems easy to implement, and I
guess it is easy to ignore the result of the second operation from a
client point of view.
A variation of the previous one. Pack both operations in a single
network request. With GraphQL, that is easy, but I don't want the
client waits for the second operation. (Is it possible to create
lambda functions that return immediately, like a trigger of other
functions?)
Attach my queries/mutations to lambda functions instead of RDS
directly. Then, those lambda functions call other lambda functions
for notifications. Seems more difficult to program, but more
micro-services architecture friendly. Probably this is the best one,
not sure.
Use SQL triggers and call lambda functions from those triggers. I
don't know if this is even possible. Researching...
Use pipelines resolvers. The first one is the query/mutation, the
second one is the lambda function that sends the push/email. I would
say this is a bad option because I don't want the client to wait for
the second operation or manage the logic when the second resolver
fails.
Amazon RDS Events: It appears it is possible to attach lambda
functions to specific AWS RDS events.
https://docs.aws.amazon.com/lambda/latest/dg/services-rds.html It
seems it is about creating DBs, restoring... and that kind of
things. I don't see anything like creating a row, updating a row...
So, I discard this unless I am wrong.
Invoking a Lambda Function with an Aurora MySQL Stored Procedure
CALL mysql.lambda_async ( lambda_function_ARN,lambda_function_input )
https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/AuroraMySQL.Integrating.Lambda.html
"For example, you might want to send a notification using Amazon
Simple Notification Service (Amazon SNS) whenever a row is inserted
into a specific table in your database." That is exactly what I am
looking for. I like this idea, but I don't know if that is possible
with Aurora Serverless. Researching... It seems it is not possible
when using server-less:
https://www.reddit.com/r/aws/comments/a9szid/aurora_serverless_call_lambda/
Use step functions: No idea about how to use it.
Somehow, attach this lambda notification function to GraphQL/AppSync
instead of the database, but I guess it is not a good idea because I
need to read the database to the push notification token and the
email of the use who is going to receive the notifications.
Which method do you recommend me? I am using amplify cli.
Thanks a lot.
Currently AWS AppSync can only send notifications when the app is active. We are looking into implementation of the non active case.
If you want to send notifications when the app is not active, you can use the push notifications on iOS: silent push/interactive push or push notifications on Android.
If you want to send emails, voice/text message or notifications on phone when the app is not active, you can integrate with Amazon Pinpiont.

Can event.requestContext.identity.cognitoIdentityId be spoofed?

I'm trying to do ACL by asserting if the item in DynamoDB whose field UserId is really the one logged in which is event.requestContext.identity.cognitoIdentityId.
But, I'm afraid that it can be spoofed just like HTTP headers etc.
My question is, is that safe?
No, this cannot be spoofed in the same way HTTP request headers can. If the request comes in through API Gateway, as a Lambda proxy integration, then there's nothing the browser can do that would allow these values to be overwritten, because this portion of the Lambda event structure is created by API Gateway and not copied from the request. Anything injected into the HTTP request would appear elsewhere in the event structure -- not here. (The HTTP request is in event.input -- which is a sibling object of event.requestContext -- not a parent.)
But then again... yes, this could be spoofed in certain other misconfiguration scenarios -- if, for example, your Lambda function allows itself to be invoked other than by your API Gateway deployment -- then of course the invoker could craft an entire event structure that had nothing to do with any HTTP request and invoke your Lambda function with it. This is perhaps too obvious to mention, since it's implicit from the way you can test a Lambda function from the console, but I mention it for thoroughness. Send a forged test event to your Lambda function using the Lambda console's test function, and naturally the Lambda function processes what you sent it.
So, unsurprisingly, with careless and overly broad permissions, yes, anything is possible... but used as intended behind API Gateway, as a Lambda Proxy Integration, I'd say no.
I have been researching this question for many hours.
I found this post where the author extracts the userId from the Token via:
const userId = await services.getUserIdFromToken(event.headers.Authorization);
This appears to be a safer way to handle setting the userId but all the other examples I have seen use event.requestContext.identity.cognitoIdentityId.

Send a request if Amazon Lambda function is successful or unsuccessful

My Amazon Lambda function (in Python) is called when an object 123456 is created in S3's input_bucket, do a transformation in the object and saves it in output_bucket.
I would like to notify my main application if the request was successful or unsuccessful. For example, a POST http://myapp.com/successful/123456 if the processing is successful and http://myapp.com/unsuccessful/123456 if its not.
One solution I thought is to create a second Amazon Lambda function that is triggered by a put event in output_bucket, and it to do the successful POST request. This solves half of the problem because but I can't trigger the unsuccessful POST request.
Maybe AWS has a more elegant solution using a parameter in Lambda or a service that deals with these types of notifications. Any advice or point in the right direction will be greatly appreciated.
Few possible solutions which I see as elegant
Using SNS Topic: From your transformation lambda, trigger a SNS topic, with success/unsuccess message, where SNS will call a HTTP/HTTPS endpoint with message payload. The advantage here is, your transformation lambda is loosely coupled with endpoint trigger and only connected through messaging.
Using Lambda Step Functions:
You could arrange to run a Lambda function every time a new object is uploaded to an S3 bucket. This function can then kick off a state machine execution by calling StartExecution. The advantage in using step functions is that you can coordinate the components of your application as series of steps in a visual workflow.
I don't think there is any elegant AWS solution, unless you re-architect, something like your lambda sends message to SQS or some intermediatery messaging service with STATUS and then interemdeiatery invokes POST to your application.
If you still want to go with your way of solving, you might need to configure "DeadLetter queue" to do error handling in failure cases (note that use cases described here are not comprehensive, so need to make sure it covers your case) like described here.

Is it possible to invoke an AWS Lambda function with a payload to make Alexa speak?

I want to have Alexa speak a response to an intent, but by manually invoking the Lambda function that contains the Alexa skill code, rather than by speaking the intent directly to the Echo.
Could you, for instance, send a JSON payload that comprises an intent request to the Lambda function somehow (by AWS-SDK or via a rule on an IoT "thing") and expect the Lambda function to execute and the Echo to play the speech response?
No. If you call your Lambda function, whatever calls it will get the return, not the Echo.
What you are asking for is "push notification". There is a very long thread of people requesting this on the ASK forum. It is the most requested feature for the ASK. But Amazon have never indicated they are considering doing this. But, then, it is their policy not to indicate what they are doing anyway.
Personally I do not think they will ever do this. There are too many security and privacy concerns. Some people have created hacks, whereby the run an agent on a computer hooked to their echo by bluetooth. They push a request to the computer and the computer plays a message over the Echo. That's the closest I've seen.