Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(telegram): add support for chat topics #1125

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions docs/notif/telegram.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ Multiple chat IDs can be provided in order to deliver notifications to multiple
| `tokenFile` | | Use content of secret file as Telegram bot token if `token` not defined |
| `chatIDs` | | List of chat IDs to send notifications to |
| `chatIDsFile` | | Use content of secret file as chat IDs if `chatIDs` not defined |
| `chatTopics` | | List of chat topic IDs to send notifications to. |
| `chatTopicsFile` | | Use content of secret file as chat topic IDs if `chatTopics` not defined |
| `templateBody`[^1] | See [below](#default-templatebody) | [Notification template](../faq.md#notification-template) for message body |

!!! abstract "Environment variables"
Expand All @@ -39,6 +41,9 @@ Multiple chat IDs can be provided in order to deliver notifications to multiple
!!! example "chat IDs secret file"
Chat IDs secret file must be a valid JSON array like: `[123456789,987654321]`

!!! example "chat topic IDS secret file"
Chat topics is also an array, so you can specify a topic ID per chat ID: `[10,20]`

### Default `templateBody`

```
Expand Down
12 changes: 7 additions & 5 deletions internal/model/notif_telegram.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ const NotifTelegramDefaultTemplateBody = `Docker tag {{ if .Entry.Image.HubLink

// NotifTelegram holds Telegram notification configuration details
type NotifTelegram struct {
Token string `yaml:"token,omitempty" json:"token,omitempty" validate:"omitempty"`
TokenFile string `yaml:"tokenFile,omitempty" json:"tokenFile,omitempty" validate:"omitempty,file"`
ChatIDs []int64 `yaml:"chatIDs,omitempty" json:"chatIDs,omitempty" validate:"omitempty"`
ChatIDsFile string `yaml:"chatIDsFile,omitempty" json:"chatIDsFile,omitempty" validate:"omitempty,file"`
TemplateBody string `yaml:"templateBody,omitempty" json:"templateBody,omitempty" validate:"required"`
Token string `yaml:"token,omitempty" json:"token,omitempty" validate:"omitempty"`
TokenFile string `yaml:"tokenFile,omitempty" json:"tokenFile,omitempty" validate:"omitempty,file"`
ChatIDs []int64 `yaml:"chatIDs,omitempty" json:"chatIDs,omitempty" validate:"omitempty"`
ChatIDsFile string `yaml:"chatIDsFile,omitempty" json:"chatIDsFile,omitempty" validate:"omitempty,file"`
ChatTopics map[string][]int64 `yaml:"chatTopics,omitempty" json:"chatTopics,omitempty" validate:"omitempty"`
ChatTopicsFile string `yaml:"chatTopicsFile,omitempty" json:"chatTopicsFile,omitempty" validate:"omitempty,file"`
TemplateBody string `yaml:"templateBody,omitempty" json:"templateBody,omitempty" validate:"required"`
}

// GetDefaults gets the default values
Expand Down
39 changes: 33 additions & 6 deletions internal/notif/telegram/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package telegram

import (
"encoding/json"
"fmt"
"net/http"
"strings"
"text/template"
Expand Down Expand Up @@ -54,6 +55,17 @@ func (c *Client) Send(entry model.NotifEntry) error {
}
}

chatTopics := c.cfg.ChatTopics
chatTopicsRaw, err := utl.GetSecret("", c.cfg.ChatTopicsFile)
if err != nil {
return errors.Wrap(err, "cannot retrieve chat topics secret for Telegram notifier")
}
if len(chatTopicsRaw) > 0 {
if err = json.Unmarshal([]byte(chatTopicsRaw), &chatTopics); err != nil {
return errors.Wrap(err, "cannot unmarshal chat topics secret for Telegram notifier")
}
}

bot, err := gotgbot.NewBot(token, &gotgbot.BotOpts{
BotClient: &gotgbot.BaseBotClient{
Client: http.Client{},
Expand Down Expand Up @@ -91,14 +103,29 @@ func (c *Client) Send(entry model.NotifEntry) error {
}

for _, chatID := range chatIDs {
_, err := bot.SendMessage(chatID, string(body), &gotgbot.SendMessageOpts{
ParseMode: gotgbot.ParseModeMarkdown,
LinkPreviewOptions: &gotgbot.LinkPreviewOptions{IsDisabled: true},
})
if err != nil {
return err
if topics, ok := chatTopics[fmt.Sprintf("%d", chatID)]; ok {
for _, topic := range topics {
err = sendTelegramMessage(bot, chatID, topic, string(body))
if err != nil {
return err
}
}
} else {
err = sendTelegramMessage(bot, chatID, 0, string(body))
if err != nil {
return err
}
}
}

return nil
}

func sendTelegramMessage(bot *gotgbot.Bot, chatID int64, threadID int64, message string) error {
_, err := bot.SendMessage(chatID, message, &gotgbot.SendMessageOpts{
MessageThreadId: threadID,
ParseMode: gotgbot.ParseModeMarkdown,
LinkPreviewOptions: &gotgbot.LinkPreviewOptions{IsDisabled: true},
})
return err
}