Skip to content

Commit

Permalink
Notification message template (#3)
Browse files Browse the repository at this point in the history
* Added: templates for messages

* Updated: docs
  • Loading branch information
capcom6 authored Jul 14, 2023
1 parent 356e5d4 commit 2876839
Show file tree
Hide file tree
Showing 7 changed files with 130 additions and 8 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## v1.0.2

### Added
- messages templates

## v1.0.1

### Added
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ services:
## Roadmap
- [x] Add Changelog
- [ ] Add the ability to change the text of messages
- [x] Add the ability to change the text of messages
- [ ] Send notifications to multiple channels/groups
- [ ] Display event time in notifications
- [ ] Online/offline time count
Expand Down
3 changes: 3 additions & 0 deletions configs/config.example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ telegram:
token: # токен бота
chatId: -1234567890123 # ИД чата для уведомлений
webhookUrl: # TODO: URL для получения веб-хуков, если не задан, то используется long-poll
messages:
online: "✅ {{.Name}} is *online*" # текст сообщения при переходе сервиса в состояние "в сети"
offline: "❌ {{.Name}} is *offline*: {{.Error}}" # текст сообщения при переходе сервиса в состояние "не в сети"
services: # список сервисов для мониторинга
- name: Google # наименование для уведомления
initialDelaySeconds: 5 # пауза перед первым опросом в секундах, по умолчанию: 0; если меньше 0, то используется случайное значение между 0 и `periodSeconds`
Expand Down
21 changes: 19 additions & 2 deletions internal/bot/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ func Run() error {
cfg := config.GetConfig()
ctx, _ := signal.NotifyContext(context.Background(), os.Interrupt)

messages := NewMessages(cfg.Telegram.Messages)
tg := infrastructure.NewTelegramBot(cfg.Telegram)
tgapi, err := tg.Api()
if err != nil {
Expand All @@ -40,9 +41,25 @@ func Run() error {
msg := tgbotapi.NewMessage(cfg.Telegram.ChatID, "")
msg.ParseMode = tgbotapi.ModeMarkdownV2
if v.State == monitor.ServiceOffline {
msg.Text = "❌ " + tgbotapi.EscapeText(msg.ParseMode, v.Name) + " is *offline*: " + tgbotapi.EscapeText(msg.ParseMode, v.Error.Error())
// msg.Text = "❌ " + tgbotapi.EscapeText(msg.ParseMode, v.Name) + " is *offline*: " + tgbotapi.EscapeText(msg.ParseMode, v.Error.Error())
context := OfflineContext{
OnlineContext: OnlineContext{
Name: tgbotapi.EscapeText(msg.ParseMode, v.Name),
},
Error: tgbotapi.EscapeText(msg.ParseMode, v.Error.Error()),
}
msg.Text, err = messages.Render(TemplateOffline, context)
} else {
msg.Text = "✅ " + tgbotapi.EscapeText(msg.ParseMode, v.Name) + " is *online*"
// msg.Text = "✅ " + tgbotapi.EscapeText(msg.ParseMode, v.Name) + " is *online*"
context := OnlineContext{
Name: tgbotapi.EscapeText(msg.ParseMode, v.Name),
}
msg.Text, err = messages.Render(TemplateOnline, context)
}

if err != nil {
errorLog.Println(err)
continue
}

if _, err := tgapi.Send(msg); err != nil {
Expand Down
73 changes: 73 additions & 0 deletions internal/bot/messages.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package bot

import (
"fmt"
"strings"
"sync"
"text/template"

"github.com/capcom6/service-monitor-tgbot/internal/config"
)

type TemplateName string

const (
TemplateOnline TemplateName = "online"
TemplateOffline TemplateName = "offline"
)

type Messages struct {
Templates config.TelegramMessages
cachedTemplates map[TemplateName]*template.Template
mux sync.Mutex
}

type OnlineContext struct {
Name string
}

type OfflineContext struct {
OnlineContext
Error string
}

func NewMessages(templates config.TelegramMessages) *Messages {
return &Messages{
Templates: templates,
cachedTemplates: make(map[TemplateName]*template.Template),
}
}

func (m *Messages) prepare(name TemplateName) (prepared *template.Template, err error) {
m.mux.Lock()
defer m.mux.Unlock()

if prepared = m.cachedTemplates[name]; prepared != nil {
return prepared, nil
}

var tmplString string
var ok bool
if tmplString, ok = m.Templates[string(name)]; !ok {
return nil, fmt.Errorf("template %s not found", name)
}

if m.cachedTemplates[name], err = template.New(string(name)).Parse(tmplString); err != nil {
return nil, fmt.Errorf("can't parse template %s: %w", name, err)
}

return m.cachedTemplates[name], nil
}

func (m *Messages) Render(name TemplateName, context any) (string, error) {
tmpl, err := m.prepare(name)
if err != nil {
return "", err
}

builder := strings.Builder{}
if err := tmpl.Execute(&builder, context); err != nil {
return "", err
}
return builder.String(), nil
}
14 changes: 9 additions & 5 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,13 @@ type Config struct {
Storage Storage `yaml:"storage"`
}
type Telegram struct {
Token string `yaml:"token" envconfig:"TELEGRAM__TOKEN" validate:"required"`
ChatID int64 `yaml:"chatId" envconfig:"TELEGRAM__CHAT_ID"`
WebhookURL string `yaml:"webhookUrl" envconfig:"TELEGRAM__WEBHOOK_URL" validate:"required"`
Debug bool `yaml:"debug" envconfig:"TELEGRAM__DEBUG"`
Token string `yaml:"token" envconfig:"TELEGRAM__TOKEN" validate:"required"`
ChatID int64 `yaml:"chatId" envconfig:"TELEGRAM__CHAT_ID"`
WebhookURL string `yaml:"webhookUrl" envconfig:"TELEGRAM__WEBHOOK_URL" validate:"required"`
Debug bool `yaml:"debug" envconfig:"TELEGRAM__DEBUG"`
Messages TelegramMessages `yaml:"messages"`
}
type TelegramMessages map[string]string
type HTTPHeader struct {
Name string `yaml:"name"`
Value string `yaml:"value"`
Expand Down Expand Up @@ -170,7 +172,7 @@ func loadConfig() Config {
path = "config.yml"
}

config := Config{}
config := defaultConfig

if err := fromYaml(path, &config); err != nil {
errorLog.Printf("couldn'n load config from %s: %s\r\n", path, err.Error())
Expand Down Expand Up @@ -205,5 +207,7 @@ func GetConfig() Config {
instance = loadConfig()
})

log.Printf("config: %+v", instance)

return instance
}
20 changes: 20 additions & 0 deletions internal/config/defaults.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package config

var (
defaultTelegramMessages TelegramMessages = TelegramMessages{
"online": "✅ {{.Name}} is *online*",
"offline": "❌ {{.Name}} is *offline*: {{.Error}}",
}

defaultConfig Config = Config{
Telegram: Telegram{
Token: "",
ChatID: 0,
WebhookURL: "",
Debug: false,
Messages: defaultTelegramMessages,
},
Services: []Service{},
Storage: Storage{},
}
)

0 comments on commit 2876839

Please sign in to comment.