123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- package email
- import (
- "fmt"
- "strconv"
- "github.com/avct/uasurfer"
- "github.com/ente-io/museum/pkg/controller/lock"
- "github.com/ente-io/museum/pkg/repo"
- "github.com/ente-io/museum/pkg/utils/email"
- "github.com/ente-io/museum/pkg/utils/time"
- log "github.com/sirupsen/logrus"
- )
- const (
- WebAppFirstUploadTemplate = "web_app_first_upload.html"
- MobileAppFirstUploadTemplate = "mobile_app_first_upload.html"
- FirstUploadEmailSubject = "Congratulations! 🎉"
- StorageLimitExceededMailLock = "storage_limit_exceeded_mail_lock"
- StorageLimitExceededTemplateID = "storage_limit_exceeded"
- StorageLimitExceededTemplate = "storage_limit_exceeded.html"
- FilesCollectedTemplate = "files_collected.html"
- FilesCollectedTemplateID = "files_collected"
- FilesCollectedSubject = "You've got photos!"
- SubscriptionUpgradedTemplate = "subscription_upgraded.html"
- SubscriptionUpgradedSubject = "Thank you for choosing ente!"
- FilesCollectedMuteDurationInMinutes = 10
- StorageLimitExceededSubject = "[Alert] You have exceeded your storage limit"
- ReferralSuccessfulTemplate = "successful_referral.html"
- ReferralSuccessfulSubject = "You've earned 10 GB on ente! 🎁"
- )
- type EmailNotificationController struct {
- UserRepo *repo.UserRepository
- LockController *lock.LockController
- NotificationHistoryRepo *repo.NotificationHistoryRepository
- isSendingStorageLimitExceededMails bool
- }
- func (c *EmailNotificationController) OnFirstFileUpload(userID int64, userAgent string) {
- user, err := c.UserRepo.Get(userID)
- if err != nil {
- return
- }
- os := getOSFromUA(userAgent)
- template := WebAppFirstUploadTemplate
- if os == uasurfer.OSAndroid || os == uasurfer.OSiOS {
- template = MobileAppFirstUploadTemplate
- }
- err = email.SendTemplatedEmail([]string{user.Email}, "team@ente.io", "team@ente.io", FirstUploadEmailSubject, template, nil, nil)
- if err != nil {
- log.Error("Error sending first upload email ", err)
- }
- }
- func getOSFromUA(ua string) uasurfer.OSName {
- return uasurfer.Parse(ua).OS.Name
- }
- func (c *EmailNotificationController) OnSuccessfulReferral(userID int64) {
- user, err := c.UserRepo.Get(userID)
- if err != nil {
- return
- }
- err = email.SendTemplatedEmail([]string{user.Email}, "team@ente.io", "team@ente.io", ReferralSuccessfulSubject, ReferralSuccessfulTemplate, nil, nil)
- if err != nil {
- log.Error("Error sending first upload email ", err)
- }
- }
- func (c *EmailNotificationController) OnFilesCollected(userID int64) {
- user, err := c.UserRepo.Get(userID)
- if err != nil {
- return
- }
- lastNotificationTime, err := c.NotificationHistoryRepo.GetLastNotificationTime(userID, FilesCollectedTemplateID)
- logger := log.WithFields(log.Fields{
- "user_id": userID,
- })
- if err != nil {
- logger.Error("Could not fetch last notification time", err)
- return
- }
- if lastNotificationTime > time.MicrosecondsAfterMinutes(-FilesCollectedMuteDurationInMinutes) {
- logger.Info("Not notifying user about a collected file")
- return
- }
- lockName := "files_collected_" + strconv.FormatInt(userID, 10)
- lockStatus := c.LockController.TryLock(lockName, time.MicrosecondsAfterMinutes(FilesCollectedMuteDurationInMinutes))
- if !lockStatus {
- log.Error("Could not acquire lock to send file collected mails")
- return
- }
- defer c.LockController.ReleaseLock(lockName)
- logger.Info("Notifying about files collected")
- err = email.SendTemplatedEmail([]string{user.Email}, "team@ente.io", "team@ente.io", FilesCollectedSubject, FilesCollectedTemplate, nil, nil)
- if err != nil {
- log.Error("Error sending files collected email ", err)
- }
- c.NotificationHistoryRepo.SetLastNotificationTimeToNow(userID, FilesCollectedTemplateID)
- }
- func (c *EmailNotificationController) OnAccountUpgrade(userID int64) {
- user, err := c.UserRepo.Get(userID)
- if err != nil {
- log.Error("Could not find user to email", err)
- return
- }
- log.Info(fmt.Sprintf("Emailing on account upgrade %d", user.ID))
- err = email.SendTemplatedEmail([]string{user.Email}, "team@ente.io", "team@ente.io", SubscriptionUpgradedSubject, SubscriptionUpgradedTemplate, nil, nil)
- if err != nil {
- log.Error("Error sending files collected email ", err)
- }
- }
- func (c *EmailNotificationController) SendStorageLimitExceededMails() {
- if c.isSendingStorageLimitExceededMails {
- log.Info("Skipping sending storage limit exceeded mails as another instance is still running")
- return
- }
- c.setStorageLimitExceededMailerJobStatus(true)
- defer c.setStorageLimitExceededMailerJobStatus(false)
- lockStatus := c.LockController.TryLock(StorageLimitExceededMailLock, time.MicrosecondsAfterHours(24))
- if !lockStatus {
- log.Error("Could not acquire lock to send storage limit exceeded mails")
- return
- }
- defer c.LockController.ReleaseLock(StorageLimitExceededMailLock)
- users, err := c.UserRepo.GetUsersWithIndividualPlanWhoHaveExceededStorageQuota()
- if err != nil {
- log.Error("Error while fetching user list", err)
- return
- }
- for _, u := range users {
- lastNotificationTime, err := c.NotificationHistoryRepo.GetLastNotificationTime(u.ID, StorageLimitExceededTemplateID)
- logger := log.WithFields(log.Fields{
- "user_id": u.ID,
- })
- if err != nil {
- logger.Error("Could not fetch last notification time", err)
- continue
- }
- if lastNotificationTime > 0 {
- continue
- }
- logger.Info("Alerting about storage limit exceeded")
- err = email.SendTemplatedEmail([]string{u.Email}, "team@ente.io", "team@ente.io", StorageLimitExceededSubject, StorageLimitExceededTemplate, nil, nil)
- if err != nil {
- logger.Info("Error notifying", err)
- continue
- }
- c.NotificationHistoryRepo.SetLastNotificationTimeToNow(u.ID, StorageLimitExceededTemplateID)
- }
- }
- func (c *EmailNotificationController) setStorageLimitExceededMailerJobStatus(isSending bool) {
- c.isSendingStorageLimitExceededMails = isSending
- }
|