From 988171f4a5e8dc3fbd138fa4f13f11245e238ee4 Mon Sep 17 00:00:00 2001 From: ice-myles <96409608+ice-myles@users.noreply.github.com> Date: Thu, 11 Jul 2024 15:56:17 +0300 Subject: [PATCH] Disabled telegram notifications except socials (new) and new_referral (new). Disabled replies. Fixed telegram long polling getUpdates limit arg. --- application.yaml | 18 +-- go.mod | 6 +- go.sum | 12 +- notifications/contract.go | 13 +- notifications/notification_invite_friend.go | 4 +- .../notification_type_badge_unlocked.go | 8 +- .../notification_type_level_changed.go | 8 +- notifications/notification_type_mining.go | 4 +- .../notification_type_new_referral.go | 118 ++++++++++++------ .../notification_type_role_changed.go | 8 +- notifications/notification_type_socials.go | 17 ++- notifications/scheduler.go | 4 +- .../scheduler_telegram_notifications.go | 28 +++-- notifications/telegram_notifications.go | 82 +++++++----- .../telegram/coin_badge_unlocked.txt | 2 +- .../translations/telegram/follow_ion_on_x.txt | 6 - .../translations/telegram/follow_us_on_x.txt | 6 - .../telegram/follow_zeus_on_x.txt | 6 - .../translations/telegram/invite_friend.txt | 2 +- .../telegram/join_ion_on_telegram.txt | 6 - .../telegram/join_our_telegram.txt | 6 - .../telegram/level_badge_unlocked.txt | 2 +- .../translations/telegram/level_changed.txt | 2 +- .../telegram/mining_ending_soon.txt | 2 +- .../translations/telegram/mining_expired.txt | 2 +- .../translations/telegram/mining_extend.txt | 2 +- .../telegram/mining_not_active.txt | 2 +- .../translations/telegram/new_referral.txt | 6 + notifications/translations/telegram/reply.txt | 2 +- .../translations/telegram/role_changed.txt | 2 +- .../telegram/social_badge_unlocked.txt | 2 +- .../translations/telegram/socials.txt | 12 ++ 32 files changed, 239 insertions(+), 161 deletions(-) delete mode 100644 notifications/translations/telegram/follow_ion_on_x.txt delete mode 100644 notifications/translations/telegram/follow_us_on_x.txt delete mode 100644 notifications/translations/telegram/follow_zeus_on_x.txt delete mode 100644 notifications/translations/telegram/join_ion_on_telegram.txt delete mode 100644 notifications/translations/telegram/join_our_telegram.txt create mode 100644 notifications/translations/telegram/new_referral.txt create mode 100644 notifications/translations/telegram/socials.txt diff --git a/application.yaml b/application.yaml index 8649637..9d7f922 100644 --- a/application.yaml +++ b/application.yaml @@ -90,16 +90,16 @@ notifications: ¬ifications wintr/multimedia/picture: urlDownload: https://ice-staging.b-cdn.net socials: - - notificationType: follow_ion_on_x - link: https://x.com/ice_blockchain/status/1743221098349535361 - notificationType: follow_us_on_x - link: https://x.com/ice_blockchain/status/1793988190614823165 - - notificationType: follow_zeus_on_x - link: https://x.com/ice_blockchain/status/1793256299519418521 - - notificationType: join_ion_on_telegram - link: https://x.com/ice_blockchain/status/1793256299519418521 + link: https://x.com/sunwaves_token - notificationType: join_our_telegram - link: https://x.com/ice_blockchain/status/1793256299519418521 + link: 'https://t.me/sunwavestoken' + - notificationType: follow_ion_on_x + link: https://x.com/ice_blockchain + - notificationType: join_ion_on_telegram + link: 'https://t.me/iceblockchain' + - notificationType: follow_zeus_on_x + link: https://x.com/ice_z3us weeklyStats: weekday: 1 hour: 10 @@ -118,6 +118,8 @@ notifications: ¬ifications password: pass replicaURLs: - postgresql://root:pass@localhost:5434/husky + wintr/connectors/storage/v3: + url: redis://default:@localhost:6379 tenantName: BogusName tokenName: BN wintr/notifications/telegram: diff --git a/go.mod b/go.mod index c3b645d..c910eed 100644 --- a/go.mod +++ b/go.mod @@ -6,8 +6,8 @@ require ( github.com/goccy/go-json v0.10.3 github.com/google/uuid v1.6.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/ice-blockchain/eskimo v1.368.0 - github.com/ice-blockchain/freezer v1.485.0 + github.com/ice-blockchain/eskimo v1.369.0 + github.com/ice-blockchain/freezer v1.488.0 github.com/ice-blockchain/go-tarantool-client v0.0.0-20230327200757-4fc71fa3f7bb github.com/ice-blockchain/wintr v1.144.0 github.com/imroc/req/v3 v3.43.7 @@ -95,7 +95,7 @@ require ( github.com/golang-jwt/jwt/v5 v5.2.1 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.4 // indirect - github.com/google/pprof v0.0.0-20240625030939-27f56978b8b0 // indirect + github.com/google/pprof v0.0.0-20240711041743-f6c9dda6c6da // indirect github.com/google/s2a-go v0.1.7 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect github.com/googleapis/gax-go/v2 v2.12.5 // indirect diff --git a/go.sum b/go.sum index 17217ff..2af738c 100644 --- a/go.sum +++ b/go.sum @@ -247,8 +247,8 @@ github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian/v3 v3.3.3 h1:DIhPTQrbPkgs2yJYdXU/eNACCG5DVQjySNRNlflZ9Fc= github.com/google/martian/v3 v3.3.3/go.mod h1:iEPrYcgCF7jA9OtScMFQyAlZZ4YXTKEtJ1E6RWzmBA0= -github.com/google/pprof v0.0.0-20240625030939-27f56978b8b0 h1:e+8XbKB6IMn8A4OAyZccO4pYfB3s7bt6azNIPE7AnPg= -github.com/google/pprof v0.0.0-20240625030939-27f56978b8b0/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= +github.com/google/pprof v0.0.0-20240711041743-f6c9dda6c6da h1:xRmpO92tb8y+Z85iUOMOicpCfaYcv7o3Cg3wKrIpg8g= +github.com/google/pprof v0.0.0-20240711041743-f6c9dda6c6da/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= @@ -282,10 +282,10 @@ github.com/holiman/uint256 v1.3.0 h1:4wdcm/tnd0xXdu7iS3ruNvxkWwrb4aeBQv19ayYn8F4 github.com/holiman/uint256 v1.3.0/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= -github.com/ice-blockchain/eskimo v1.368.0 h1:4xougCqbB62CEvBRzfoqEzFa/6ZYf1OeKoa2EoV53f8= -github.com/ice-blockchain/eskimo v1.368.0/go.mod h1:OpR88RU/bYLmjugzyumwo/sx0fvG8B9pYsLZIy/DFgI= -github.com/ice-blockchain/freezer v1.485.0 h1:znX6LMcYFbOArD/zHvwm/bYvgAzyX6Z/aYFmrJet90Q= -github.com/ice-blockchain/freezer v1.485.0/go.mod h1:NmqNJ34CIRUHzBZ7Tgd42Ei30qKeSqflQh4PM/iW4M4= +github.com/ice-blockchain/eskimo v1.369.0 h1:DFguku6xR4rb8G1Ay4LAh0s6qzYPnoKsO28uFJGvAko= +github.com/ice-blockchain/eskimo v1.369.0/go.mod h1:l4MZKGo/Lpq+LFr65HUAGc/SvN4IclA0kpFqXjjQsZ8= +github.com/ice-blockchain/freezer v1.488.0 h1:Q3XGS16eDQ4zeSTqfYLLwAt+H3TbDda9hI+VhEfhTx0= +github.com/ice-blockchain/freezer v1.488.0/go.mod h1:bSwFbBC95BBF+/WrPJp+l9qyrGruim0pnTpAmkkWoLQ= github.com/ice-blockchain/go-tarantool-client v0.0.0-20230327200757-4fc71fa3f7bb h1:8TnFP3mc7O+tc44kv2e0/TpZKnEVUaKH+UstwfBwRkk= github.com/ice-blockchain/go-tarantool-client v0.0.0-20230327200757-4fc71fa3f7bb/go.mod h1:ZsQU7i3mxhgBBu43Oev7WPFbIjP4TniN/b1UPNGbrq8= github.com/ice-blockchain/wintr v1.144.0 h1:YQE0olkPdSI6AOlw7r/j5jGI6uLciZQrvXFIkN4C4l4= diff --git a/notifications/contract.go b/notifications/contract.go index 4f67aeb..ab7ca9a 100644 --- a/notifications/contract.go +++ b/notifications/contract.go @@ -72,6 +72,7 @@ const ( SocialsFollowOurTelegramNotificationType NotificationType = "join_our_telegram" WeeklyStatsNotificationType NotificationType = "weekly_stats" ReplyNotificationType NotificationType = "reply" + SocialsNotificationType NotificationType = "socials" ) var ( @@ -125,11 +126,8 @@ var ( MiningExpiredNotificationType, MiningNotActiveNotificationType, InviteFriendNotificationType, - SocialsFollowIceOnXNotificationType, - SocialsFollowUsOnXNotificationType, - SocialsFollowZeusOnXNotificationType, - SocialsFollowIONOnTelegramNotificationType, - SocialsFollowOurTelegramNotificationType, + NewReferralNotificationType, + SocialsNotificationType, ReplyNotificationType, } //nolint:gochecknoglobals // It's just for more descriptive validation messages. @@ -218,8 +216,9 @@ const ( requestingUserIDCtxValueKey = "requestingUserIDCtxValueKey" requestDeadline = 30 * stdlibtime.Second - schedulerWorkersCount int64 = 10 - schedulerPushBatchSize int64 = 250 + schedulerWorkersCount int64 = 10 + schedulerPushBatchSize int64 = 250 + telegramLongPollingLimit int64 = 100 defaultLanguage = "en" // Protection from getting ErrDuplicate on session creation due to ReferralsCountChangeGuardUpdatedAt on freezer. diff --git a/notifications/notification_invite_friend.go b/notifications/notification_invite_friend.go index ccdce37..b7aa134 100644 --- a/notifications/notification_invite_friend.go +++ b/notifications/notification_invite_friend.go @@ -27,8 +27,8 @@ func (r *repository) addScheduledInviteFriendNotifications(ctx context.Context, dayDuration = 24 * stdlibtime.Hour firstNotificationDuration = 1 * stdlibtime.Hour } - availableChannels := []NotificationChannel{PushNotificationChannel, TelegramNotificationChannel} - scheduled := make([]*scheduledNotification, 0, 2*len(availableChannels)) //nolint:gomnd,mnd // . + availableChannels := []NotificationChannel{PushNotificationChannel} + scheduled := make([]*scheduledNotification, 0, len(availableChannels)) for _, channel := range availableChannels { scheduled = append(scheduled, &scheduledNotification{ ScheduledAt: now, diff --git a/notifications/notification_type_badge_unlocked.go b/notifications/notification_type_badge_unlocked.go index eae3518..83aed39 100644 --- a/notifications/notification_type_badge_unlocked.go +++ b/notifications/notification_type_badge_unlocked.go @@ -137,8 +137,8 @@ func (s *achievedBadgesSource) Process(ctx context.Context, msg *messagebroker.M return errors.Wrapf(s.sendInAppNotification(ctx, in), "failed to sendInAppNotification for %v, notif:%#v", notifType, in) }) } - if tokens.TelegramBotID != "" && tokens.TelegramBotID != tokens.UserID && //nolint:nestif // . - tokens.TelegramUserID != "" && tokens.TelegramUserID != tokens.UserID { + if false && (tokens.TelegramBotID != "" && tokens.TelegramBotID != tokens.UserID && //nolint:revive,nestif // . + tokens.TelegramUserID != "" && tokens.TelegramUserID != tokens.UserID) { tmplTelegram, found := allTelegramNotificationTemplates[notifType][tokens.Language] if !found { log.Warn(fmt.Sprintf("language `%v` was not found in the `%v` telegram config", tokens.Language, notifType)) @@ -162,8 +162,8 @@ func (s *achievedBadgesSource) Process(ctx context.Context, msg *messagebroker.M }, }, } - buttonText := tmplTelegram.getButtonText(nil) - buttonLink := getTelegramDeeplink(notifType, s.cfg, "", "") + buttonText := tmplTelegram.getButtonText(nil, 0) + buttonLink := getTelegramDeeplink(notifType, s.cfg, "", "", "") if buttonText != "" && buttonLink != "" { tn.tn.Buttons = append(tn.tn.Buttons, struct { Text string `json:"text,omitempty"` diff --git a/notifications/notification_type_level_changed.go b/notifications/notification_type_level_changed.go index af8d732..cd5d097 100644 --- a/notifications/notification_type_level_changed.go +++ b/notifications/notification_type_level_changed.go @@ -115,8 +115,8 @@ func (s *completedLevelsSource) Process(ctx context.Context, msg *messagebroker. return errors.Wrapf(s.sendInAppNotification(ctx, in), "failed to sendInAppNotification for %v, notif:%#v", LevelChangedNotificationType, in) }) } - if tokens.TelegramBotID != "" && tokens.TelegramBotID != tokens.UserID && //nolint:nestif // . - tokens.TelegramUserID != "" && tokens.TelegramUserID != tokens.UserID { + if false && (tokens.TelegramBotID != "" && tokens.TelegramBotID != tokens.UserID && //nolint:revive,nestif // . + tokens.TelegramUserID != "" && tokens.TelegramUserID != tokens.UserID) { if tmplTelegram, found := allTelegramNotificationTemplates[LevelChangedNotificationType][tokens.Language]; !found { log.Warn(fmt.Sprintf("language `%v` was not found in the `%v` telegram config", tokens.Language, LevelChangedNotificationType)) } else { //nolint:dupl // . @@ -139,8 +139,8 @@ func (s *completedLevelsSource) Process(ctx context.Context, msg *messagebroker. }, }, } - buttonText := tmplTelegram.getButtonText(nil) - buttonLink := getTelegramDeeplink(LevelChangedNotificationType, s.cfg, "", "") + buttonText := tmplTelegram.getButtonText(nil, 0) + buttonLink := getTelegramDeeplink(LevelChangedNotificationType, s.cfg, "", "", "") if buttonText != "" && buttonLink != "" { tn.tn.Buttons = append(tn.tn.Buttons, struct { Text string `json:"text,omitempty"` diff --git a/notifications/notification_type_mining.go b/notifications/notification_type_mining.go index 8a5b5b4..3526014 100644 --- a/notifications/notification_type_mining.go +++ b/notifications/notification_type_mining.go @@ -106,8 +106,8 @@ func (m *miningSessionSource) insertMiningScheduledNotifications(ctx context.Con dayDuration = 24 * stdlibtime.Hour uniquenessTime = fmt.Sprintf("%v:%02d:%02d %02d:%02d:%02d", now.Year(), int(now.Month()), now.Day(), now.Hour(), 0, 0) } - scheduled := make([]*scheduledNotification, 0, 2*notificationsNum) //nolint:gomnd,mnd // . - for _, channel := range []NotificationChannel{PushNotificationChannel, TelegramNotificationChannel} { + scheduled := make([]*scheduledNotification, 0, notificationsNum) + for _, channel := range []NotificationChannel{PushNotificationChannel} { scheduled = append(scheduled, &scheduledNotification{ ScheduledAt: now, ScheduledFor: message.ResettableStartingAt, diff --git a/notifications/notification_type_new_referral.go b/notifications/notification_type_new_referral.go index b037a2e..da5ec20 100644 --- a/notifications/notification_type_new_referral.go +++ b/notifications/notification_type_new_referral.go @@ -5,6 +5,7 @@ package notifications import ( "context" "fmt" + "strings" "github.com/hashicorp/go-multierror" "github.com/pkg/errors" @@ -16,10 +17,11 @@ import ( "github.com/ice-blockchain/wintr/log" "github.com/ice-blockchain/wintr/notifications/inapp" "github.com/ice-blockchain/wintr/notifications/push" + "github.com/ice-blockchain/wintr/notifications/telegram" "github.com/ice-blockchain/wintr/time" ) -func (r *repository) sendNewReferralNotification(ctx context.Context, us *users.UserSnapshot) error { //nolint:funlen,gocyclo,revive,cyclop // . +func (r *repository) sendNewReferralNotification(ctx context.Context, us *users.UserSnapshot) error { //nolint:funlen,gocyclo,revive,cyclop,gocognit // . if ctx.Err() != nil { return errors.Wrap(ctx.Err(), "unexpected deadline") } @@ -66,19 +68,13 @@ func (r *repository) sendNewReferralNotification(ctx context.Context, us *users. }, } tokens, err := r.getPushNotificationTokens(ctx, MicroCommunityNotificationDomain, us.User.ReferredBy) - if err != nil || tokens == nil || tokens.PushNotificationTokens == nil || len(*tokens.PushNotificationTokens) == 0 { + if err != nil || tokens == nil { return multierror.Append( //nolint:wrapcheck // . err, errors.Wrapf(r.sendInAppNotification(ctx, in), "failed to sendInAppNotification for %v, notif:%#v", NewReferralNotificationType, in), ).ErrorOrNil() } - tmpl, found := allPushNotificationTemplates[NewReferralNotificationType][tokens.Language] - if !found { - log.Warn(fmt.Sprintf("language `%v` was not found in the `%v` push config", tokens.Language, NewReferralNotificationType)) - - return errors.Wrapf(r.sendInAppNotification(ctx, in), "failed to sendInAppNotification for %v, notif:%#v", NewReferralNotificationType, in) - } - pn := make([]*pushNotification, 0, len(*tokens.PushNotificationTokens)) + var exConcurrently []func() error data := struct { Username, Coin string Amount uint64 @@ -87,40 +83,90 @@ func (r *repository) sendNewReferralNotification(ctx context.Context, us *users. Coin: r.cfg.TokenName, Amount: r.getNewReferralCoinAmount(ctx, us.User.ReferredBy), } - for _, token := range *tokens.PushNotificationTokens { - pn = append(pn, &pushNotification{ - pn: &push.Notification[push.DeviceToken]{ - Data: map[string]string{"deeplink": deeplink}, - Target: token, - Title: tmpl.getTitle(data), - Body: tmpl.getBody(data), - ImageURL: us.User.ProfilePictureURL, - }, - sn: &sentNotification{ - SentAt: now, - Language: tokens.Language, - sentNotificationPK: sentNotificationPK{ - UserID: us.User.ReferredBy, - Uniqueness: us.User.ID, - NotificationType: NewReferralNotificationType, - NotificationChannel: PushNotificationChannel, - NotificationChannelValue: string(token), + if tokens.PushNotificationTokens != nil && len(*tokens.PushNotificationTokens) != 0 { + tmpl, found := allPushNotificationTemplates[NewReferralNotificationType][tokens.Language] + if !found { + log.Warn(fmt.Sprintf("language `%v` was not found in the `%v` push config", tokens.Language, NewReferralNotificationType)) + + return errors.Wrapf(r.sendInAppNotification(ctx, in), "failed to sendInAppNotification for %v, notif:%#v", NewReferralNotificationType, in) + } + pn := make([]*pushNotification, 0, len(*tokens.PushNotificationTokens)) + for _, token := range *tokens.PushNotificationTokens { + pn = append(pn, &pushNotification{ + pn: &push.Notification[push.DeviceToken]{ + Data: map[string]string{"deeplink": deeplink}, + Target: token, + Title: tmpl.getTitle(data), + Body: tmpl.getBody(data), + ImageURL: us.User.ProfilePictureURL, }, - }, + sn: &sentNotification{ + SentAt: now, + Language: tokens.Language, + sentNotificationPK: sentNotificationPK{ + UserID: us.User.ReferredBy, + Uniqueness: us.User.ID, + NotificationType: NewReferralNotificationType, + NotificationChannel: PushNotificationChannel, + NotificationChannelValue: string(token), + }, + }, + }) + } + exConcurrently = append(exConcurrently, func() error { + return errors.Wrapf(runConcurrently(ctx, r.sendPushNotification, pn), "failed to sendPushNotifications atleast to some devices for %v, args:%#v", NewReferralNotificationType, pn) //nolint:lll // . + }, func() error { + return errors.Wrapf(r.sendInAppNotification(ctx, in), "failed to sendInAppNotification for %v, notif:%#v", NewReferralNotificationType, in) }) } + if tokens.TelegramBotID != "" && tokens.TelegramBotID != tokens.UserID && //nolint:nestif // . + tokens.TelegramUserID != "" && tokens.TelegramUserID != tokens.UserID { + tmplTelegram, found := allTelegramNotificationTemplates[NewReferralNotificationType][tokens.Language] + if !found { + log.Warn(fmt.Sprintf("language `%v` was not found in the `%v` telegram config", tokens.Language, NewReferralNotificationType)) + } else { + if botInfo, botFound := r.cfg.TelegramBots[strings.ToLower(tokens.TelegramBotID)]; botFound { + tn := &telegramNotification{ + tn: &telegram.Notification{ + ChatID: tokens.TelegramUserID, + Text: tmplTelegram.getBody(data), + BotToken: botInfo.BotToken, + }, + sn: &sentNotification{ + SentAt: now, + Language: tokens.Language, + sentNotificationPK: sentNotificationPK{ + UserID: us.User.ReferredBy, + Uniqueness: us.User.ID, + NotificationType: NewReferralNotificationType, + NotificationChannel: TelegramNotificationChannel, + NotificationChannelValue: us.User.ID, + }, + }, + } + buttonText := tmplTelegram.getButtonText(nil, 0) + buttonLink := getTelegramDeeplink(NewReferralNotificationType, r.cfg, "", "", us.User.ID) + if buttonText != "" && buttonLink != "" { + tn.tn.Buttons = append(tn.tn.Buttons, struct { + Text string `json:"text,omitempty"` + URL string `json:"url,omitempty"` + }{ + Text: buttonText, + URL: buttonLink, + }) + } + exConcurrently = append(exConcurrently, func() error { + return errors.Wrapf(r.sendTelegramNotification(ctx, tn), "failed to send telegram notification for %v, notif:%#v", NewReferralNotificationType, in) + }) + } + } + } - return errors.Wrap(executeConcurrently(func() error { - return errors.Wrapf(runConcurrently(ctx, r.sendPushNotification, pn), "failed to sendPushNotifications atleast to some devices for %v, args:%#v", NewReferralNotificationType, pn) //nolint:lll // . - }, func() error { - return errors.Wrapf(r.sendInAppNotification(ctx, in), "failed to sendInAppNotification for %v, notif:%#v", NewReferralNotificationType, in) - }), "failed to executeConcurrently") + return errors.Wrap(executeConcurrently(exConcurrently...), "failed to executeConcurrently") } func (r *repository) getNewReferralCoinAmount(ctx context.Context, referredBy string) uint64 { - const defaultNewReferralCoinAmount = 500.0 - //nolint:gocritic,godot // TODO: Uncomment this asap! - // const defaultNewReferralCoinAmount = tokenomics.WelcomeBonusV2Amount + const defaultNewReferralCoinAmount = tokenomics.WelcomeBonusV2Amount freezerInternalID, err := tokenomics.GetInternalID(ctx, r.freezerDB, referredBy) if err != nil { log.Error(errors.Wrapf(err, "failed to tokenomics.GetInternalID for referredBy: %v", referredBy)) diff --git a/notifications/notification_type_role_changed.go b/notifications/notification_type_role_changed.go index 27a797b..4bd7c16 100644 --- a/notifications/notification_type_role_changed.go +++ b/notifications/notification_type_role_changed.go @@ -115,8 +115,8 @@ func (s *enabledRolesSource) Process(ctx context.Context, msg *messagebroker.Mes return errors.Wrapf(s.sendInAppNotification(ctx, in), "failed to sendInAppNotification for %v, notif:%#v", RoleChangedNotificationType, in) }) } - if tokens.TelegramBotID != "" && tokens.TelegramBotID != tokens.UserID && //nolint:nestif // . - tokens.TelegramUserID != "" && tokens.TelegramUserID != tokens.UserID { + if false && (tokens.TelegramBotID != "" && tokens.TelegramBotID != tokens.UserID && //nolint:revive,nestif // . + tokens.TelegramUserID != "" && tokens.TelegramUserID != tokens.UserID) { tmplTelegram, found := allTelegramNotificationTemplates[RoleChangedNotificationType][tokens.Language] if !found { log.Warn(fmt.Sprintf("language `%v` was not found in the `%v` telegram config", tokens.Language, RoleChangedNotificationType)) @@ -140,8 +140,8 @@ func (s *enabledRolesSource) Process(ctx context.Context, msg *messagebroker.Mes }, }, } - buttonText := tmplTelegram.getButtonText(nil) - buttonLink := getTelegramDeeplink(LevelChangedNotificationType, s.cfg, "", "") + buttonText := tmplTelegram.getButtonText(nil, 0) + buttonLink := getTelegramDeeplink(LevelChangedNotificationType, s.cfg, "", "", "") if buttonText != "" && buttonLink != "" { tn.tn.Buttons = append(tn.tn.Buttons, struct { Text string `json:"text,omitempty"` diff --git a/notifications/notification_type_socials.go b/notifications/notification_type_socials.go index 445f3b7..ba567dc 100644 --- a/notifications/notification_type_socials.go +++ b/notifications/notification_type_socials.go @@ -19,14 +19,14 @@ func (r *repository) addScheduledSocialsNotifications(ctx context.Context, us *u return errors.Wrap(ctx.Err(), "unexpected deadline") } now := time.Now() - scheduled := make([]*scheduledNotification, 0, 2*len(r.cfg.Socials)) //nolint:gomnd,mnd // . + scheduled := make([]*scheduledNotification, 0, len(r.cfg.Socials)+1) var dayDuration stdlibtime.Duration if r.cfg.Development { dayDuration = 1 * stdlibtime.Minute } else { dayDuration = 24 * stdlibtime.Hour } - for _, channel := range []NotificationChannel{PushNotificationChannel, TelegramNotificationChannel} { + for _, channel := range []NotificationChannel{PushNotificationChannel} { for ix := range r.cfg.Socials { scheduled = append(scheduled, &scheduledNotification{ ScheduledAt: now, @@ -44,6 +44,19 @@ func (r *repository) addScheduledSocialsNotifications(ctx context.Context, us *u }) } } + scheduled = append(scheduled, &scheduledNotification{ + ScheduledAt: now, + ScheduledFor: time.New(us.CreatedAt.Add(dayDuration)), + Language: us.Language, + UserID: us.ID, + NotificationType: string(SocialsNotificationType), + Uniqueness: fmt.Sprintf("%v_%v", us.ID, SocialsNotificationType), + NotificationChannel: string(TelegramNotificationChannel), + NotificationChannelValue: us.ID, + Data: &users.JSON{ + "TenantName": r.cfg.TenantName, + }, + }) return errors.Wrapf(insertScheduledNotifications(ctx, r.db, scheduled), "can't execute insertScheduledNotifications:%#v", scheduled) } diff --git a/notifications/scheduler.go b/notifications/scheduler.go index e19044f..f8e34e6 100644 --- a/notifications/scheduler.go +++ b/notifications/scheduler.go @@ -43,7 +43,9 @@ func MustStartScheduler(ctx context.Context, cancel context.CancelFunc) *Schedul schedulerTelegramNotificationsMX: &sync.Mutex{}, } go sh.startWeeklyStatsUpdater(ctx) - go sh.startGetUpdatesTelegramLongPolling(ctx) + if false { + go sh.startGetUpdatesTelegramLongPolling(ctx) + } sh.wg = new(sync.WaitGroup) sh.wg.Add(3 * int(schedulerWorkersCount)) //nolint:gomnd,mnd // . sh.cancel = cancel diff --git a/notifications/scheduler_telegram_notifications.go b/notifications/scheduler_telegram_notifications.go index b40d7fa..1a22bd9 100644 --- a/notifications/scheduler_telegram_notifications.go +++ b/notifications/scheduler_telegram_notifications.go @@ -109,18 +109,10 @@ func (s *Scheduler) runTelegramNotificationsProcessor(ctx context.Context, worke }, scheduled: notification.scheduledNotification, } - buttonText := tmpl.getButtonText(notification.Data) - buttonLink := getTelegramDeeplink(NotificationType(notification.NotificationType), s.cfg, notification.Username, tmpl.getInviteText(notification.Data)) - if buttonText != "" && buttonLink != "" { - tn.tn.Buttons = append(tn.tn.Buttons, struct { - Text string `json:"text,omitempty"` - URL string `json:"url,omitempty"` - }{ - Text: buttonText, - URL: buttonLink, - }) - } - if notification.NotificationType == string(ReplyNotificationType) { + switch notification.NotificationType { + case string(SocialsNotificationType): + tn.tn.Buttons = append(tn.tn.Buttons, prepareTelegramButtonsForSocialNotificationType(s.cfg, tmpl.ButtonText)...) + case string(ReplyNotificationType): replyMessageID, pErr := strconv.ParseInt(notification.NotificationChannelValue, 10, 64) if pErr != nil { log.Warn("can't convert notification chanel value to integer for reply notification type", pErr) @@ -129,6 +121,18 @@ func (s *Scheduler) runTelegramNotificationsProcessor(ctx context.Context, worke continue } tn.tn.ReplyMessageID = replyMessageID + default: + buttonText := tmpl.getButtonText(notification.Data, 0) + buttonLink := getTelegramDeeplink(NotificationType(notification.NotificationType), s.cfg, notification.Username, tmpl.getInviteText(notification.Data), notification.UserID) //nolint:lll // . + if buttonText != "" && buttonLink != "" { + tn.tn.Buttons = append(tn.tn.Buttons, struct { + Text string `json:"text,omitempty"` + URL string `json:"url,omitempty"` + }{ + Text: buttonText, + URL: buttonLink, + }) + } } toSendTelegramNotifications = append(toSendTelegramNotifications, tn) } diff --git a/notifications/telegram_notifications.go b/notifications/telegram_notifications.go index 6fbea82..73b2177 100644 --- a/notifications/telegram_notifications.go +++ b/notifications/telegram_notifications.go @@ -24,19 +24,23 @@ import ( type ( telegramNotificationTemplate struct { - body, buttonText, inviteText *template.Template - Body string `json:"body"` //nolint:revive // That's intended. - ButtonText string `json:"buttonText"` //nolint:revive // That's intended. - InviteText string `json:"inviteText"` //nolint:revive // That's intended. + body, inviteText *template.Template + Body string `json:"body"` //nolint:revive // That's intended. + InviteText string `json:"inviteText"` //nolint:revive // That's intended. + ButtonText []string `json:"buttonText"` + buttonText []*template.Template //nolint:revive // That's intended. } ) -func (t *telegramNotificationTemplate) getButtonText(data any) string { +func (t *telegramNotificationTemplate) getButtonText(data any, ix int) string { //nolint:unparam // . + if ix > len(t.buttonText)-1 { + return "" + } if data == nil { - return t.ButtonText + return t.ButtonText[ix] } bf := new(bytes.Buffer) - log.Panic(errors.Wrapf(t.buttonText.Execute(bf, data), "failed to execute button text template for data:%#v", data)) + log.Panic(errors.Wrapf(t.buttonText[ix].Execute(bf, data), "failed to execute button text 1 template for data:%#v", data)) return bf.String() } @@ -66,7 +70,7 @@ func (t *telegramNotificationTemplate) getInviteText(data any) string { return bf.String() } -func loadTelegramNotificationTranslationTemplates() { +func loadTelegramNotificationTranslationTemplates() { //nolint:funlen // . const totalLanguages = 50 allTelegramNotificationTemplates = make(map[NotificationType]map[languageCode]*telegramNotificationTemplate, len(AllTelegramNotificationTypes)) for _, notificationType := range AllTelegramNotificationTypes { @@ -76,9 +80,9 @@ func loadTelegramNotificationTranslationTemplates() { } allTelegramNotificationTemplates[notificationType] = make(map[languageCode]*telegramNotificationTemplate, totalLanguages) var translations map[string]*struct { - Body string `json:"body"` - ButtonText string `json:"buttonText"` - InviteText string `json:"inviteText"` + Body string `json:"body"` + InviteText string `json:"inviteText"` + ButtonText []string `json:"buttonText"` } err := json.Unmarshal(content, &translations) if err != nil { @@ -87,12 +91,14 @@ func loadTelegramNotificationTranslationTemplates() { for language, data := range translations { var tmpl telegramNotificationTemplate tmpl.Body = data.Body - tmpl.ButtonText = data.ButtonText if notificationType == InviteFriendNotificationType { tmpl.InviteText = data.InviteText tmpl.inviteText = template.Must(template.New(fmt.Sprintf("telegram_%v_%v_invite_text", notificationType, language)).Parse(data.InviteText)) } - tmpl.buttonText = template.Must(template.New(fmt.Sprintf("telegram_%v_%v_button_text", notificationType, language)).Parse(data.ButtonText)) + tmpl.ButtonText = data.ButtonText + for ix := range data.ButtonText { + tmpl.buttonText = append(tmpl.buttonText, template.Must(template.New(fmt.Sprintf("telegram_%v_%v_button_text_%v", notificationType, language, ix)).Parse(data.ButtonText[ix]))) //nolint:lll // . + } tmpl.body = template.Must(template.New(fmt.Sprintf("telegram_%v_%v_body", notificationType, language)).Parse(data.Body)) allTelegramNotificationTemplates[notificationType][language] = &tmpl } @@ -100,29 +106,20 @@ func loadTelegramNotificationTranslationTemplates() { } //nolint:exhaustive // We know what cases need to be handled only. -func getTelegramDeeplink(nt NotificationType, cfg *config, username, inviteText string) string { - urls := getSocialsMapURL(cfg) +func getTelegramDeeplink(nt NotificationType, cfg *config, username, inviteText, userID string) string { switch nt { case MiningExtendNotificationType, MiningEndingSoonNotificationType, MiningExpiredNotificationType, MiningNotActiveNotificationType: return cfg.WebAppLink case InviteFriendNotificationType: return fmt.Sprintf("%[1]v?url=%[2]v/@%[3]v&text=%[4]v", cfg.InviteURL, url.QueryEscape(cfg.WebSiteURL), url.QueryEscape(username), url.QueryEscape(inviteText)) //nolint:lll // . - case SocialsFollowIceOnXNotificationType: - return urls[string(SocialsFollowIceOnXNotificationType)] - case SocialsFollowUsOnXNotificationType: - return urls[string(SocialsFollowUsOnXNotificationType)] - case SocialsFollowZeusOnXNotificationType: - return urls[string(SocialsFollowZeusOnXNotificationType)] - case SocialsFollowIONOnTelegramNotificationType: - return urls[string(SocialsFollowIONOnTelegramNotificationType)] - case SocialsFollowOurTelegramNotificationType: - return urls[string(SocialsFollowOurTelegramNotificationType)] case CoinBadgeUnlockedNotificationType, LevelBadgeUnlockedNotificationType, SocialBadgeUnlockedNotificationType: return fmt.Sprintf("%v?startapp=goto_profile_badges", cfg.WebAppLink) case LevelChangedNotificationType: return fmt.Sprintf("%v?startapp=goto_profile", cfg.WebAppLink) case ReplyNotificationType: return cfg.WebAppLink + case NewReferralNotificationType: + return fmt.Sprintf("%v://profile?userId=%v", cfg.WebAppLink, userID) default: log.Panic(fmt.Sprintf("wrong notification type:%v", nt)) } @@ -130,13 +127,40 @@ func getTelegramDeeplink(nt NotificationType, cfg *config, username, inviteText return "" } -func getSocialsMapURL(cfg *config) map[string]string { +func prepareTelegramButtonsForSocialNotificationType(cfg *config, buttonTexts []string) []struct { + Text string `json:"text,omitempty"` + URL string `json:"url,omitempty"` +} { + urls := getSocialsMapURL(cfg) + if len(urls) != len(buttonTexts) { + log.Error(errors.New("socials cfg/translation misconfiguration")) + + return nil + } + res := make([]struct { + Text string `json:"text,omitempty"` + URL string `json:"url,omitempty"` + }, 0, len(buttonTexts)) + for ix, text := range buttonTexts { + res = append(res, struct { + Text string `json:"text,omitempty"` + URL string `json:"url,omitempty"` + }{ + Text: text, + URL: urls[ix], + }) + } + + return res +} + +func getSocialsMapURL(cfg *config) map[int]string { if len(cfg.Socials) == 0 { log.Panic("no urls for socials") } - urls := make(map[string]string, len(cfg.Socials)) + urls := make(map[int]string, len(cfg.Socials)) for ix := range cfg.Socials { - urls[cfg.Socials[ix].NotificationType] = cfg.Socials[ix].Link + urls[ix] = cfg.Socials[ix].Link } return urls @@ -172,7 +196,7 @@ func (s *Scheduler) getTelegramLongPollingUpdates(ctx context.Context) (err erro upd, gErr := s.telegramNotificationsClient.GetUpdates(ctx, &telegram.GetUpdatesArg{ BotToken: bot.BotToken, AllowedUpdates: []string{"message", "callback_query"}, - Limit: int64(1), + Limit: telegramLongPollingLimit, Offset: nextOffset, }) if gErr != nil { diff --git a/notifications/translations/telegram/coin_badge_unlocked.txt b/notifications/translations/telegram/coin_badge_unlocked.txt index e3124d1..f1cf524 100644 --- a/notifications/translations/telegram/coin_badge_unlocked.txt +++ b/notifications/translations/telegram/coin_badge_unlocked.txt @@ -1,6 +1,6 @@ { "en":{ "body":"🎉 New badge earned!\n\nYou've unlocked the {{.BadgeName}} coin badge! Check it out in your profile.", - "buttonText": "🤩 View Badge" + "buttonText": ["🤩 View Badge"] } } \ No newline at end of file diff --git a/notifications/translations/telegram/follow_ion_on_x.txt b/notifications/translations/telegram/follow_ion_on_x.txt deleted file mode 100644 index 7b75bca..0000000 --- a/notifications/translations/telegram/follow_ion_on_x.txt +++ /dev/null @@ -1,6 +0,0 @@ -{ - "en": { - "body": "❄️ Follow Ice Open Network on X\n\nStay updated with the latest news and insights from Ice Open Network", - "buttonText": "👉 Follow ION on X" - } -} diff --git a/notifications/translations/telegram/follow_us_on_x.txt b/notifications/translations/telegram/follow_us_on_x.txt deleted file mode 100644 index e9cc3a5..0000000 --- a/notifications/translations/telegram/follow_us_on_x.txt +++ /dev/null @@ -1,6 +0,0 @@ -{ - "en": { - "body": "👋 Follow us on X\n\nConnect with us on X and join our fast-growing community.", - "buttonText": "🎉 Follow {{.TenantName}} on X" - } -} \ No newline at end of file diff --git a/notifications/translations/telegram/follow_zeus_on_x.txt b/notifications/translations/telegram/follow_zeus_on_x.txt deleted file mode 100644 index 4c32452..0000000 --- a/notifications/translations/telegram/follow_zeus_on_x.txt +++ /dev/null @@ -1,6 +0,0 @@ -{ - "en": { - "body": "🙌 Follow Zeus on X\n\nStay connected with the founder of Ice Open Network on X", - "buttonText": "🌟 Follow Zeus on X" - } -} \ No newline at end of file diff --git a/notifications/translations/telegram/invite_friend.txt b/notifications/translations/telegram/invite_friend.txt index 88aeead..6f6d018 100644 --- a/notifications/translations/telegram/invite_friend.txt +++ b/notifications/translations/telegram/invite_friend.txt @@ -1,7 +1,7 @@ { "en": { "body": "👋  Invite friends, earn more {{.TenantName}}!\n\nBring your friends to the network and watch your {{.TenantName}} balance grow!", - "buttonText": "⭐️ Invite Now", + "buttonText": ["⭐️ Invite Now"], "inviteText": "🌟 One of the biggest and oldest electronic music festivals in the WORLD is launching their token on #IceOpenNetwork.\n\n Join {{.TenantName}} and receive 10 SW coins when you sign-up using my referral code: {{.Username}}\n\n 🎶 Music is the anSWer" } } \ No newline at end of file diff --git a/notifications/translations/telegram/join_ion_on_telegram.txt b/notifications/translations/telegram/join_ion_on_telegram.txt deleted file mode 100644 index 1245e32..0000000 --- a/notifications/translations/telegram/join_ion_on_telegram.txt +++ /dev/null @@ -1,6 +0,0 @@ -{ - "en": { - "body": "🤩 Join Ice Open Network on Telegram\n\nStay connected and follow the latest updates from Ice Open Network on Telegram", - "buttonText": "💙 Join Now" - } -} diff --git a/notifications/translations/telegram/join_our_telegram.txt b/notifications/translations/telegram/join_our_telegram.txt deleted file mode 100644 index 8236bba..0000000 --- a/notifications/translations/telegram/join_our_telegram.txt +++ /dev/null @@ -1,6 +0,0 @@ -{ - "en": { - "body": "📣 Join our Telegram community!\n\nJoin our community channel for exclusive updates.", - "buttonText": "✅ Join Now" - } -} \ No newline at end of file diff --git a/notifications/translations/telegram/level_badge_unlocked.txt b/notifications/translations/telegram/level_badge_unlocked.txt index ea07b8f..bdc7368 100644 --- a/notifications/translations/telegram/level_badge_unlocked.txt +++ b/notifications/translations/telegram/level_badge_unlocked.txt @@ -1,6 +1,6 @@ { "en":{ "body":"🎉 New badge earned!\n\nYou've unlocked the {{.BadgeName}} level badge! Check it out in your profile.", - "buttonText": "🤩 View Badge" + "buttonText": ["🤩 View Badge"] } } \ No newline at end of file diff --git a/notifications/translations/telegram/level_changed.txt b/notifications/translations/telegram/level_changed.txt index 0dce712..86da149 100644 --- a/notifications/translations/telegram/level_changed.txt +++ b/notifications/translations/telegram/level_changed.txt @@ -1,6 +1,6 @@ { "en":{ "body":"🚀 A new level achieved!\n\nCongratulations! Your hard work is paying off, keep leveling up! 🏆", - "buttonText": "🙌 Check Your Level" + "buttonText": ["🙌 Check Your Level"] } } \ No newline at end of file diff --git a/notifications/translations/telegram/mining_ending_soon.txt b/notifications/translations/telegram/mining_ending_soon.txt index 2819d66..990508f 100644 --- a/notifications/translations/telegram/mining_ending_soon.txt +++ b/notifications/translations/telegram/mining_ending_soon.txt @@ -1,6 +1,6 @@ { "en": { "body": "🚨 Time's Running Out 🚨\n\nYou've got 1 hour left to extend your check-in session.", - "buttonText": "👉 Extend Session" + "buttonText": ["👉 Extend Session"] } } \ No newline at end of file diff --git a/notifications/translations/telegram/mining_expired.txt b/notifications/translations/telegram/mining_expired.txt index 90f84c7..0197d7b 100644 --- a/notifications/translations/telegram/mining_expired.txt +++ b/notifications/translations/telegram/mining_expired.txt @@ -1,6 +1,6 @@ { "en": { "body": "💔 Don't lose more coins!\n\nYou're losing coins for inactivity, come back and start your check-in session again.", - "buttonText": "👉 Start Session" + "buttonText": ["👉 Start Session"] } } \ No newline at end of file diff --git a/notifications/translations/telegram/mining_extend.txt b/notifications/translations/telegram/mining_extend.txt index 9d78a7c..6c21c61 100644 --- a/notifications/translations/telegram/mining_extend.txt +++ b/notifications/translations/telegram/mining_extend.txt @@ -1,6 +1,6 @@ { "en": { "body": "🚀 Extend your check-in session!🔓\n\n Press and hold the {{.TenantName}} logo button to keep earning {{.TokenName}} tokens. 💰", - "buttonText": "👉 Extend Session" + "buttonText": ["👉 Extend Session"] } } \ No newline at end of file diff --git a/notifications/translations/telegram/mining_not_active.txt b/notifications/translations/telegram/mining_not_active.txt index 4b76fc4..87eaced 100644 --- a/notifications/translations/telegram/mining_not_active.txt +++ b/notifications/translations/telegram/mining_not_active.txt @@ -1,6 +1,6 @@ { "en": { "body": "⏰ Tick-tock, tick-tock!\n\nKeep your coins safe by starting a new check-in session now.", - "buttonText": "👉 Start Session" + "buttonText": ["👉 Start Session"] } } \ No newline at end of file diff --git a/notifications/translations/telegram/new_referral.txt b/notifications/translations/telegram/new_referral.txt new file mode 100644 index 0000000..e17a350 --- /dev/null +++ b/notifications/translations/telegram/new_referral.txt @@ -0,0 +1,6 @@ +{ + "en":{ + "body":"🔥 {{.Username}} has joined your team.\n\nYou earned {{.Amount}} {{.Coin}} tokens! 🌟", + "buttonText": ["👉 View Profile"] + } +} diff --git a/notifications/translations/telegram/reply.txt b/notifications/translations/telegram/reply.txt index 736de87..785dae4 100644 --- a/notifications/translations/telegram/reply.txt +++ b/notifications/translations/telegram/reply.txt @@ -1,6 +1,6 @@ { "en":{ "body":"🎉 Hi, {{.Username}}!\n\nJoin to our app.", - "buttonText": "👉 Join the app" + "buttonText": ["👉 Join the app"] } } \ No newline at end of file diff --git a/notifications/translations/telegram/role_changed.txt b/notifications/translations/telegram/role_changed.txt index 8dd4b0b..31959af 100644 --- a/notifications/translations/telegram/role_changed.txt +++ b/notifications/translations/telegram/role_changed.txt @@ -1,6 +1,6 @@ { "en":{ "body":"🌟You’re a community hero!\n\nYou made it! Welcome to the AMBASSADOR team. 🚀", - "buttonText": "💼 View Role" + "buttonText": ["💼 View Role"] } } \ No newline at end of file diff --git a/notifications/translations/telegram/social_badge_unlocked.txt b/notifications/translations/telegram/social_badge_unlocked.txt index 9996c55..e8d6d58 100644 --- a/notifications/translations/telegram/social_badge_unlocked.txt +++ b/notifications/translations/telegram/social_badge_unlocked.txt @@ -1,6 +1,6 @@ { "en":{ "body":"🎉 New badge earned!\n\nYou've unlocked the {{.BadgeName}} social badge! Check it out in your profile.", - "buttonText": "🤩 View Badge" + "buttonText": ["🤩 View Badge"] } } \ No newline at end of file diff --git a/notifications/translations/telegram/socials.txt b/notifications/translations/telegram/socials.txt new file mode 100644 index 0000000..7099482 --- /dev/null +++ b/notifications/translations/telegram/socials.txt @@ -0,0 +1,12 @@ +{ + "en": { + "body": "🚀 Join our socials to stay updated on all the latest news and important updates!", + "buttonText": [ + "Follow us on X", + "Join us on Telegram", + "Follow Ice Open Network on X", + "Join Ice Open Network on Telegram", + "Follow Zeus on X" + ] + } +}