diff options
| author | 2025-10-23 13:37:50 +0700 | |
|---|---|---|
| committer | 2025-10-23 13:37:50 +0700 | |
| commit | 4b2da2abbc7376ce0de71a00b18b7091b00dbcd1 (patch) | |
| tree | 89e0aa5c62230ae91460231f521b6d7c5a19c740 /internal/mailer/mailer.go | |
| parent | bdd7f88f8bdb951babd18883ae20e6dbd9632202 (diff) | |
| download | web-4b2da2abbc7376ce0de71a00b18b7091b00dbcd1.tar.gz web-4b2da2abbc7376ce0de71a00b18b7091b00dbcd1.zip | |
feat: subscription settings
Diffstat (limited to 'internal/mailer/mailer.go')
| -rw-r--r-- | internal/mailer/mailer.go | 76 |
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 +} |