~gjabell/mfn

5b4281288c36ba37209226e9be469f05e18bc34c — Galen Abell 1 year, 1 month ago d0ec1c9
Add Gotify notifier
3 files changed, 118 insertions(+), 9 deletions(-)

M config.go
A gotify.go
M main.go
M config.go => config.go +52 -9
@@ 7,6 7,10 @@ import (
	"github.com/BurntSushi/toml"
)

type validator interface {
	validate() error
}

type EmailConfig struct {
	SubjectTemplate    *template.Template `toml:"-"`
	SubjectTemplateStr string             `toml:"subject_template"`


@@ 50,6 54,44 @@ func (c *EmailConfig) validate() error {
	return nil
}

type GotifyConfig struct {
	TitleTemplate      *template.Template `toml:"-"`
	TitleTemplateStr   string             `toml:"title_template"`
	MessageTemplate    *template.Template `toml:"-"`
	MessageTemplateStr string             `toml:"message_template"`
	Server             string             `toml:"server"`
	Token              string             `toml:"token"`
	Priority           int                `toml:"priority"`
}

func (c *GotifyConfig) validate() error {
	for k, v := range map[string]string{
		"title template":   c.TitleTemplateStr,
		"message template": c.MessageTemplateStr,
		"server":           c.Server,
		"token":            c.Token,
	} {
		if v == "" {
			return fmt.Errorf("you must provide a valid %s", k)
		}
	}

	// parse the templates
	titleTmpl, err := template.New("title_template").Parse(c.TitleTemplateStr)
	if err != nil {
		return err
	}
	c.TitleTemplate = titleTmpl

	messageTmpl, err := template.New("message_template").Parse(c.MessageTemplateStr)
	if err != nil {
		return err
	}
	c.MessageTemplate = messageTmpl

	return nil
}

type WebhookConfig struct {
	Template    *template.Template `toml:"-"`
	TemplateStr string             `toml:"template"`


@@ 83,6 125,7 @@ type Config struct {
	DbPath   string `toml:"db_path"`

	EmailConfig   *EmailConfig   `toml:"email"`
	GotifyConfig  *GotifyConfig  `toml:"gotify"`
	WebhookConfig *WebhookConfig `toml:"webhook"`
}



@@ 112,15 155,15 @@ func (c *Config) validate() error {
		}
	}

	if c.EmailConfig != nil {
		if err := c.EmailConfig.validate(); err != nil {
			return fmt.Errorf("invalid email config: %s", err)
		}
	}

	if c.WebhookConfig != nil {
		if err := c.WebhookConfig.validate(); err != nil {
			return fmt.Errorf("invalid webhook config: %s", err)
	for k, v := range map[string]validator{
		"email":   c.EmailConfig,
		"gotify":  c.GotifyConfig,
		"webhook": c.WebhookConfig,
	} {
		if v != nil {
			if err := v.validate(); err != nil {
				return fmt.Errorf("invalid %s config: %s", k, err)
			}
		}
	}


A gotify.go => gotify.go +63 -0
@@ 0,0 1,63 @@
package main

import (
	"bytes"
	"html/template"
	"net/http"
	"net/url"
	"strconv"

	mf "miniflux.app/client"
)

type Gotify struct {
	titleTemplate   *template.Template
	messageTemplate *template.Template
	server          string
	token           string
	priority        int
}

func NewGotify(conf *Config) *Gotify {
	gc := conf.GotifyConfig

	return &Gotify{
		titleTemplate:   gc.TitleTemplate,
		messageTemplate: gc.MessageTemplate,
		server:          gc.Server,
		token:           gc.Token,
		priority:        gc.Priority,
	}
}

func (g *Gotify) Notify(entry *mf.Entry) error {
	var title, message bytes.Buffer
	if err := g.titleTemplate.Execute(&title, entry); err != nil {
		return err
	}

	if err := g.messageTemplate.Execute(&message, entry); err != nil {
		return err
	}

	u, err := url.Parse(g.server)
	if err != nil {
		return err
	}

	q := u.Query()
	q.Set("token", g.token)

	u.Path = u.Path + "message"
	u.RawQuery = q.Encode()

	if _, err := http.PostForm(u.String(), url.Values{
		"title":    {title.String()},
		"message":  {message.String()},
		"priority": {strconv.Itoa(g.priority)},
	}); err != nil {
		return err
	}

	return nil
}

M main.go => main.go +3 -0
@@ 82,6 82,9 @@ func main() {
	if conf.EmailConfig != nil {
		notifiers["email"] = NewEmail(conf)
	}
	if conf.GotifyConfig != nil {
		notifiers["gotify"] = NewGotify(conf)
	}
	if conf.WebhookConfig != nil {
		notifiers["webhook"] = NewWebhook(conf)
	}