Send RSVP confirmation emails via Resend
This commit is contained in:
1
go.mod
1
go.mod
@@ -4,6 +4,7 @@ go 1.24.0
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/lib/pq v1.10.9
|
github.com/lib/pq v1.10.9
|
||||||
|
github.com/resend/resend-go/v2 v2.28.0
|
||||||
github.com/stripe/stripe-go/v76 v76.25.0
|
github.com/stripe/stripe-go/v76 v76.25.0
|
||||||
google.golang.org/api v0.258.0
|
google.golang.org/api v0.258.0
|
||||||
)
|
)
|
||||||
|
|||||||
2
go.sum
2
go.sum
@@ -30,6 +30,8 @@ github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
|||||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
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 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
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/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||||
|
|||||||
69
main.go
69
main.go
@@ -18,12 +18,29 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
_ "github.com/lib/pq"
|
_ "github.com/lib/pq"
|
||||||
|
"github.com/resend/resend-go/v2"
|
||||||
"github.com/stripe/stripe-go/v76"
|
"github.com/stripe/stripe-go/v76"
|
||||||
"github.com/stripe/stripe-go/v76/checkout/session"
|
"github.com/stripe/stripe-go/v76/checkout/session"
|
||||||
"github.com/stripe/stripe-go/v76/webhook"
|
"github.com/stripe/stripe-go/v76/webhook"
|
||||||
"google.golang.org/api/idtoken"
|
"google.golang.org/api/idtoken"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type eventInfo struct {
|
||||||
|
Name string
|
||||||
|
Date string
|
||||||
|
Location string
|
||||||
|
Address string
|
||||||
|
}
|
||||||
|
|
||||||
|
var events = map[string]eventInfo{
|
||||||
|
"afac26": {
|
||||||
|
Name: "Applause for a Cause",
|
||||||
|
Date: "Saturday, February 7, 2026 at 6:30 PM",
|
||||||
|
Location: "Helios Gym",
|
||||||
|
Address: "597 Central Avenue, Sunnyvale, CA 94086",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
templates *template.Template
|
templates *template.Template
|
||||||
db *sql.DB
|
db *sql.DB
|
||||||
@@ -241,6 +258,9 @@ func handleRSVPPost(w http.ResponseWriter, r *http.Request) {
|
|||||||
http.Error(w, "database error", http.StatusInternalServerError)
|
http.Error(w, "database error", http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if *req.NumPeople > 0 {
|
||||||
|
go sendRSVPConfirmation(eventID, email, *req.NumPeople)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
numPeople, donation, err := getRSVP(eventID, email)
|
numPeople, donation, err := getRSVP(eventID, email)
|
||||||
@@ -352,6 +372,55 @@ func processPayment(sess *stripe.CheckoutSession) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func sendRSVPConfirmation(eventID, email string, numPeople int) {
|
||||||
|
event, ok := events[eventID]
|
||||||
|
if !ok {
|
||||||
|
log.Printf("[ERROR] unknown event %s for email confirmation", eventID)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
resendKey := os.Getenv("RESEND_KEY")
|
||||||
|
if resendKey == "" {
|
||||||
|
log.Println("[ERROR] RESEND_KEY not set, skipping confirmation email")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
client := resend.NewClient(resendKey)
|
||||||
|
|
||||||
|
word := "person"
|
||||||
|
if numPeople != 1 {
|
||||||
|
word = "people"
|
||||||
|
}
|
||||||
|
|
||||||
|
html := fmt.Sprintf(`
|
||||||
|
<div style="font-family: sans-serif; max-width: 600px; margin: 0 auto;">
|
||||||
|
<h2>Your RSVP is Confirmed!</h2>
|
||||||
|
<p>You're all set for <strong>%s</strong>.</p>
|
||||||
|
<table style="margin: 20px 0; border-collapse: collapse;">
|
||||||
|
<tr><td style="padding: 8px 0; color: #666;">Party Size</td><td style="padding: 8px 0 8px 20px;"><strong>%d %s</strong></td></tr>
|
||||||
|
<tr><td style="padding: 8px 0; color: #666;">Date</td><td style="padding: 8px 0 8px 20px;"><strong>%s</strong></td></tr>
|
||||||
|
<tr><td style="padding: 8px 0; color: #666;">Location</td><td style="padding: 8px 0 8px 20px;"><strong>%s</strong><br>%s</td></tr>
|
||||||
|
</table>
|
||||||
|
<p>See you there!</p>
|
||||||
|
<p style="color: #666; font-size: 14px; margin-top: 30px;">— HCA Events</p>
|
||||||
|
</div>
|
||||||
|
`, event.Name, numPeople, word, event.Date, event.Location, event.Address)
|
||||||
|
|
||||||
|
params := &resend.SendEmailRequest{
|
||||||
|
From: "HCA Events <events@hca.run>",
|
||||||
|
To: []string{email},
|
||||||
|
Subject: fmt.Sprintf("RSVP Confirmed: %s", event.Name),
|
||||||
|
Html: html,
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := client.Emails.Send(params)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("[ERROR] failed to send confirmation email to %s: %v", email, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Printf("sent confirmation email to %s for %s", email, eventID)
|
||||||
|
}
|
||||||
|
|
||||||
func handleDonateSuccess(w http.ResponseWriter, r *http.Request) {
|
func handleDonateSuccess(w http.ResponseWriter, r *http.Request) {
|
||||||
eventID := r.PathValue("eventID")
|
eventID := r.PathValue("eventID")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user