github.com/aws/aws-sdk-go-v2/service/route53 v1.40.0/go.mod h1:n6oZO1BbhPw2X46ObAjn8ol00kujRT+Y+Q9AnbrRUe0=
github.com/aws/aws-sdk-go-v2/service/s3 v1.53.0 h1:r3o2YsgW9zRcIP3Q0WCmttFVhTuugeKIvT5z9xDspc0=
github.com/aws/aws-sdk-go-v2/service/s3 v1.53.0/go.mod h1:w2E4f8PUfNtyjfL6Iu+mWI96FGttE03z3UdNcUEC4tA=
-github.com/aws/aws-sdk-go-v2/service/ses v1.22.0 h1:1HJMg3WpV9L003TOhH8eEQgkPnegOwCE3/j0Iqlmt0U=
-github.com/aws/aws-sdk-go-v2/service/ses v1.22.0/go.mod h1:9MbVy83ucnbP+4D9lky3IeUBxjECR2bHq63yzkl+WKU=
github.com/aws/aws-sdk-go-v2/service/ssm v1.49.0 h1:EtNvvxv0m6aP4cbTyo43vBRXeTpyt8juyNPmgKSTyYs=
github.com/aws/aws-sdk-go-v2/service/ssm v1.49.0/go.mod h1:wzPAvA+afHPFlAMkCf80sg7bm7GbCuFX1INetlm9DAk=
github.com/aws/aws-sdk-go-v2/service/sso v1.19.0 h1:u6OkVDxtBPnxPkZ9/63ynEe+8kHbtS5IfaC4PzVxzWM=
github.com/aws/aws-sdk-go-v2/service/sts v1.27.0/go.mod h1:nXfOBMWPokIbOY+Gi7a1psWMSvskUCemZzI+SMB7Akc=
github.com/aws/smithy-go v1.20.1 h1:4SZlSlMr36UEqC7XOyRVb27XMeZubNcBNN+9IgEPIQw=
github.com/aws/smithy-go v1.20.1/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E=
-github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
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-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw=
github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
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/resend/resend-go/v2 v2.28.0 h1:ttM1/VZR4fApBv3xI1TneSKi1pbfFsVrq7fXFlHKtj4=
+github.com/resend/resend-go/v2 v2.28.0/go.mod h1:3YCb8c8+pLiqhtRFXTyFwlLvfjQtluxOr9HEh2BwCkQ=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
+github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts=
golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos=
golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
"context"
"fmt"
- "github.com/aws/aws-sdk-go-v2/aws"
- "github.com/aws/aws-sdk-go-v2/service/ses"
- sestypes "github.com/aws/aws-sdk-go-v2/service/ses/types"
+ resend "github.com/resend/resend-go/v2"
)
type Config struct {
+ ApiKey string
FromEmail string
BaseDomain string
}
type Client struct {
- ses *ses.Client
- cfg Config
+ resend *resend.Client
+ cfg Config
}
-func NewClient(awsCfg aws.Config, cfg Config) *Client {
+func NewClient(cfg Config) *Client {
return &Client{
- ses: ses.NewFromConfig(awsCfg),
- cfg: cfg,
+ resend: resend.NewClient(cfg.ApiKey),
+ cfg: cfg,
}
}
-func (c *Client) SendWelcome(ctx context.Context, email, slug, password string) error {
+func (c *Client) SendWelcome(_ context.Context, email, slug, password string) error {
url := fmt.Sprintf("https://%s.%s", slug, c.cfg.BaseDomain)
- subject := "Your Crimata hub is ready"
- text := fmt.Sprintf("Your hub is live at %s\n\nPassword: %s\n\nChange your password in Settings after logging in.\n\n— Crimata", url, password)
- html := fmt.Sprintf(`<p>Your hub is live at <a href="%s">%s</a></p><p><strong>Password:</strong> <code>%s</code></p><p style="color:#555">Change your password in Settings after logging in.</p><p>— Crimata</p>`, url, url, password)
- _, err := c.ses.SendEmail(ctx, &ses.SendEmailInput{
- Source: aws.String(c.cfg.FromEmail),
- Destination: &sestypes.Destination{ToAddresses: []string{email}},
- Message: &sestypes.Message{
- Subject: &sestypes.Content{Data: aws.String(subject)},
- Body: &sestypes.Body{
- Text: &sestypes.Content{Data: aws.String(text)},
- Html: &sestypes.Content{Data: aws.String(html)},
- },
- },
+ _, err := c.resend.Emails.Send(&resend.SendEmailRequest{
+ From: c.cfg.FromEmail,
+ To: []string{email},
+ Subject: "Your Crimata hub is ready",
+ Text: fmt.Sprintf("Your hub is live at %s\n\nUsername: %s\nPassword: %s\n\nChange your password in Settings after logging in.\n\n— Crimata", url, slug, password),
+ Html: fmt.Sprintf(`<p>Your hub is live at <a href="%s">%s</a></p><p><strong>Username:</strong> <code>%s</code><br><strong>Password:</strong> <code>%s</code></p><p style="color:#555">Change your password in Settings after logging in.</p><p>— Crimata</p>`, url, url, slug, password),
})
return err
}
-func (c *Client) SendDataExport(ctx context.Context, email, downloadURL string) error {
- subject := "Your Crimata data export is ready"
- text := fmt.Sprintf("Your data export is ready for download:\n\n%s\n\nThis link expires in 24 hours.\n\n— Crimata", downloadURL)
- html := fmt.Sprintf(`<p>Your data export is ready: <a href="%s">Download</a></p><p style="color:#555">This link expires in 24 hours.</p><p>— Crimata</p>`, downloadURL)
-
- _, err := c.ses.SendEmail(ctx, &ses.SendEmailInput{
- Source: aws.String(c.cfg.FromEmail),
- Destination: &sestypes.Destination{ToAddresses: []string{email}},
- Message: &sestypes.Message{
- Subject: &sestypes.Content{Data: aws.String(subject)},
- Body: &sestypes.Body{
- Text: &sestypes.Content{Data: aws.String(text)},
- Html: &sestypes.Content{Data: aws.String(html)},
- },
- },
+func (c *Client) SendDataExport(_ context.Context, email, downloadURL string) error {
+ _, err := c.resend.Emails.Send(&resend.SendEmailRequest{
+ From: c.cfg.FromEmail,
+ To: []string{email},
+ Subject: "Your Crimata data export is ready",
+ Text: fmt.Sprintf("Your data export is ready for download:\n\n%s\n\nThis link expires in 24 hours.\n\n— Crimata", downloadURL),
+ Html: fmt.Sprintf(`<p>Your data export is ready: <a href="%s">Download</a></p><p style="color:#555">This link expires in 24 hours.</p><p>— Crimata</p>`, downloadURL),
})
return err
}