notify

package module
v1.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 27, 2024 License: MIT Imports: 20 Imported by: 11

README

Notify

Build Status Coverage Status Go Reference

This library provides ability to send notifications using multiple services:

  • Email
  • Telegram
  • Slack
  • Webhook

Install

go get -u github.com/go-pkgz/notify

Usage

All supported notification methods could adhere to the following interface. Example on how to use it:

package main

import (
	"context"
	"fmt"

	"github.com/go-pkgz/notify"
)

func main() {
	// create notifiers
	notifiers := []notify.Notifier{
		notify.NewWebhook(notify.WebhookParams{}),
		notify.NewEmail(notify.SMTPParams{}),
		notify.NewSlack("token"),
	}
	tg, err := notify.NewTelegram(notify.TelegramParams{Token: "token"})
	if err == nil {
		notifiers = append(notifiers, tg)
	}
	err = notify.Send(context.Background(), notifiers, "https://example.com/webhook", "Hello, world!")
	if err != nil {
		fmt.Printf("Sent message error: %s", err))
	}
}
Email

mailto: scheme is supported. Only subject and from query params are used.

Examples:

  • mailto:"John Wayne"<john@example.org>?subject=test-subj&from="Notifier"<notify@example.org>
  • mailto:addr1@example.org,addr2@example.org?&subject=test-subj&from=notify@example.org
package main

import (
	"context"
	"log"
	"time"

	"github.com/go-pkgz/notify"
)

func main() {
	wh := notify.NewEmail(notify.SMTPParams{
		Host:        "localhost", // the only required field, others are optional
		Port:        25,
		TLS:         false, // TLS, but not STARTTLS
		ContentType: "text/html",
		Charset:     "UTF-8",
		Username:    "username",
		Password:    "password",
		TimeOut:     time.Second * 10, // default is 30 seconds
	})
	err := wh.Send(
		context.Background(),
		`mailto:"John Wayne"<john@example.org>?subject=test-subj&from="Notifier"<notify@example.org>`,
		"Hello, World!",
	)
	if err != nil {
		log.Fatalf("problem sending message using email, %v", err)
	}
}
Telegram

telegram: scheme akin to mailto: is supported. Query params parseMode (doc, legacy Markdown by default, preferable use MarkdownV2 or HTML instead). Examples:

  • telegram:channel
  • telegram:channelID // channel ID is a number, like -1001480738202: use that instruction to obtain it
  • telegram:userID

Here is an instruction on obtaining token for your notification bot.

package main

import (
	"context"
	"log"
	"time"

	"github.com/go-pkgz/notify"
)

func main() {
	tg, err := notify.NewTelegram(notify.TelegramParams{
		Token:      "token",          // required
		Timeout:    time.Second * 10, // default is 5 seconds
		SuccessMsg: "Success",        // optional, for auth, set by default
		ErrorMsg:   "Error",          // optional, for auth, unset by default
	})
	if err != nil {
		log.Fatalf("problem creating telegram notifier, %v", err)
	}
	err = tg.Send(context.Background(), "telegram:-1001480738202", "Hello, World!")
	if err != nil {
		log.Fatalf("problem sending message using telegram, %v", err)
	}
}
HTML Formatting

parseMode HTML supports limited set of tags, so Telegram provides TelegramSupportedHTML method which strips all unsupported tags and replaces h1-h3 with <b> and h4-h6 with <i><b> to preserve formatting.

If you want to post text into HTML tag like text, you can use EscapeTelegramText method to escape it (by replacing symbols &, <, > with &amp;, &lt;, &gt;).

Authorisation

You can use Telegram notifications as described above, just to send messages. But also, you can use Telegram to authorise users as a login method or to sign them up for notifications. Functions used for processing updates from users are GetBotUsername, AddToken, CheckToken, Request, and Run or ProcessUpdate (only one of two can be used at a time).

Normal flow is following:

  1. you run the Run goroutine
  2. call AddToken and provide user with that token
  3. user clicks on the link https://t.me/<BOT_USERNAME>/?start=<TOKEN>
  4. you call CheckToken to verify that the user clicked the link, and if so you will receive user's UserID

Alternative flow is the same, but instead of running the Run goroutine, you set up process update flow separately (to use with auth as well, for example) and run ProcessUpdate when update is received. Example of such a setup can be seen in Remark42.

Slack

slack: scheme akin to mailto: is supported. title, titleLink, attachmentText and query params are used: if they are defined, message would be sent with a text attachment. Examples:

  • slack:channel
  • slack:channelID
  • slack:userID
  • slack:channel?title=title&attachmentText=test%20text&titleLink=https://example.org
package main

import (
	"context"
	"log"

	"github.com/go-pkgz/notify"
	"github.com/slack-go/slack"
)

func main() {
	wh := notify.NewSlack(
		"token",
		slack.OptionDebug(true), // optional, you can pass any slack.Options
	)
	err := wh.Send(context.Background(), "slack:general", "Hello, World!")
	if err != nil {
		log.Fatalf("problem sending message using slack, %v", err)
	}
}
Webhook

http:// and https:// schemas are supported.

package main

import (
	"context"
	"log"
	"time"

	"github.com/go-pkgz/notify"
)

func main() {
	wh := notify.NewWebhook(notify.WebhookParams{
		Timeout: time.Second,                                          // optional, default is 5 seconds
		Headers: []string{"Content-Type:application/json,text/plain"}, // optional
	})
	err := wh.Send(context.Background(), "https://example.org/webhook", "Hello, World!")
	if err != nil {
		log.Fatalf("problem sending message using webhook, %v", err)
	}
}

Status

The library extracted from remark42 project. The original code in production use on multiple sites and seems to work fine.

go-pkgz/notify library still in development and until version 1 released some breaking changes possible.

Documentation

Overview

Package notify provides notification functionality.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func EscapeTelegramText

func EscapeTelegramText(text string) string

EscapeTelegramText returns text sanitized of symbols not allowed inside other HTML tags in Telegram HTML message payload

https://core.telegram.org/bots/api#html-style

func Send

func Send(ctx context.Context, notifiers []Notifier, destination, text string) error

Send sends message to provided destination, picking the right one based on destination schema

func TelegramSupportedHTML

func TelegramSupportedHTML(htmlText string) string

TelegramSupportedHTML returns HTML with only tags allowed in Telegram HTML message payload, also trims ending newlines

https://core.telegram.org/bots/api#html-style, https://core.telegram.org/api/entities#allowed-entities

Types

type Email

type Email struct {
	SMTPParams
	// contains filtered or unexported fields
}

Email notifications client

func NewEmail

func NewEmail(smtpParams SMTPParams) *Email

NewEmail makes new Email object

func (*Email) Schema

func (e *Email) Schema() string

Schema returns schema prefix supported by this client

func (*Email) Send

func (e *Email) Send(ctx context.Context, destination, text string) error

Send sends the message over Email, with "from", "subject" and "unsubscribeLink" parsed from destination field with "mailto:" schema. "unsubscribeLink" passed as a header, https://support.google.com/mail/answer/81126 -> "Use one-click unsubscribe"

Example:

- mailto:"John Wayne"<john@example.org>?subject=test-subj&from="Notifier"<notify@example.org> - mailto:addr1@example.org,addr2@example.org?subject=test-subj&from=notify@example.org&unsubscribeLink=http://example.org/unsubscribe

func (*Email) String

func (e *Email) String() string

String representation of Email object

type Notifier

type Notifier interface {
	fmt.Stringer
	Schema() string                                           // returns schema prefix supported by this client
	Send(ctx context.Context, destination, text string) error // sends message to provided destination
}

Notifier defines common interface among all notifiers

type SMTPParams

type SMTPParams struct {
	Host               string        // SMTP host
	Port               int           // SMTP port
	TLS                bool          // TLS auth
	StartTLS           bool          // StartTLS auth
	InsecureSkipVerify bool          // skip certificate verification
	ContentType        string        // Content type
	Charset            string        // Character set
	LoginAuth          bool          // LOGIN auth method instead of default PLAIN, needed for Office 365 and outlook.com
	Username           string        // username
	Password           string        // password
	TimeOut            time.Duration // TCP connection timeout
}

SMTPParams contain settings for smtp server connection

type Slack

type Slack struct {
	// contains filtered or unexported fields
}

Slack notifications client

func NewSlack

func NewSlack(token string, opts ...slack.Option) *Slack

NewSlack makes Slack client for notifications

func (*Slack) Schema

func (s *Slack) Schema() string

Schema returns schema prefix supported by this client

func (*Slack) Send

func (s *Slack) Send(ctx context.Context, destination, text string) error

Send sends the message over Slack, with "title", "titleLink" and "attachmentText" parsed from destination field with "slack:" schema same way "mailto:" schema is constructed.

Example:

- slack:channelName - slack:channelID - slack:userID - slack:channel?title=title&attachmentText=test%20text&titleLink=https://example.org

func (*Slack) String

func (s *Slack) String() string

type Telegram

type Telegram struct {
	TelegramParams
	// contains filtered or unexported fields
}

Telegram notifications client

func NewTelegram

func NewTelegram(params TelegramParams) (*Telegram, error)

NewTelegram makes telegram bot for notifications

func (*Telegram) AddToken

func (t *Telegram) AddToken(token, user, site string, expires time.Time)

AddToken adds token

func (*Telegram) CheckToken

func (t *Telegram) CheckToken(token, user string) (telegram, site string, err error)

CheckToken verifies incoming token, returns the user address if it's confirmed and empty string otherwise

func (*Telegram) GetBotUsername

func (t *Telegram) GetBotUsername() string

GetBotUsername returns bot username

func (*Telegram) ProcessUpdate

func (t *Telegram) ProcessUpdate(ctx context.Context, textUpdate string) error

ProcessUpdate is alternative to Run, it processes provided plain text update from Telegram so that caller could get updates and send it not only there but to multiple sources

func (*Telegram) Request

func (t *Telegram) Request(ctx context.Context, method string, b []byte, data interface{}) error

Request makes a request to the Telegram API and return the result

func (*Telegram) Run

func (t *Telegram) Run(ctx context.Context)

Run starts processing login requests sent in Telegram, required for user notifications to work Blocks caller

func (*Telegram) Schema

func (t *Telegram) Schema() string

Schema returns schema prefix supported by this client

func (*Telegram) Send

func (t *Telegram) Send(ctx context.Context, destination, text string) error

Send sends provided message to Telegram chat, with `parseMode` parsed from destination field (Markdown by default) with "telegram:" schema same way "mailto:" schema is constructed.

Example:

- telegram:channel - telegram:chatID // chatID is a number, like `-1001480738202` - telegram:channel?parseMode=HTML

func (*Telegram) String

func (t *Telegram) String() string

type TelegramBotInfo

type TelegramBotInfo struct {
	Username string `json:"username"`
}

TelegramBotInfo structure contains information about telegram bot, which is used from whole telegram API response

type TelegramParams

type TelegramParams struct {
	Token                string        // token for telegram bot API interactions
	Timeout              time.Duration // http client timeout
	ErrorMsg, SuccessMsg string        // messages for successful and unsuccessful subscription requests to bot
	// contains filtered or unexported fields
}

TelegramParams contain settings for telegram notifications

type TelegramUpdate

type TelegramUpdate struct {
	Result []struct {
		UpdateID int `json:"update_id"`
		Message  struct {
			Chat struct {
				ID   int    `json:"id"`
				Name string `json:"first_name"`
				Type string `json:"type"`
			} `json:"chat"`
			Text string `json:"text"`
		} `json:"message"`
	} `json:"result"`
}

TelegramUpdate contains update information, which is used from whole telegram API response

type Webhook

type Webhook struct {
	WebhookParams
	// contains filtered or unexported fields
}

Webhook notifications client

func NewWebhook

func NewWebhook(params WebhookParams) *Webhook

NewWebhook makes Webhook

func (*Webhook) Schema

func (wh *Webhook) Schema() string

Schema returns schema prefix supported by this client

func (*Webhook) Send

func (wh *Webhook) Send(ctx context.Context, destination, text string) error

Send sends Webhook notification. Destination field is expected to have http:// or https:// schema.

Example:

- https://example.com/webhook

func (*Webhook) String

func (wh *Webhook) String() string

String describes the webhook instance

type WebhookParams

type WebhookParams struct {
	Timeout time.Duration
	Headers []string // headers in format "header:value"
}

WebhookParams contain settings for webhook notifications

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL