158 lines
5.8 KiB
Go
158 lines
5.8 KiB
Go
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
|
|
}
|