Skip to content

Commit

Permalink
support ses
Browse files Browse the repository at this point in the history
  • Loading branch information
Xinguang committed Mar 23, 2020
1 parent 92b0e28 commit a1e03e3
Show file tree
Hide file tree
Showing 18 changed files with 524 additions and 272 deletions.
17 changes: 17 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"SendmailFunction": {
"ReCAPTCHA_SECRET": "reCaptcha Secret Key",

"MAIL_SUBJECT": "Test email",
"IS_HTML": "true",
"MAIL_FROM": "[email protected]",
"CC_ADDRESSES": "<[email protected]>, Bob <[email protected]>",
"BCC_ADDRESSES": "<[email protected]>, Bob <[email protected]>",
"TO_ADDRESSES": "<[email protected]>, Bob <[email protected]>",
"SMTP_USER": "[email protected]",
"SMTP_PASSWORD": "password",
"SMTP_HOST": "sender.com",
"SMTP_PORT": "587"
}
}

1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
# Auto detect text files and perform LF normalization
* text=auto
*.html linguist-detectable=false
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,7 @@
main
main.zip
*.bak
.aws
.aws-sam
*.local
*/bak/*
36 changes: 23 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,17 @@ Contact forms. They are all around us. Almost every website has one.

Preparing a binary to deploy to AWS Lambda requires that it is compiled for Linux and placed into a .zip file.


## Via docker

``` shell
docker run -it --rm -v $(pwd):/work -w /work lambci/lambda:build-go1.x sam build
cd .aws-sam/build/SendmailFunction
zip main.zip main
```

## For developers on Linux and macOS

``` shell
# Remember to build your handler executable for Linux!
GOOS=linux GOARCH=amd64 go build -o main main.go
Expand Down Expand Up @@ -105,25 +115,25 @@ Let’s look at the [sample code](example.html) to understand it better.

| Key | Value |
| ------------- | ------------- |
| SENDMAIL_SUBJECT | email subject |
| SENDMAIL_MAILTYPE | html or plain |
| SENDER_USER | smtp user name |
| SENDER_NAME | the display sender name |
| SENDER_PASSWORD | smtp password |
| SENDER_HOST | smtp host(E.g., example.com) |
| SENDER_PORT | smtp port(E.g., 587) |
| RECIPIENTS | recipients (E.g., recipient <[email protected]>;recipient <[email protected]>;) |
| SECRET_KEY | reCaptcha Secret Key |

| ReCAPTCHA_SECRET | reCaptcha Secret Key |
| SES_REGION | AWS Region (E.g.,'us-west-1') |
| MAIL_SUBJECT | email subject |
| IS_HTML | true or false |
| MAIL_FROM | from(E.g., recipient <[email protected]> or [email protected]) |
| TO_ADDRESSES | recipients (E.g., recipient <[email protected]>,recipient <[email protected]>) |
| CC_ADDRESSES | recipients (E.g., recipient <[email protected]>,recipient <[email protected]>) |
| BCC_ADDRESSES | recipients (E.g., recipient <[email protected]>,recipient <[email protected]>) |
| SMTP_USER | smtp user name |
| SMTP_PASSWORD | smtp password |
| SMTP_HOST | smtp host(E.g., example.com) |
| SMTP_PORT | smtp port(E.g., 587) |

### Dev environment

- https://www.jianshu.com/p/166d272f51b3
-
```sh
sam init --runtime

sam local invoke SendmailFunction --event test-event.json
sam local invoke SendmailFunction --event test-event.json --env-vars .env
# or
sam local start-api

Expand Down
4 changes: 4 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
#!/bin/sh
# use sam
# docker run -it --rm -v $(pwd):/work -w /work -v $(pwd)/.aws:/root/.aws lambci/lambda:build-go1.x bash
# docker run -it --rm -v $(pwd):/work -w /work lambci/lambda:build-go1.x sam build

docker run -it --rm -v$(pwd):/work -w /work golang:alpine sh -c'
apk add --update git zip
GOOS=linux go build -v -ldflags '-d -s -w' -a -tags netgo -installsuffix netgo -o main main.go
Expand Down
10 changes: 7 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
module github.com/Xinguang/lambda-sendmail

go 1.12
go 1.13

require (
github.com/aws/aws-lambda-go v1.10.0
github.com/sirupsen/logrus v1.4.1
github.com/aws/aws-lambda-go v1.14.1
github.com/aws/aws-sdk-go v1.29.29
github.com/caarlos0/env v3.5.0+incompatible
github.com/sirupsen/logrus v1.4.2
github.com/xinguang/go-recaptcha v1.0.1
golang.org/x/tools v0.0.0-20200321224714-0d839f3cf2ed // indirect
)
81 changes: 75 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,11 +1,80 @@
github.com/aws/aws-lambda-go v1.10.0 h1:uafgdfYGQD0UeT7d2uKdyWW8j/ZYRifRPIdmeqLzLCk=
github.com/aws/aws-lambda-go v1.10.0/go.mod h1:zUsUQhAUjYzR8AuduJPCfhBuKWUaDbQiPOG+ouzmE1A=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/aws/aws-lambda-go v1.14.1 h1:iklNeBEa1+EbcYVomAcZXXSEViwFzygvAPQ48TLvDlA=
github.com/aws/aws-lambda-go v1.14.1/go.mod h1:FEwgPLE6+8wcGBTe5cJN3JWurd1Ztm9zN4jsXsjzKKw=
github.com/aws/aws-sdk-go v1.29.29 h1:4TdSYzXL8bHKu80tzPjO4c0ALw4Fd8qZGqf1aozUcBU=
github.com/aws/aws-sdk-go v1.29.29/go.mod h1:1KvfttTE3SPKMpo8g2c6jL3ZKfXtFvKscTgahTma5Xg=
github.com/caarlos0/env v3.5.0+incompatible h1:Yy0UN8o9Wtr/jGHZDpCBLpNrzcFLLM2yixi/rBrKyJs=
github.com/caarlos0/env v3.5.0+incompatible/go.mod h1:tdCsowwCzMLdkqRYDlHpZCp2UooDD3MspDBjZ2AD02Y=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33 h1:I6FyU15t786LL7oL/hn43zqTuEGr4PN7F4XJ1p4E3Y8=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/urfave/cli/v2 v2.1.1 h1:Qt8FeAtxE/vfdrLmR3rxR6JRE0RoVmbXu8+6kZtYU4k=
github.com/urfave/cli/v2 v2.1.1/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ=
github.com/xinguang/go-recaptcha v1.0.1 h1:oB6dDxDYofvKl7Emdf/Wj5R9a7ffoMLpwlKW/u9+dRI=
github.com/xinguang/go-recaptcha v1.0.1/go.mod h1:SyVUtlgYY04YsLNZo7frgunPDJ1ZAkdddC0Joro7Xw0=
github.com/yuin/goldmark v1.1.25 h1:isv+Q6HQAmmL2Ofcmg8QauBmDPlUUnSoNhEcC940Rds=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2 h1:CCH4IOTTfewWjGOlSp+zGcjutRKlBEZQ6wTn8ozI/nI=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b h1:0mm1VjtFUOIlE1SbDlwjYaDxZVDP2S5ou6y0gSgXHu8=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200321224714-0d839f3cf2ed h1:OCZDlBlLYiUK6T33/8+3BnojrS2W+Dg1rKYJhR89xGE=
golang.org/x/tools v0.0.0-20200321224714-0d839f3cf2ed/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
34 changes: 20 additions & 14 deletions recaptcha/lambdahandle.go → handle.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package recaptcha
package main

import (
"net/mail"

"github.com/Xinguang/lambda-sendmail/sendmail"
"github.com/aws/aws-lambda-go/events"
log "github.com/sirupsen/logrus"
"github.com/xinguang/go-recaptcha"
)

type Contact struct {
Expand All @@ -15,27 +16,32 @@ type Contact struct {
Token string `json:"token"`
}

// Handle for verify a user's response to a reCAPTCHA challenge
func Handle(contact Contact) (events.APIGatewayProxyResponse, error) {
if !verify(contact.Token) {
var (
captcha *recaptcha.ReCAPTCHA
)
func init() {
_captcha, err := recaptcha.New()
if err != nil {
log.Fatal("ReCAPTCHA:", err)
}
captcha = _captcha
}

// handle for verify a user's response to a reCAPTCHA challenge
func handle(contact Contact) (events.APIGatewayProxyResponse, error) {
log.Debugf("Contact: %s", contact)
err := captcha.Verify(contact.Token)
if err != nil {
return events.APIGatewayProxyResponse{
Body: "timeout-or-duplicate",
Body: err.Error(),
StatusCode: 400,
}, nil
}

log.Info(contact)
reply := mail.Address{Name: contact.Name, Address: contact.Email}
message := sendmail.NewMessage()

message.Add("Reply-To", reply.String())
message.SetBody(contact.Message)

log.Info("send email")
err := sendmail.Send(*message)
_, err = sendmail.Send(reply, contact.Message)

if err != nil {
log.Fatal(err)
return events.APIGatewayProxyResponse{
Body: "there is some errors",
StatusCode: 400,
Expand Down
3 changes: 1 addition & 2 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package main

import (
"github.com/Xinguang/lambda-sendmail/recaptcha"
"github.com/aws/aws-lambda-go/lambda"
)

Expand All @@ -14,5 +13,5 @@ import (
// env GOOS=linux go build -v -ldflags '-d -s -w' -a -tags netgo -installsuffix netgo -o main main.go as a build command.
func main() {
// Make the handler available for Remote Procedure Call by AWS Lambda
lambda.Start(recaptcha.Handle)
lambda.Start(handle)
}
60 changes: 0 additions & 60 deletions recaptcha/recaptcha.go

This file was deleted.

30 changes: 30 additions & 0 deletions sendmail/env.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package sendmail

import (
"github.com/caarlos0/env"
log "github.com/sirupsen/logrus"
)

type ENV struct {
MailSubject string `env:"MAIL_SUBJECT" envDefault:"Test email"`
SesRegion string `env:"SES_REGION" envDefault:"us-west-1"`
IsHtml bool `env:"IS_HTML" envDefault:true`
MailFrom string `env:"MAIL_FROM"`
CcAddresses string `env:"CC_ADDRESSES"`
BccAddresses string `env:"BCC_ADDRESSES"`
ToAddresses string `env:"TO_ADDRESSES"`
SmtpUser string `env:"SMTP_USER"`
SmtpPassword string `env:"SMTP_PASSWORD"`
SmtpHost string `env:"SMTP_HOST"`
SmtpPort int `env:"SMTP_PORT" envDefault:587`
}
var (
envHolder = ENV{}
)

func init() {
err := env.Parse(&envHolder)
if err != nil {
log.Fatal(err)
}
}
Loading

0 comments on commit a1e03e3

Please sign in to comment.