summaryrefslogtreecommitdiffci
path: root/internal/mailer/mailer.go
diff options
from:
to:
context:
space:
mode:
authorGravatar SayaAndy <saya.andy@posteo.com> 2025-10-23 13:37:50 +0700
committerGravatar SayaAndy <saya.andy@posteo.com> 2025-10-23 13:37:50 +0700
commit4b2da2abbc7376ce0de71a00b18b7091b00dbcd1 (patch)
tree89e0aa5c62230ae91460231f521b6d7c5a19c740 /internal/mailer/mailer.go
parentbdd7f88f8bdb951babd18883ae20e6dbd9632202 (diff)
downloadweb-4b2da2abbc7376ce0de71a00b18b7091b00dbcd1.tar.gz
web-4b2da2abbc7376ce0de71a00b18b7091b00dbcd1.zip
feat: subscription settings
Diffstat (limited to 'internal/mailer/mailer.go')
-rw-r--r--internal/mailer/mailer.go76
1 files changed, 76 insertions, 0 deletions
diff --git a/internal/mailer/mailer.go b/internal/mailer/mailer.go
index 450b818..cd5eda8 100644
--- a/internal/mailer/mailer.go
+++ b/internal/mailer/mailer.go
@@ -43,6 +43,14 @@ type Mailer struct {
l map[string]*locale.LocaleConfig
}
+type SubscriptionType int
+
+const (
+ All SubscriptionType = iota
+ None
+ Specific
+)
+
func NewMailer(db *sql.DB, clientHost string, mailHost string, publicName string, mailAddress string, username string, password string, salt []byte, localization map[string]*locale.LocaleConfig) (*Mailer, error) {
verificationCodes, err := ristretto.NewCache(&ristretto.Config[uint64, string]{
NumCounters: 10000,
@@ -279,3 +287,71 @@ func (m *Mailer) Verify(verificationCodeEncoded string, lang string) error {
delete(m.lostMailMap, verificationSegments[0])
return nil
}
+
+func (m *Mailer) GetSubscriptions(userId string) (subscriptionType SubscriptionType, tags []string, err error) {
+ tx, err := m.db.Begin()
+ if err != nil {
+ return None, nil, fmt.Errorf("failed to initialize transaction with db: %s", err)
+ }
+
+ hash := m.GetHash(userId)
+
+ var rows *sql.Rows
+ if rows, err = tx.Query(`SELECT tags FROM subscription_user_to_tags_table WHERE user_id=? LIMIT 1;`, hash); err != nil {
+ tx.Rollback()
+ return None, nil, fmt.Errorf("failed to query user-to-tags table in db for the user: %s", err)
+ }
+ defer tx.Commit()
+ defer rows.Close()
+
+ if !rows.Next() {
+ return None, nil, nil
+ }
+
+ tagsString := ""
+ if err = rows.Scan(&tagsString); err != nil {
+ return None, nil, fmt.Errorf("failed to scan the result from user-to-tags query: %s", err)
+ }
+
+ switch tagsString {
+ case "":
+ return None, nil, nil
+ case "_all":
+ return All, nil, nil
+ default:
+ return Specific, strings.Split(tagsString, ","), nil
+ }
+}
+
+func (m *Mailer) Subscribe(userId string, subscriptionType SubscriptionType, tags ...string) error {
+ tx, err := m.db.Begin()
+ if err != nil {
+ return fmt.Errorf("failed to initialize transaction with db: %s", err)
+ }
+
+ tagsOutput := ""
+ switch subscriptionType {
+ case All:
+ tagsOutput = "_all"
+ case None:
+ tagsOutput = ""
+ case Specific:
+ tagsOutput = strings.Join(tags, ",")
+ }
+
+ hash := m.GetHash(userId)
+
+ if _, err = tx.Exec(`INSERT INTO subscription_user_to_tags_table(user_id, tags) VALUES(?, ?)
+ ON CONFLICT(user_id) DO UPDATE SET
+ tags=excluded.tags;`, hash, tagsOutput); err != nil {
+ tx.Rollback()
+ return fmt.Errorf("failed to configure user-to-tags table in db for the user: %s", err)
+ }
+
+ if err = tx.Commit(); err != nil {
+ tx.Rollback()
+ return fmt.Errorf("failed to commit transaction to db: %s", err)
+ }
+
+ return nil
+}