town/email/email.go

120 lines
2.4 KiB
Go
Raw Permalink Normal View History

2021-03-23 21:58:17 +00:00
package email
import (
"bytes"
2023-03-07 01:06:46 +00:00
"crypto/tls"
2021-03-23 21:58:17 +00:00
"fmt"
2024-04-16 00:44:55 +00:00
"net"
"net/mail"
2023-03-07 01:06:46 +00:00
"net/smtp"
2021-03-23 21:58:17 +00:00
"os/exec"
)
2023-03-07 01:06:46 +00:00
const (
2024-04-08 17:25:52 +00:00
SMTPHost = "smtp.migadu.com"
2023-03-09 06:33:31 +00:00
SMTPPort = 465
2023-03-07 01:06:46 +00:00
)
2021-03-23 21:58:17 +00:00
func SendLocalEmail(username, subject, body string) error {
cmd := exec.Command("/usr/sbin/sendmail", username)
cmd.Stdin = bytes.NewBufferString(fmt.Sprintf("Subject: %s\n\n%s", subject, body))
if err := cmd.Run(); err != nil {
return fmt.Errorf("failed to send local email: %w", err)
}
return nil
}
2023-03-07 01:06:46 +00:00
type ExternalMailer struct {
Password string
}
func NewExternalMailer(pw string) *ExternalMailer {
if pw == "" {
panic("why?")
}
return &ExternalMailer{
Password: pw,
}
}
2024-04-16 00:44:55 +00:00
func (m *ExternalMailer) Send(address, subj, body string) error {
2024-09-01 20:34:29 +00:00
from := mail.Address{Name: "Tilde Town Admins", Address: "root@tilde.town"}
to := mail.Address{Name: "", Address: address}
2023-03-09 06:33:31 +00:00
2024-04-16 00:44:55 +00:00
// Setup headers
headers := make(map[string]string)
headers["From"] = from.String()
headers["To"] = to.String()
headers["Subject"] = subj
// Setup message
2023-03-09 06:33:31 +00:00
message := ""
for k, v := range headers {
message += fmt.Sprintf("%s: %s\r\n", k, v)
}
message += "\r\n" + body
2024-04-16 00:44:55 +00:00
// Connect to the SMTP Server
servername := fmt.Sprintf("%s:%d", SMTPHost, SMTPPort)
host, _, _ := net.SplitHostPort(servername)
2023-03-07 01:06:46 +00:00
2024-04-16 00:44:55 +00:00
auth := smtp.PlainAuth("", "root@tilde.town", m.Password, host)
2023-03-07 01:06:46 +00:00
2024-04-16 00:44:55 +00:00
// TLS config
tlsconfig := &tls.Config{
2023-03-07 01:06:46 +00:00
InsecureSkipVerify: true,
2024-04-16 00:44:55 +00:00
ServerName: host,
2023-03-07 01:06:46 +00:00
}
2024-04-16 00:44:55 +00:00
// Here is the key, you need to call tls.Dial instead of smtp.Dial
// for smtp servers running on 465 that require an ssl connection
// from the very beginning (no starttls)
conn, err := tls.Dial("tcp", servername, tlsconfig)
2023-03-07 01:06:46 +00:00
if err != nil {
2024-04-16 00:44:55 +00:00
return fmt.Errorf("failed dial: %w", err)
2023-03-07 01:06:46 +00:00
}
2024-04-16 00:44:55 +00:00
c, err := smtp.NewClient(conn, host)
2023-03-07 01:06:46 +00:00
if err != nil {
2024-04-16 00:44:55 +00:00
return fmt.Errorf("failed to make smtp client: %w", err)
2023-03-07 01:06:46 +00:00
}
2024-04-16 00:44:55 +00:00
// Auth
2023-03-07 01:06:46 +00:00
if err = c.Auth(auth); err != nil {
2024-04-16 00:44:55 +00:00
return fmt.Errorf("failed to make auth: %w", err)
2023-03-07 01:06:46 +00:00
}
2024-04-16 00:44:55 +00:00
// To && From
if err = c.Mail(from.Address); err != nil {
return fmt.Errorf("failed to create mail: %w", err)
2023-03-07 01:06:46 +00:00
}
2024-04-16 00:44:55 +00:00
if err = c.Rcpt(to.Address); err != nil {
return fmt.Errorf("failed to add rcpt: %w", err)
2023-03-07 01:06:46 +00:00
}
2024-04-16 00:44:55 +00:00
// Data
2023-03-07 01:06:46 +00:00
w, err := c.Data()
if err != nil {
2024-04-16 00:44:55 +00:00
return fmt.Errorf("failed to send data: %w", err)
2023-03-07 01:06:46 +00:00
}
2023-03-10 03:21:12 +00:00
_, err = w.Write([]byte(message))
2023-03-07 01:06:46 +00:00
if err != nil {
2024-04-16 00:44:55 +00:00
return fmt.Errorf("failed to write: %w", err)
}
err = w.Close()
if err != nil {
return fmt.Errorf("failed to close: %w", err)
2023-03-07 01:06:46 +00:00
}
c.Quit()
return nil
}