mirror of
https://github.com/binwiederhier/ntfy.git
synced 2025-05-03 23:41:30 +02:00
Send emails
This commit is contained in:
parent
c8c53eed07
commit
873c57b3d8
6 changed files with 46 additions and 14 deletions
|
@ -7,7 +7,6 @@ import (
|
||||||
"github.com/urfave/cli/v2/altsrc"
|
"github.com/urfave/cli/v2/altsrc"
|
||||||
"heckel.io/ntfy/util"
|
"heckel.io/ntfy/util"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -60,7 +59,3 @@ func initConfigFileInputSource(configFlag string, flags []cli.Flag) cli.BeforeFu
|
||||||
return altsrc.ApplyInputSourceValues(context, inputSource, flags)
|
return altsrc.ApplyInputSourceValues(context, inputSource, flags)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func collapseTopicURL(s string) string {
|
|
||||||
return strings.TrimPrefix(strings.TrimPrefix(s, "https://"), "http://")
|
|
||||||
}
|
|
||||||
|
|
|
@ -95,6 +95,7 @@ func execServe(c *cli.Context) error {
|
||||||
conf.CacheDuration = cacheDuration
|
conf.CacheDuration = cacheDuration
|
||||||
conf.KeepaliveInterval = keepaliveInterval
|
conf.KeepaliveInterval = keepaliveInterval
|
||||||
conf.ManagerInterval = managerInterval
|
conf.ManagerInterval = managerInterval
|
||||||
|
//XXXXXXXXX
|
||||||
conf.GlobalTopicLimit = globalTopicLimit
|
conf.GlobalTopicLimit = globalTopicLimit
|
||||||
conf.VisitorSubscriptionLimit = visitorSubscriptionLimit
|
conf.VisitorSubscriptionLimit = visitorSubscriptionLimit
|
||||||
conf.VisitorRequestLimitBurst = visitorRequestLimitBurst
|
conf.VisitorRequestLimitBurst = visitorRequestLimitBurst
|
||||||
|
|
|
@ -180,7 +180,7 @@ func runCommandInternal(c *cli.Context, command string, m *client.Message) error
|
||||||
defer os.Remove(scriptFile)
|
defer os.Remove(scriptFile)
|
||||||
verbose := c.Bool("verbose")
|
verbose := c.Bool("verbose")
|
||||||
if verbose {
|
if verbose {
|
||||||
log.Printf("[%s] Executing: %s (for message: %s)", collapseTopicURL(m.TopicURL), command, m.Raw)
|
log.Printf("[%s] Executing: %s (for message: %s)", util.ShortTopicURL(m.TopicURL), command, m.Raw)
|
||||||
}
|
}
|
||||||
cmd := exec.Command("sh", "-c", scriptFile)
|
cmd := exec.Command("sh", "-c", scriptFile)
|
||||||
cmd.Stdin = c.App.Reader
|
cmd.Stdin = c.App.Reader
|
||||||
|
|
|
@ -41,6 +41,10 @@ type Config struct {
|
||||||
ManagerInterval time.Duration
|
ManagerInterval time.Duration
|
||||||
AtSenderInterval time.Duration
|
AtSenderInterval time.Duration
|
||||||
FirebaseKeepaliveInterval time.Duration
|
FirebaseKeepaliveInterval time.Duration
|
||||||
|
SMTPAddr string
|
||||||
|
SMTPUser string
|
||||||
|
SMTPPass string
|
||||||
|
SMTPFrom string
|
||||||
MessageLimit int
|
MessageLimit int
|
||||||
MinDelay time.Duration
|
MinDelay time.Duration
|
||||||
MaxDelay time.Duration
|
MaxDelay time.Duration
|
||||||
|
|
|
@ -15,6 +15,7 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/smtp"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -188,6 +189,23 @@ func createFirebaseSubscriber(conf *Config) (subscriber, error) {
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Server) sendMail(to string, m *message) error {
|
||||||
|
host, _, err := net.SplitHostPort(s.config.SMTPAddr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
subject := m.Title
|
||||||
|
if subject == "" {
|
||||||
|
subject = m.Message
|
||||||
|
}
|
||||||
|
msg := []byte(fmt.Sprintf("From: %s\r\n"+
|
||||||
|
"To: %s\r\n"+
|
||||||
|
"Subject: %s\r\n\r\n"+
|
||||||
|
"%s\r\n", s.config.SMTPFrom, to, subject, m.Message))
|
||||||
|
auth := smtp.PlainAuth("", s.config.SMTPUser, s.config.SMTPPass, host)
|
||||||
|
return smtp.SendMail(s.config.SMTPAddr, auth, s.config.SMTPFrom, []string{to}, msg)
|
||||||
|
}
|
||||||
|
|
||||||
// Run executes the main server. It listens on HTTP (+ HTTPS, if configured), and starts
|
// Run executes the main server. It listens on HTTP (+ HTTPS, if configured), and starts
|
||||||
// a manager go routine to print stats and prune messages.
|
// a manager go routine to print stats and prune messages.
|
||||||
func (s *Server) Run() error {
|
func (s *Server) Run() error {
|
||||||
|
@ -307,7 +325,7 @@ func (s *Server) handlePublish(w http.ResponseWriter, r *http.Request, _ *visito
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
m := newDefaultMessage(t.ID, strings.TrimSpace(string(b)))
|
m := newDefaultMessage(t.ID, strings.TrimSpace(string(b)))
|
||||||
cache, firebase, err := s.parseParams(r, m)
|
cache, firebase, email, err := s.parseParams(r, m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -327,6 +345,13 @@ func (s *Server) handlePublish(w http.ResponseWriter, r *http.Request, _ *visito
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
if s.config.SMTPAddr != "" && email != "" && !delayed {
|
||||||
|
go func() {
|
||||||
|
if err := s.sendMail(email, m); err != nil {
|
||||||
|
log.Printf("Unable to send email: %v", err.Error())
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
if cache {
|
if cache {
|
||||||
if err := s.cache.AddMessage(m); err != nil {
|
if err := s.cache.AddMessage(m); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -341,9 +366,10 @@ func (s *Server) handlePublish(w http.ResponseWriter, r *http.Request, _ *visito
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) parseParams(r *http.Request, m *message) (cache bool, firebase bool, err error) {
|
func (s *Server) parseParams(r *http.Request, m *message) (cache bool, firebase bool, email string, err error) {
|
||||||
cache = readParam(r, "x-cache", "cache") != "no"
|
cache = readParam(r, "x-cache", "cache") != "no"
|
||||||
firebase = readParam(r, "x-firebase", "firebase") != "no"
|
firebase = readParam(r, "x-firebase", "firebase") != "no"
|
||||||
|
email = readParam(r, "x-email", "email", "mail", "e")
|
||||||
m.Title = readParam(r, "x-title", "title", "t")
|
m.Title = readParam(r, "x-title", "title", "t")
|
||||||
messageStr := readParam(r, "x-message", "message", "m")
|
messageStr := readParam(r, "x-message", "message", "m")
|
||||||
if messageStr != "" {
|
if messageStr != "" {
|
||||||
|
@ -351,7 +377,7 @@ func (s *Server) parseParams(r *http.Request, m *message) (cache bool, firebase
|
||||||
}
|
}
|
||||||
m.Priority, err = util.ParsePriority(readParam(r, "x-priority", "priority", "prio", "p"))
|
m.Priority, err = util.ParsePriority(readParam(r, "x-priority", "priority", "prio", "p"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, false, errHTTPBadRequest
|
return false, false, "", errHTTPBadRequest
|
||||||
}
|
}
|
||||||
tagsStr := readParam(r, "x-tags", "tags", "tag", "ta")
|
tagsStr := readParam(r, "x-tags", "tags", "tag", "ta")
|
||||||
if tagsStr != "" {
|
if tagsStr != "" {
|
||||||
|
@ -363,19 +389,19 @@ func (s *Server) parseParams(r *http.Request, m *message) (cache bool, firebase
|
||||||
delayStr := readParam(r, "x-delay", "delay", "x-at", "at", "x-in", "in")
|
delayStr := readParam(r, "x-delay", "delay", "x-at", "at", "x-in", "in")
|
||||||
if delayStr != "" {
|
if delayStr != "" {
|
||||||
if !cache {
|
if !cache {
|
||||||
return false, false, errHTTPBadRequest
|
return false, false, "", errHTTPBadRequest
|
||||||
}
|
}
|
||||||
delay, err := util.ParseFutureTime(delayStr, time.Now())
|
delay, err := util.ParseFutureTime(delayStr, time.Now())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, false, errHTTPBadRequest
|
return false, false, "", errHTTPBadRequest
|
||||||
} else if delay.Unix() < time.Now().Add(s.config.MinDelay).Unix() {
|
} else if delay.Unix() < time.Now().Add(s.config.MinDelay).Unix() {
|
||||||
return false, false, errHTTPBadRequest
|
return false, false, "", errHTTPBadRequest
|
||||||
} else if delay.Unix() > time.Now().Add(s.config.MaxDelay).Unix() {
|
} else if delay.Unix() > time.Now().Add(s.config.MaxDelay).Unix() {
|
||||||
return false, false, errHTTPBadRequest
|
return false, false, "", errHTTPBadRequest
|
||||||
}
|
}
|
||||||
m.Time = delay.Unix()
|
m.Time = delay.Unix()
|
||||||
}
|
}
|
||||||
return cache, firebase, nil
|
return cache, firebase, email, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func readParam(r *http.Request, names ...string) string {
|
func readParam(r *http.Request, names ...string) string {
|
||||||
|
@ -714,6 +740,7 @@ func (s *Server) sendDelayedMessages() error {
|
||||||
log.Printf("unable to publish to Firebase: %v", err.Error())
|
log.Printf("unable to publish to Firebase: %v", err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// FIXME delayed email
|
||||||
}
|
}
|
||||||
if err := s.cache.MarkPublished(m); err != nil {
|
if err := s.cache.MarkPublished(m); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -138,3 +138,8 @@ func ParsePriority(priority string) (int, error) {
|
||||||
func ExpandHome(path string) string {
|
func ExpandHome(path string) string {
|
||||||
return os.ExpandEnv(strings.ReplaceAll(path, "~", "$HOME"))
|
return os.ExpandEnv(strings.ReplaceAll(path, "~", "$HOME"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ShortTopicURL shortens the topic URL to be human-friendly, removing the http:// or https://
|
||||||
|
func ShortTopicURL(s string) string {
|
||||||
|
return strings.TrimPrefix(strings.TrimPrefix(s, "https://"), "http://")
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue