Possible to get the message body with lambda? - amazon-web-services

I set the MX records for my domain to the ones AWS provides for receiving emails with SES.
Now I want to process incoming emails via Lambda function.
To be more specific, I would like to scan the message body for certain keywords and perform a task based on this.
Does the lambda function get the email body? When looking through the event variable, I could only find a subject line.
All examples I found went to S3 to get the message body. Does the body really not get sent to Lambda and it is necessary to fetch it via S3?

Message bodies can get very large. That's why you need to download them from S3.

Related

Can a lambda return a response and wait for a new body without closing the session?

I am running a puppeteer function in AWS Lambda and I have a scenario that the user makes a POST request to the lambda with his username and email. The function is going to check if they are valid in a website and return the JSON to the user with the answer. Is it possible to use the same lambda session to receive another input/body from the user?
The reason I need it to be the same session is because each time an user and email is sent to the lambda, the puppeteer website is going to generate unique ID's that need to be used AFTER the user sends his data in that exact moment because it is logged into the website with an unique session.
I'm currently running this function in a NodeJS and it is fine because the session isnt going to be closed but the session is closed once the lambda returns the first response.
Like people mentioned above, Lambda function is stateless resource and you can ultimately use dynamoDB to store any values such session ID or so.
Additionally, if the Lambda function should wait for response or any updated values by querying DynamoDB, then you can implement AWS Step Function or Airflow which provides the "wait" state.
See what States you can leverage in the AWS Docs.

How to invoke lambda when lex does not process the intent automatically?

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.

Amazon Lex get incoming SMS number in java lambda function handler from Twilio?

I've created a lex sms chatbot and published it to a Twilio SMS Channel. Within my java lambda fulfillment handleRequest function I receive 2 parameters: an Input object and a Context. Input has some type of system generated userId, but I need the phone number of the incoming sms message from Twilio.
I've configured Twilio to call Lex via webhook per these instructions:
http://docs.aws.amazon.com/lex/latest/dg/twilio-bot-association.html#twilio-bot-assoc-create-assoc
I'm using the system created webhook callback url between Lex and Twilio and would like to avoid writing my own Lex-Twilio go between with Gateway API and lambda if possible.
I think I'm missing a configuration in Twilio to send this to Lex maybe? I haven't setup any TwilML app or anything, just linked the SMS number to my webhook callback url for lex. Everything works fine except getting the incoming sms number.
UPDATE:
I exhausted all possibilities with my input object and context in my java lambda function. I guess there's no way to get at the payload from twilio in Java. I tried switching to an input stream handler but still only had the input format defined in the documentation here: http://docs.aws.amazon.com/lex/latest/dg/lambda-input-response-format.html
I had to bite the bullet and build my own gateway API and Node handler. It's just a layer that sits before lex and translates twilio into lex input format and vis versa on the response. It updates the userId with the incoming phone number.
This tutorial was very useful in doing this:
https://aws.amazon.com/blogs/ai/integrate-your-amazon-lex-bot-with-any-messaging-service/
It was a lot of work just to get one additional field, but It does provide me the flexibility to switch SMS providers in the future easier.
I am not sure as what exactly stopped you from getting the user phone number in your lambda function. You can always get sender phone number from 'userId' field from the input event in your lambda function. You can refer to the documentation to get more information.

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.

example of params for publishing to an amazon sns topic using node.js

I'm trying to follow along the amazon sns publish example using the Amazon documentation site but it's vague on Message, MessageAttributes and MessageStructure.
First of all, is the Message property going to be a string even if you set MessageStructure to json? e.g. If I want to send an object instead of just a string message. If it's string - do I need to JSON.stringify my object before passing it as a Message property?
http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/SNS.html#publish-property
Should I be doing this using MessageAttributes instead? What is that property - the amazon documentation merely states it "Message attributes for Publish action" which seems like a tautology.
http://docs.aws.amazon.com/sns/latest/APIReference/API_Publish.html
Setting MessageStructure to json is only used if you are going to send a json-formatted message structure to SNS in the specific jormat SNS understands. This is only used when you are publishing to multiple endpoint types and want to vary the message body by endpoint type. This isn't the same as "I want to send a message where the body has been serialized as JSON."
If you are sending "a JSON object," you need to stringify it, and send it just as you would any other (non-JSON) messages, because SNS messages are, fundamentally, strings.
MessageAttributes are something else entirely. They allow you to send pseudo-out-of-band key/value pairs along with your message, which can be useful for example if your message has been gzipped and base64 encoded (again, for example) you could attach an "external_id" attribute that the recipient could evaluate to decide whether it needed to unpack the whole message or could just discard it.