Select Git revision
mail.go 3.74 KiB
package api
import (
"bytes"
"net/smtp"
"strings"
"text/template"
"0xacab.org/meskio/cicer/api/db"
)
const (
orderTmpl = `To: {{.To}}
From: {{.From}}
Content-Type: text/plain; charset="utf-8"
Subject: [garbanzo] pedido {{.OrderName}}
Hola {{.MemberName}},
El pedido {{.OrderName}} a sido cerrado.
Se han pedido:{{range $name, $amount := .Products}}
* {{$name}}: {{$amount}}{{end}}
Las siguientes personas han pedido:
{{range $name, $purchases := .Purchases}}
{{$name}}:{{range $purchases}}
* {{.OrderProduct.Product.Name}}: {{.Amount}}{{end}}
{{end}}
Salud y garbancicos.
`
passwordResetTmpl = `To: {{.To}}
From: {{.From}}
Content-Type: text/plain; charset="utf-8"
Subject: [garbanzo] recupera tu contraseña
Hola {{.Name}},
Hemos recivido una petición para recuperar tu contraseña en el Garbanzo Negro.
Si no has pedido cambiar tu contraseña ignora este email o si siguen llegandote
emails como este informa a las administradoras.
Para cambiar tu contraseña visita el siguiente enlace y sigue las instrucciones:
{{.Link}}
Salud y garbancicos.
`
newMemberTmpl = `To: {{.To}}
From: {{.From}}
Content-Type: text/plain; charset="utf-8"
Subject: [garbanzo] bienvenida a cicer
Hola {{.Name}},
Bienvenida a Cicer, la web de gestión de el Garbanzo Negro. Tu cuenta esta casi
creada, solo nos falta elijas una contraseña y un nombre de acceso visitando el
siguiente enlace:
{{.Link}}
Salud y garbancicos.
`
)
type Mail struct {
auth smtp.Auth
server string
email string
baseURL string
tmpl *template.Template
}
func NewMail(email, password, server, baseURL string) *Mail {
hostname := strings.Split(server, ":")[0]
username := strings.Split(email, "@")[0]
tmpl := template.Must(template.New("order").Parse(orderTmpl))
template.Must(tmpl.New("password_reset").Parse(passwordResetTmpl))
template.Must(tmpl.New("new_member").Parse(newMemberTmpl))
return &Mail{
auth: smtp.PlainAuth("", username, password, hostname),
server: server,
email: email,
baseURL: baseURL,
tmpl: tmpl,
}
}
type orderData struct {
To string
From string
MemberName string
OrderName string
Products map[string]int
Purchases map[string][]db.OrderPurchase
}
func (m Mail) sendOrder(to string, order *db.Order) error {
if m.server == "" {
return nil
}
products := make(map[string]int)
purchases := make(map[string][]db.OrderPurchase)
for _, t := range order.Transactions {
var purchase []db.OrderPurchase
for _, p := range t.OrderPurchase {
if p.Amount == 0 {
continue
}
products[p.OrderProduct.Product.Name] += p.Amount
purchase = append(purchase, p)
}
purchases[t.Member.Name] = purchase
}
data := orderData{
To: to,
From: m.email,
OrderName: order.Name,
MemberName: order.Member.Name,
Products: products,
Purchases: purchases,
}
var buff bytes.Buffer
err := m.tmpl.ExecuteTemplate(&buff, "order", data)
if err != nil {
return err
}
return smtp.SendMail(m.server, m.auth, m.email, []string{to}, buff.Bytes())
}
type passwordResetData struct {
To string
From string
Name string
Link string
}
func (m Mail) sendPasswordReset(member db.Member, link string) error {
return m.sendMemberReset(member, link, "password_reset")
}
func (m Mail) sendNewMember(member db.Member, link string) error {
return m.sendMemberReset(member, link, "new_member")
}
func (m Mail) sendMemberReset(member db.Member, link string, tmpl string) error {
if m.server == "" {
return nil
}
var buff bytes.Buffer
data := passwordResetData{
To: member.Email,
From: m.email,
Name: member.Name,
Link: m.baseURL + link,
}
err := m.tmpl.ExecuteTemplate(&buff, tmpl, data)
if err != nil {
return err
}
return smtp.SendMail(m.server, m.auth, m.email, []string{member.Email}, buff.Bytes())
}