1
0
mirror of https://github.com/nikoksr/notify.git synced 2025-02-03 13:01:26 +02:00

refactor(lib): comment and clean up code

This commit is contained in:
Niko Köser 2021-01-25 05:05:28 +01:00
parent 8daf2e3a9d
commit b9c0efe21f
No known key found for this signature in database
GPG Key ID: F3F28C118DAA6375
7 changed files with 78 additions and 87 deletions

View File

@ -4,31 +4,32 @@ import (
"github.com/pkg/errors"
)
type Notifier struct {
Disabled bool
services []Service
const defaultDisabled = false // Notifier is enabled by default
// Notify is the central struct for managing notification services and sending messages to them.
type Notify struct {
Disabled bool
notifiers []Notifier
}
const defaultDisabled = false
// ErrSendNotification signals that the notifier failed to send a notification.
var ErrSendNotification = errors.New("Send notification")
// Service implements a Listen and a Send method. The Listen method makes the notification Service listens
// for external commands and will answer to these commands if supported. For example, our telegram Notifier listens for
// commands like /info and will answer with basic information about the server. The Send command simply sends a
// message string to the internal destination Service. E.g for telegram it sends the message to the specified group
// chat.
type Service interface {
// Notifier defines the behavior for notification services. The Send command simply sends a message string to the
// internal destination Notifier. E.g for telegram it sends the message to the specified group chat.
type Notifier interface {
Send(string, string) error
}
func New() *Notifier {
notifier := &Notifier{
// New returns a new instance of Notify. Defaulting to being not disabled and using the pseudo notification
// service under the hood.
func New() *Notify {
notifier := &Notify{
Disabled: defaultDisabled,
}
// Use the pseudo Service to prevent from nil reference bugs when using the Notifier Service. In case no services
// are provided or the creation of all other services failed, the pseudo Service will be used under the hood
// Use the pseudo Notifier to prevent from nil reference bugs when using the Notify Notifier. In case no notifiers
// are provided or the creation of all other notifiers failed, the pseudo Notifier will be used under the hood
// doing nothing but preventing nil-reference errors.
notifier.usePseudo()

View File

@ -5,14 +5,15 @@ import (
"golang.org/x/sync/errgroup"
)
func (n Notifier) Send(subject, message string) error {
// Send calls the underlying notification services to send the given message to their respective endpoints.
func (n Notify) Send(subject, message string) error {
if n.Disabled {
return nil
}
var eg errgroup.Group
for _, service := range n.services {
for _, service := range n.notifiers {
if service != nil {
s := service
eg.Go(func() error {

View File

@ -5,11 +5,13 @@ import (
"github.com/pkg/errors"
)
// Discord struct holds necessary data to communicate with the Discord API.
type Discord struct {
client *discordgo.Session
channelIDs []string
}
// New takes a Discord API token and returns a new instance of a Discord notification service.
func New(apiToken string) (*Discord, error) {
client, err := discordgo.New("Bot " + apiToken)
if err != nil {
@ -24,10 +26,13 @@ func New(apiToken string) (*Discord, error) {
return d, nil
}
// AddReceivers takes Telegram channel IDs and adds them to the internal channel ID list. The Send method will send
// a given message to all those channels.
func (d *Discord) AddReceivers(channelIDs ...string) {
d.channelIDs = append(d.channelIDs, channelIDs...)
}
// Send takes a message subject and a message body and sends them to all previously set chats.
func (d Discord) Send(subject, message string) error {
fullMessage := subject + "\n" + message // Treating subject as message title

View File

@ -1,55 +1,57 @@
package mail
import (
"net/smtp"
"net/textproto"
"github.com/jordan-wright/email"
"github.com/pkg/errors"
gomail "gopkg.in/mail.v2"
)
const (
headerFrom = "From"
headerTo = "To"
headerSubject = "Subject"
bodyContentType = "text/plain"
)
// Mail struct holds necessary data to send emails.
type Mail struct {
client *gomail.Dialer
senderAddress string
smtpHostAddr string
smtpAuth smtp.Auth
receiverAddresses []string
}
func New(host, userName, password string, port int) (*Mail, error) {
client := gomail.NewDialer(host, port, userName, password)
m := &Mail{
client: client,
// New returns a new instance of a Mail notification service.
func New(senderAddress, smtpHostAddress string) *Mail {
return &Mail{
senderAddress: senderAddress,
smtpHostAddr: smtpHostAddress,
receiverAddresses: []string{},
}
return m, nil
}
// AuthenticateSMTP authenticates you to send emails via smtp.
// Example values: "", "test@gmail.com", "password123", "smtp.gmail.com"
func (m *Mail) AuthenticateSMTP(identity, userName, password, host string) {
m.smtpAuth = smtp.PlainAuth(identity, userName, password, host)
}
// AddReceivers takes email addresses and adds them to the internal address list. The Send method will send
// a given message to all those addresses.
func (m *Mail) AddReceivers(addresses ...string) {
m.receiverAddresses = append(m.receiverAddresses, addresses...)
}
// Send takes a message subject and a message body and sends them to all previously set chats. Message body supports
// html as markup language.
func (m Mail) Send(subject, message string) error {
msg := gomail.NewMessage()
msg := &email.Email{
To: m.receiverAddresses,
From: m.senderAddress,
Subject: subject,
// Text: []byte("Text Body is, of course, supported!"),
HTML: []byte(message),
Headers: textproto.MIMEHeader{},
}
// Set E-Mail sender
msg.SetHeader(headerFrom, m.client.Host)
// Set E-Mail receivers
msg.SetHeader(headerTo, m.receiverAddresses...)
// Set E-Mail subject
msg.SetHeader(headerSubject, subject)
// Set E-Mail body
msg.SetBody(bodyContentType, message)
err := m.client.DialAndSend(msg)
err := msg.Send(m.smtpHostAddr, m.smtpAuth)
if err != nil {
err = errors.Wrap(err, "failed to dial and send mail")
err = errors.Wrap(err, "failed to send mail")
}
return err

View File

@ -2,10 +2,13 @@ package pseudo
type Pseudo struct{}
// New returns a new instance of a Pseudo notification service. This is used internally to initialize
// notification services list and prevent nil-reference errors.
func New() *Pseudo {
return &Pseudo{}
}
// Send basically does nothing. Just here to conform the notify.Notifier interface.
func (Pseudo) Send(string, string) error {
return nil
}

View File

@ -5,16 +5,16 @@ import (
"github.com/pkg/errors"
)
const (
defaultParseMode = tgbotapi.ModeHTML
)
const defaultParseMode = tgbotapi.ModeHTML
// Telegram struct holds necessary data to communicate with the Telegram API.
type Telegram struct {
client *tgbotapi.BotAPI
listener *tgbotapi.BotAPI
chatIDs []int64
}
// New returns a new instance of a Telegram notification service.
func New(apiToken string) (*Telegram, error) {
client, err := tgbotapi.NewBotAPI(apiToken)
if err != nil {
@ -29,10 +29,14 @@ func New(apiToken string) (*Telegram, error) {
return t, nil
}
// AddReceivers takes Telegram chat IDs and adds them to the internal chat ID list. The Send method will send
// a given message to all those chats.
func (t *Telegram) AddReceivers(chatIDs ...int64) {
t.chatIDs = append(t.chatIDs, chatIDs...)
}
// Send takes a message subject and a message body and sends them to all previously set chats. Message body supports
// html as markup language.
func (t Telegram) Send(subject, message string) error {
fullMessage := subject + "\n" + message // Treating subject as message title

47
use.go
View File

@ -4,55 +4,30 @@ import (
"github.com/nikoksr/notify/service/pseudo"
)
func (n *Notifier) useService(service Service) {
// useService adds a given service to the notifiers services list. If the list still contains
// a pseudo service we remove it before adding the 'real' service.
func (n *Notify) useService(service Notifier) {
if service == nil {
return
}
// Remove pseudo service in case a 'real' service will be added
if len(n.services) > 0 {
_, isPseudo := n.services[0].(*pseudo.Pseudo)
if len(n.notifiers) > 0 {
_, isPseudo := n.notifiers[0].(*pseudo.Pseudo)
if isPseudo {
n.services = n.services[1:]
n.notifiers = n.notifiers[1:]
}
}
n.services = append(n.services, service)
n.notifiers = append(n.notifiers, service)
}
// usePseudo adds a pseudo Service to the Service list.
func (n *Notifier) usePseudo() {
// usePseudo adds a pseudo notification service to the notifiers services list.
func (n *Notify) usePseudo() {
n.useService(pseudo.New())
}
func (n *Notifier) UseService(service Service) {
// UseService adds a given service to the notifiers services list.
func (n *Notify) UseService(service Notifier) {
n.useService(service)
}
/*
func (n *Notifier) UseTelegram(apiToken string, chatID int64) error {
telegramService, err := telegram.New(apiToken)
if err != nil {
return err
}
telegramService.AddReceivers(chatID)
n.useService(telegramService)
return nil
}
func (n *Notifier) UseDiscordService(apiToken, channelID string) error {
discordService, err := discord.New(apiToken)
if err != nil {
return err
}
discordService.AddReceivers(channelID)
n.useService(discordService)
return nil
}
*/