wallet-sync-server/mail/mail.go
2022-08-22 12:05:53 -04:00

107 lines
2.4 KiB
Go

package mail
import (
"context"
"fmt"
"log"
"time"
"github.com/mailgun/mailgun-go/v4"
"lbryio/wallet-sync-server/auth"
"lbryio/wallet-sync-server/env"
"lbryio/wallet-sync-server/server/paths"
)
const MAILGUN_DEBUG = false
// useful with MAILGUN_DEBUG to see what gets called with what
const MAILGUN_DRY_RUN = false
type MailInterface interface {
SendVerificationEmail(auth.Email, auth.VerifyTokenString) error
}
type Mail struct {
Env env.EnvInterface
}
// Split out everything I can to make it testable. Right now
// mailgun.MailgunImpl is inspectable enough to test but
// mailgun.Message is not.
func (m *Mail) prepareMessage(token auth.VerifyTokenString) (
mg *mailgun.MailgunImpl,
sender string,
subject string,
text string,
html string,
err error,
) {
verificationMode, err := env.GetAccountVerificationMode(m.Env)
if err != nil {
return
}
sendingDomain, serverDomain, isDomainEU, privateAPIKey, err := env.GetMailgunConfigs(m.Env, verificationMode)
if err != nil {
return
}
// Create an instance of the Mailgun Client
mg = mailgun.NewMailgun(sendingDomain, privateAPIKey)
// see https://help.mailgun.com/hc/en-us/articles/360007512013-Can-I-migrate-my-domain-to-EU-
if isDomainEU {
mg.SetAPIBase("https://api.eu.mailgun.net/v3")
}
sender = fmt.Sprintf("wallet-sync@%s", sendingDomain)
subject = fmt.Sprintf("Verify your wallet sync account on %s", serverDomain)
url := fmt.Sprintf("https://%s%s?verifyToken=%s", serverDomain, paths.PathVerify, token)
text = fmt.Sprintf("Click here to verify your account:\n\n%s", url)
html = fmt.Sprintf("Click here to verify your account:\n\n<a href=\"%s\">%s</a>", url, url)
if MAILGUN_DEBUG {
log.Printf(
"NewMessage\n\n%s\n\n%s\n\n%s\n\n%s",
sender, subject, text, html,
)
}
return
}
func (m *Mail) SendVerificationEmail(recipient auth.Email, token auth.VerifyTokenString) (err error) {
mg, sender, subject, text, html, err := m.prepareMessage(token)
if err != nil {
return err
}
message := mg.NewMessage(sender, subject, text, string(recipient))
message.SetHtml(html)
if MAILGUN_DEBUG {
log.Printf("Send\n\n%+v\n", message)
}
if !MAILGUN_DRY_RUN {
// Send the message with a 10 second timeout
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
defer cancel()
resp, id, err := mg.Send(ctx, message)
if err != nil {
log.Fatal(err)
}
if MAILGUN_DEBUG {
log.Printf("Sent Mailgun message. ID: %s Resp: %s\n", id, resp)
}
}
return
}