add user telegram notifications

This commit is contained in:
Dmitry Verkhoturov
2021-07-03 14:57:09 -05:00
committed by Umputun
parent 7f081e1d2c
commit 200733ed03
12 changed files with 392 additions and 112 deletions
+60 -42
View File
@@ -211,7 +211,7 @@ type SMTPGroup struct {
// NotifyGroup defines options for notification
type NotifyGroup struct {
Type []string `long:"type" env:"TYPE" description:"[deprecated, use user and admin types instead] types of notifications" choice:"none" choice:"telegram" choice:"email" choice:"slack" default:"none" env-delim:","` //nolint
Users []string `long:"users" env:"USERS" description:"types of user notifications" choice:"none" choice:"email" default:"none" env-delim:","` //nolint
Users []string `long:"users" env:"USERS" description:"types of user notifications" choice:"none" choice:"email" choice:"telegram" default:"none" env-delim:","` //nolint
Admins []string `long:"admins" env:"ADMINS" description:"types of admin notifications" choice:"none" choice:"telegram" choice:"email" choice:"slack" default:"none" env-delim:","` //nolint
QueueSize int `long:"queue" env:"QUEUE" description:"size of notification queue" default:"100"`
Telegram struct {
@@ -462,16 +462,22 @@ func (s *ServerCommand) newServerApp() (*serverApp, error) {
}
var emailNotifications bool
notifyService, err := s.makeNotify(dataService, authenticator)
var telegramNotificationsBotUsername string
notifyService, telegramBotUsername, err := s.makeNotify(dataService, authenticator)
if contains("email", s.Notify.Users) {
emailNotifications = true
}
if contains("telegram", s.Notify.Users) {
telegramNotificationsBotUsername = telegramBotUsername
}
if err != nil {
log.Printf("[WARN] failed to make notify service, %s", err)
notifyService = notify.NopService // disable notifier
emailNotifications = false // email notifications are not available in this case
notifyService = notify.NopService // disable notifier
emailNotifications = false // email notifications are not available in this case
telegramNotificationsBotUsername = "" // telegram notifications are not available in this case either
}
imgProxy := &proxy.Image{
@@ -494,28 +500,29 @@ func (s *ServerCommand) newServerApp() (*serverApp, error) {
}
srv := &api.Rest{
Version: s.Revision,
DataService: dataService,
WebRoot: s.WebRoot,
RemarkURL: s.RemarkURL,
ImageProxy: imgProxy,
CommentFormatter: commentFormatter,
Migrator: migr,
ReadOnlyAge: s.ReadOnlyAge,
SharedSecret: s.SharedSecret,
Authenticator: authenticator,
Cache: loadingCache,
NotifyService: notifyService,
SSLConfig: sslConfig,
UpdateLimiter: s.UpdateLimit,
ImageService: imageService,
EmailNotifications: emailNotifications,
EmojiEnabled: s.EnableEmoji,
AnonVote: s.AnonymousVote && s.RestrictVoteIP,
SimpleView: s.SimpleView,
ProxyCORS: s.ProxyCORS,
AllowedAncestors: s.AllowedHosts,
SendJWTHeader: s.Auth.SendJWTHeader,
Version: s.Revision,
DataService: dataService,
WebRoot: s.WebRoot,
RemarkURL: s.RemarkURL,
ImageProxy: imgProxy,
CommentFormatter: commentFormatter,
Migrator: migr,
ReadOnlyAge: s.ReadOnlyAge,
SharedSecret: s.SharedSecret,
Authenticator: authenticator,
Cache: loadingCache,
NotifyService: notifyService,
SSLConfig: sslConfig,
UpdateLimiter: s.UpdateLimit,
ImageService: imageService,
EmailNotifications: emailNotifications,
TelegramBotUsername: telegramNotificationsBotUsername,
EmojiEnabled: s.EnableEmoji,
AnonVote: s.AnonymousVote && s.RestrictVoteIP,
SimpleView: s.SimpleView,
ProxyCORS: s.ProxyCORS,
AllowedAncestors: s.AllowedHosts,
SendJWTHeader: s.Auth.SendJWTHeader,
}
srv.ScoreThresholds.Low, srv.ScoreThresholds.Critical = s.LowScore, s.CriticalScore
@@ -868,46 +875,57 @@ func (s *ServerCommand) loadEmailTemplate() (string, error) {
return string(file), nil
}
func (s *ServerCommand) makeNotify(dataStore *service.DataStore, authenticator *auth.Service) (*notify.Service, error) {
// aside from notify.Service and error, returns telegram bot name which will be passed to the frontend
func (s *ServerCommand) makeNotify(dataStore *service.DataStore, authenticator *auth.Service) (*notify.Service, string, error) {
var notifyService *notify.Service
var destinations []notify.Destination
var telegramBotUsername string
for _, t := range s.Notify.Admins {
switch t {
case "slack":
slack, err := notify.NewSlack(s.Notify.Slack.Token, s.Notify.Slack.Channel)
if err != nil {
return nil, errors.Wrap(err, "failed to create slack notification destination")
return nil, "", errors.Wrap(err, "failed to create slack notification destination")
}
destinations = append(destinations, slack)
case "telegram":
telegramParams := notify.TelegramParams{
AdminChannelID: s.Notify.Telegram.Channel,
Token: s.Telegram.Token,
Timeout: s.Telegram.Timeout,
}
tg, err := notify.NewTelegram(telegramParams)
if err != nil {
return nil, errors.Wrap(err, "failed to create telegram notification destination")
}
destinations = append(destinations, tg)
case "email":
case "none":
notifyService = notify.NopService
default:
return nil, errors.Errorf("unsupported admin notification type %q", s.Notify.Type)
return nil, "", errors.Errorf("unsupported admin notification type %q", s.Notify.Type)
}
}
for _, t := range s.Notify.Users {
switch t {
case "telegram":
case "email":
case "none":
notifyService = notify.NopService
default:
return nil, errors.Errorf("unsupported user notification type %q", s.Notify.Type)
return nil, "", errors.Errorf("unsupported user notification type %q", s.Notify.Type)
}
}
if contains("telegram", s.Notify.Users) || contains("telegram", s.Notify.Admins) {
if contains("telegram", s.Notify.Admins) && s.Notify.Telegram.Channel == "" {
return nil, "", errors.New("--notify.telegram.channel must be set for admin notifications to work")
}
telegramParams := notify.TelegramParams{
AdminChannelID: s.Notify.Telegram.Channel,
UserNotifications: contains("telegram", s.Notify.Users),
Token: s.Telegram.Token,
Timeout: s.Telegram.Timeout,
}
tg, err := notify.NewTelegram(telegramParams)
if err != nil {
return nil, "", errors.Wrap(err, "failed to create telegram notification destination")
}
destinations = append(destinations, tg)
telegramBotUsername = tg.BotUsername
}
// with logic below admin notifications enable notifications for users on the backend even if they
// are not enabled explicitly, however they won't be visible to the users in the frontend
// because api.Rest.EmailNotifications would be set to false.
@@ -949,7 +967,7 @@ func (s *ServerCommand) makeNotify(dataStore *service.DataStore, authenticator *
}
emailService, err := notify.NewEmail(emailParams, smtpParams)
if err != nil {
return nil, errors.Wrap(err, "failed to create email notification destination")
return nil, "", errors.Wrap(err, "failed to create email notification destination")
}
destinations = append(destinations, emailService)
}
@@ -958,7 +976,7 @@ func (s *ServerCommand) makeNotify(dataStore *service.DataStore, authenticator *
log.Printf("[INFO] make notify, for users: %s, for admins: %s", s.Notify.Users, s.Notify.Admins)
notifyService = notify.NewService(dataStore, s.Notify.QueueSize, destinations...)
}
return notifyService, nil
return notifyService, telegramBotUsername, nil
}
func (s *ServerCommand) makeSSLConfig() (config api.SSLConfig, err error) {