feat: notification digests via SMTP
Adds a periodic inbox-summary email per opted-in user. SMTP is configured via appsettings (Smtp section); the digest is built from existing analytics (health score, top senders, recommendations) and sent by a new hourly DigestWorker, mirroring the GmailSyncWorker pattern. Frequency and send hour are configurable (Digest section). Backend: IEmailSender (SmtpEmailSender, MailKit), IDigestService, DigestWorker, new User.DigestEnabled/LastDigestSentUtc fields + migration, SettingsController for the per-user toggle and a send-now test endpoint, all scoped to the authenticated UserId. Frontend: SettingsApi + a bell/no-bell toggle button in the topbar. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -48,3 +48,25 @@ public class AiOptions
|
||||
public string OpenAiApiKey { get; set; } = string.Empty;
|
||||
public string OpenAiModel { get; set; } = "gpt-4o-mini";
|
||||
}
|
||||
|
||||
public class SmtpOptions
|
||||
{
|
||||
public const string SectionName = "Smtp";
|
||||
public bool Enabled { get; set; } = false;
|
||||
public string Host { get; set; } = string.Empty;
|
||||
public int Port { get; set; } = 587;
|
||||
public bool UseSsl { get; set; } = true;
|
||||
public string User { get; set; } = string.Empty;
|
||||
public string Password { get; set; } = string.Empty;
|
||||
public string FromAddress { get; set; } = string.Empty;
|
||||
public string FromName { get; set; } = "InboxIntel";
|
||||
}
|
||||
|
||||
public class DigestOptions
|
||||
{
|
||||
public const string SectionName = "Digest";
|
||||
/// <summary>How often a digest is sent to each opted-in user.</summary>
|
||||
public int FrequencyDays { get; set; } = 7;
|
||||
/// <summary>Hour (UTC) the background worker checks for due digests.</summary>
|
||||
public int SendHourUtc { get; set; } = 8;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user