AWS Serverless contact form request - amazon-web-services

I have a static website (a simple landing page) hosted on AWS S3, with Cloudfront enabled in front of it.
I would like to add a public contact form request.
I found some solutions but I would like to know which one is the best.
1/ Front-end JS send a message to an SNS topic and subscribe my email to it (but it means that I need to share an AccessKey in public)
2/ Front-end JS send a message to SNS, trigger a Lambda function which process and send email via SES.
3/ Front-end JS send a POST request to a public API Gateway, trigger a Lambda function which process and send email via SES
4/ Others?
Thank you for your help.

3rd option is the best and easiest one to implement. Also as #Mark said in comments, you don't need to keep your access keys in client side in this case.

3rd for sure. You could even use API Gateway's AWS Service Proxy and call SNS/SES API directly, without the need of using AWS Lambda.
This tutorial covers this use case.

Related

How to bcc another recipient on an Amazon Cognito verification email

For legal reasons I need to BCC someone on my Cognito verification emails when someone signs up on my website. Is there a way to configure this in Amazon SES or Cognito? I have searched through the settings on both of the services and searched google but I haven't been able to find anything. I am wondering if maybe I should use SNS to trigger a welcome email with the compliance information after the user verifies their email, though I am still not sure if this is possible.
You will need to implement a Cognito custom email sender Lambda function. There's an example of that function using NodeJS at the above link. Having gone through this myself I would point out that it can only be done using NodeJS or Java due to the specific AWS encryption SDK needed to decode the email body in your Lambda function.
Inside that example Lambda function you can see the different event triggers the function has to handle. In the CustomEmailSender_SignUp trigger handler you would add your BCC when you send the email.
You would need to use the AWS SDK inside that code to send the emails using SES.

Can an SNS trigger an API gateway? If yes, then how can the API gateway subscribe to the SNS?

I need to create an API gateway to consume messages from an SNS. I see that there are some questions on the same, like this, which hasn't been answered directly.
The main issue I face is : How to make the API gateway subscribe to the SNS?
SNS supports HTTP/HTTPS endpoint subscriptions. So I don't see a reason why you could not subscribe API gateway https endpoint to SNS this way.
As Marcin has mentioned, it can be done. Mentioning the steps I used:
Create SNS, and a lambda
Whatever the language is, make sure to print the event in the log. (For JavaScript, use console.log(event), and for Python use print(event) etc)
Create an API Gateway (REST API), select a "New API", and create it.
In the API create a POST method, select lambda, and make sure to use it as a proxy.
Copy the trigger HTTPS link
Add a HTTPS subscription in the SNS, and use the trigger link here.
The confirmation would be pending now.
Go to the lambda, inside it's monitoring section, go to cloud watch logs.
Inside the logs, you will find the event object printed. Inside it, look for SubscribeURL, along which the URL would be mentioned.
Copy this URL, and go back to the SNS. Select your subscription and use the "Confirm Subscription" option, and paste this link there.
The status should come as "Confirmed" now.

Facing issues adding destination while creating a dynamic contact form for S3 static website using AWS Lambda

I have been trying to create a email form for my website using AWS Lambda, Amazon API Gateway and SES.
I followed the instructions provided in the blog by AWS. The instructions for adding destinations and creating a link between the mailFwd and the destinations are not provided by the article.
Also, there is a part of the article which mentions adding a code snippet under the policy so that SES can access the lambda function. I can't find where the policy section is.
The application flow looks like this:
JavaScript / HTML -> API Gateway -> AWS Lambda Function mailfwd -> SES
This means, your frontend sends an HTTP request to the API Gateway which forwards an HTTP event to your Lambda function and your Lambda function processes the mail data from the HTTP event and forwards it to SES.
To avoid any confusion: SES is neither calling nor accessing your Lambda function, it's only the other way around. In order to allow the Lambda function to call SES and send a mail, you have to copy the IAM policy from the blog post (the policy about ses:SendMail) to the policy of your Lambda function's IAM role. (I admit that the blog post's wording is a bit confusing here).
Besides that, you don't need to create any links between the services. You only need to tell API Gateway which Lambda function to call if an HTTP request comes in. In this case you choose the mailfwd function as mentioned in the article:
Select your newly-created resource and choose “create method.” Choose a POST. Here, you will choose our AWS Lambda Function. To do this, select “mailfwd” from the drop down.

Difference between two methods to confirm AWS SNS topic subscription confirmation

I'm attempting to subscribe an SNS topic to a HTTPS endpoint I own. I'm reading the docs on how to process incoming messages from SNS and how the subscription confirmation needs to be done. I see two methods of confirmation:
https://docs.aws.amazon.com/sns/latest/dg/sns-http-https-endpoint-as-subscriber.html - Using the subscribeURL. We can perform a HTTP get request on the "SubscribeURL" attribute value and that would confirm the subscription.
Calling the ConfirmSubscription API - We pass the SNS Topic ARN and the token received when SNS sends a confirm subscription message to the SNS endpoint.
I'm trying to understand what's the difference between the two methods. The most obvious one to me was this - The choice of using the API will require AWS credentials since the request needs to be signed. But seems like the same call will succeed with just the HTTP GET request?
What's the best practice out there (if any) and/or which method is the one being followed by other folks using AWS/SNS?
There isn't a difference -- these two alternatives are in fact the same thing.
The SubscribeURL attribute is a pre-constructed (by the service) link to the ConfirmSubscription action on the SNS API endpoint.
The API accepts GET or POST. No signature is required in this case.
This call requires an AWS signature only when the AuthenticateOnUnsubscribe flag is set to "true".
https://docs.aws.amazon.com/sns/latest/api/API_ConfirmSubscription.html
Before SNS will talk to an endpoint, you need to prove that you control that endpoint. So your options are to write some code that can do it automatically (most of the SDKs support this) or to capture the token, and by returning it via the API call prove that you control it.
This is a one-time procedure, so you do not need to deploy any AWS credentials to your API endpoint - you can do it from a different system.
We generally build the confirmation handler into the application.

Possible to send request directly to Amazon SQS from http (javascript client)?

Is it possible to send a messaging request to Amazon's SQS directly from javascript? I'm trying to create a logging system and would love to bypass sending the request to a middleman server. Also, does anybody know of any alternatives to this solution that I may leverage?
SQS(and as a matter of fact all aws services) expose REST based apis. You can directly make a http request to the SQS REST api through javascript code. The api documentation id given here.
Unless you load your Javascript from the same SQS domain as you're trying to send to then no, due the clients/Javascript Same-Origin Policy you wont be able to cross post to SQS.
Your best bet is to use a middle-man server of your own.
You can use the AWS Javascript API in your JS app, and then use that library to make the SQS API call for you.