2022-07-06 23:19:05 +02:00
|
|
|
package mailer
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"errors"
|
|
|
|
"mime"
|
|
|
|
"net/http"
|
|
|
|
"os/exec"
|
2023-02-01 22:07:46 +02:00
|
|
|
"strings"
|
2022-07-06 23:19:05 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
var _ Mailer = (*Sendmail)(nil)
|
|
|
|
|
2022-12-13 11:45:59 +02:00
|
|
|
// Sendmail implements [mailer.Mailer] interface and defines a mail
|
|
|
|
// client that sends emails via the "sendmail" *nix command.
|
2022-07-06 23:19:05 +02:00
|
|
|
//
|
|
|
|
// This client is usually recommended only for development and testing.
|
|
|
|
type Sendmail struct {
|
|
|
|
}
|
|
|
|
|
|
|
|
// Send implements `mailer.Mailer` interface.
|
2022-11-21 14:53:05 +02:00
|
|
|
func (c *Sendmail) Send(m *Message) error {
|
2023-02-01 22:07:46 +02:00
|
|
|
toAddresses := addressesToStrings(m.To, false)
|
|
|
|
|
2022-07-06 23:19:05 +02:00
|
|
|
headers := make(http.Header)
|
2022-11-21 14:53:05 +02:00
|
|
|
headers.Set("Subject", mime.QEncoding.Encode("utf-8", m.Subject))
|
|
|
|
headers.Set("From", m.From.String())
|
2022-07-06 23:19:05 +02:00
|
|
|
headers.Set("Content-Type", "text/html; charset=UTF-8")
|
2023-02-01 22:07:46 +02:00
|
|
|
headers.Set("To", strings.Join(toAddresses, ","))
|
2022-07-06 23:19:05 +02:00
|
|
|
|
|
|
|
cmdPath, err := findSendmailPath()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
var buffer bytes.Buffer
|
|
|
|
|
|
|
|
// write
|
|
|
|
// ---
|
|
|
|
if err := headers.Write(&buffer); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if _, err := buffer.Write([]byte("\r\n")); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2022-11-21 14:53:05 +02:00
|
|
|
if m.HTML != "" {
|
|
|
|
if _, err := buffer.Write([]byte(m.HTML)); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if _, err := buffer.Write([]byte(m.Text)); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2022-07-06 23:19:05 +02:00
|
|
|
}
|
|
|
|
// ---
|
|
|
|
|
2023-02-01 22:07:46 +02:00
|
|
|
sendmail := exec.Command(cmdPath, strings.Join(toAddresses, ","))
|
2022-07-06 23:19:05 +02:00
|
|
|
sendmail.Stdin = &buffer
|
|
|
|
|
|
|
|
return sendmail.Run()
|
|
|
|
}
|
|
|
|
|
|
|
|
func findSendmailPath() (string, error) {
|
|
|
|
options := []string{
|
|
|
|
"/usr/sbin/sendmail",
|
|
|
|
"/usr/bin/sendmail",
|
|
|
|
"sendmail",
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, option := range options {
|
|
|
|
path, err := exec.LookPath(option)
|
|
|
|
if err == nil {
|
|
|
|
return path, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return "", errors.New("Failed to locate a sendmail executable path.")
|
|
|
|
}
|