diff --git a/cmd/bounce.go b/cmd/bounce.go index 7bf820115..4b23db126 100644 --- a/cmd/bounce.go +++ b/cmd/bounce.go @@ -204,6 +204,23 @@ func handleBounceWebhook(c echo.Context) error { } bounces = append(bounces, bs...) + // ForwardEmail. + case service == "forwardemail" && app.constants.BounceForwardemailEnabled: + var ( + sig = c.Request().Header.Get("X-Webhook-Signature") + ) + + bs, err := app.bounce.Forwardemail.ProcessBounce([]byte(sig), rawReq) + if err != nil { + app.log.Printf("error processing forwardemail notification: %v", err) + if _, ok := err.(*echo.HTTPError); ok { + return err + } + + return echo.NewHTTPError(http.StatusBadRequest, app.i18n.T("globals.messages.invalidData")) + } + bounces = append(bounces, bs...) + default: return echo.NewHTTPError(http.StatusBadRequest, app.i18n.Ts("bounces.unknownService")) } diff --git a/cmd/init.go b/cmd/init.go index c593a2ae0..632f0ac16 100644 --- a/cmd/init.go +++ b/cmd/init.go @@ -113,10 +113,11 @@ type constants struct { Extensions []string } - BounceWebhooksEnabled bool - BounceSESEnabled bool - BounceSendgridEnabled bool - BouncePostmarkEnabled bool + BounceWebhooksEnabled bool + BounceSESEnabled bool + BounceSendgridEnabled bool + BouncePostmarkEnabled bool + BounceForwardemailEnabled bool PermissionsRaw json.RawMessage Permissions map[string]struct{} @@ -432,6 +433,9 @@ func initConstants() *constants { c.BounceSESEnabled = ko.Bool("bounce.ses_enabled") c.BounceSendgridEnabled = ko.Bool("bounce.sendgrid_enabled") c.BouncePostmarkEnabled = ko.Bool("bounce.postmark.enabled") + c.BounceForwardemailEnabled = ko.Bool("bounce.forwardemail.enabled") + + fmt.Println(c.BounceForwardemailEnabled) c.HasLegacyUser = ko.Exists("app.admin_username") || ko.Exists("app.admin_password") @@ -709,6 +713,13 @@ func initBounceManager(app *App) *bounce.Manager { ko.String("bounce.postmark.username"), ko.String("bounce.postmark.password"), }, + ForwardEmail: struct { + Enabled bool + Key string + }{ + ko.Bool("bounce.forwardemail.enabled"), + ko.String("bounce.forwardemail.key"), + }, RecordBounceCB: app.core.RecordBounce, } diff --git a/cmd/settings.go b/cmd/settings.go index dca7258d4..60ec9d63a 100644 --- a/cmd/settings.go +++ b/cmd/settings.go @@ -67,11 +67,13 @@ func handleGetSettings(c echo.Context) error { for i := 0; i < len(s.Messengers); i++ { s.Messengers[i].Password = strings.Repeat(pwdMask, utf8.RuneCountInString(s.Messengers[i].Password)) } + s.UploadS3AwsSecretAccessKey = strings.Repeat(pwdMask, utf8.RuneCountInString(s.UploadS3AwsSecretAccessKey)) s.SendgridKey = strings.Repeat(pwdMask, utf8.RuneCountInString(s.SendgridKey)) + s.BouncePostmark.Password = strings.Repeat(pwdMask, utf8.RuneCountInString(s.BouncePostmark.Password)) + s.BounceForwardEmail.Key = strings.Repeat(pwdMask, utf8.RuneCountInString(s.BounceForwardEmail.Key)) s.SecurityCaptchaSecret = strings.Repeat(pwdMask, utf8.RuneCountInString(s.SecurityCaptchaSecret)) s.OIDC.ClientSecret = strings.Repeat(pwdMask, utf8.RuneCountInString(s.OIDC.ClientSecret)) - s.BouncePostmark.Password = strings.Repeat(pwdMask, utf8.RuneCountInString(s.BouncePostmark.Password)) return c.JSON(http.StatusOK, okResp{s}) } @@ -199,6 +201,9 @@ func handleUpdateSettings(c echo.Context) error { if set.BouncePostmark.Password == "" { set.BouncePostmark.Password = cur.BouncePostmark.Password } + if set.BounceForwardEmail.Key == "" { + set.BounceForwardEmail.Key = cur.BounceForwardEmail.Key + } if set.SecurityCaptchaSecret == "" { set.SecurityCaptchaSecret = cur.SecurityCaptchaSecret } diff --git a/cmd/upgrade.go b/cmd/upgrade.go index 5dff65974..b1ef418ed 100644 --- a/cmd/upgrade.go +++ b/cmd/upgrade.go @@ -39,6 +39,7 @@ var migList = []migFunc{ {"v2.5.0", migrations.V2_5_0}, {"v3.0.0", migrations.V3_0_0}, {"v4.0.0", migrations.V4_0_0}, + {"v4.1.0", migrations.V4_1_0}, } // upgrade upgrades the database to the current version by running SQL migration files diff --git a/docs/docs/content/bounces.md b/docs/docs/content/bounces.md index 1c8c1a4dd..e67e895fc 100644 --- a/docs/docs/content/bounces.md +++ b/docs/docs/content/bounces.md @@ -42,11 +42,12 @@ curl -u curl -u 'api_username:access_token' -X POST 'http://localhost:9000/webho ## External webhooks listmonk supports receiving bounce webhook events from the following SMTP providers. -| Endpoint | Description | More info | -|:----------------------------------------------------------|:---------------------------------------|:----------------------------------------------------------------------------------------------------------------------| -| `https://listmonk.yoursite.com/webhooks/service/ses` | Amazon (AWS) SES | See below | -| `https://listmonk.yoursite.com/webhooks/service/sendgrid` | Sendgrid / Twilio Signed event webhook | [More info](https://docs.sendgrid.com/for-developers/tracking-events/getting-started-event-webhook-security-features) | -| `https://listmonk.yoursite.com/webhooks/service/postmark` | Postmark webhook | [More info](https://postmarkapp.com/developer/webhooks/webhooks-overview) | +| Endpoint | Description | More info | +|:--------------------------------------------------------------|:---------------------------------------|:----------------------------------------------------------------------------------------------------------------------| +| `https://listmonk.yoursite.com/webhooks/service/ses` | Amazon (AWS) SES | See below | +| `https://listmonk.yoursite.com/webhooks/service/sendgrid` | Sendgrid / Twilio Signed event webhook | [More info](https://docs.sendgrid.com/for-developers/tracking-events/getting-started-event-webhook-security-features) | +| `https://listmonk.yoursite.com/webhooks/service/postmark` | Postmark webhook | [More info](https://postmarkapp.com/developer/webhooks/webhooks-overview) | +| `https://listmonk.yoursite.com/webhooks/service/forwardemail` | Forward Email webhook | [More info](https://forwardemail.net/en/faq#do-you-support-bounce-webhooks) | ## Amazon Simple Email Service (SES) diff --git a/docs/swagger/collections.yaml b/docs/swagger/collections.yaml index 48529b49c..6dabe6233 100644 --- a/docs/swagger/collections.yaml +++ b/docs/swagger/collections.yaml @@ -2705,6 +2705,8 @@ components: type: string settings.bounces.enableSendgrid: type: string + settings.bounces.enableForwardemail: + type: string settings.bounces.enablePostmark: type: string settings.bounces.enableWebhooks: @@ -2725,6 +2727,8 @@ components: type: string settings.bounces.sendgridKey: type: string + settings.bounces.forwardemailKey: + type: string settings.bounces.postmarkUsername: type: string settings.bounces.postmarkUsernameHelp: @@ -3408,6 +3412,10 @@ components: type: boolean bounce.sendgrid_key: type: string + bounce.forwardemail_enabled: + type: boolean + bounce.forwardemail_key: + type: string bounce.postmark_enabled: type: boolean bounce.postmark_username: diff --git a/frontend/src/views/Settings.vue b/frontend/src/views/Settings.vue index 301ce271f..92b4e2d53 100644 --- a/frontend/src/views/Settings.vue +++ b/frontend/src/views/Settings.vue @@ -172,6 +172,12 @@ export default Vue.extend({ hasDummy = 'postmark'; } + if (this.isDummy(form['bounce.forwardemail'].key)) { + form['bounce.forwardemail'].key = ''; + } else if (this.hasDummy(form['bounce.forwardemail'].key)) { + hasDummy = 'forwardemail'; + } + for (let i = 0; i < form.messengers.length; i += 1) { // If it's the dummy UI password placeholder, ignore it. if (this.isDummy(form.messengers[i].password)) { diff --git a/frontend/src/views/settings/bounces.vue b/frontend/src/views/settings/bounces.vue index 2df8fb27a..5b834a957 100644 --- a/frontend/src/views/settings/bounces.vue +++ b/frontend/src/views/settings/bounces.vue @@ -68,8 +68,9 @@
- +
@@ -83,8 +84,9 @@
- +
@@ -95,6 +97,21 @@
+
+
+ + + +
+
+ + + +
+
@@ -180,7 +197,8 @@ - + diff --git a/frontend/src/views/settings/smtp.vue b/frontend/src/views/settings/smtp.vue index e246b8e09..dec134608 100644 --- a/frontend/src/views/settings/smtp.vue +++ b/frontend/src/views/settings/smtp.vue @@ -73,6 +73,7 @@ Mailjet Sendgrid Postmark + Forward Email
@@ -165,8 +166,8 @@
- +
@@ -220,6 +221,9 @@ const smtpTemplates = { sendgrid: { host: 'smtp.sendgrid.net', port: 465, auth_protocol: 'login', tls_type: 'TLS', }, + forwardemail: { + host: 'smtp.forwardemail.net', port: 465, auth_protocol: 'login', tls_type: 'TLS', + }, postmark: { host: 'smtp.postmarkapp.com', port: 587, auth_protocol: 'cram', tls_type: 'STARTTLS', }, diff --git a/i18n/ca.json b/i18n/ca.json index 10ba3bed4..7315e2674 100644 --- a/i18n/ca.json +++ b/i18n/ca.json @@ -375,6 +375,7 @@ "settings.bounces.countHelp": "Nombre de rebots per subscriptor", "settings.bounces.delete": "Esborra", "settings.bounces.enable": "Activa el processament de rebots", + "settings.bounces.enableForwardemail": "Enable Forward Email", "settings.bounces.enableMailbox": "Activa la bústia de rebots", "settings.bounces.enablePostmark": "Activa Postmark", "settings.bounces.enableSES": "Activa SES", @@ -383,6 +384,7 @@ "settings.bounces.enabled": "Activat", "settings.bounces.folder": "Carpeta", "settings.bounces.folderHelp": "Nom de la carpeta IMAP a escanejar. Ex: Safata d'entrada.", + "settings.bounces.forwardemailKey": "Forward Email Key", "settings.bounces.hard": "Hard", "settings.bounces.invalidScanInterval": "L'interval d'escaneig ha de ser com a mínim d'1 minut.", "settings.bounces.name": "Rebots", diff --git a/i18n/cs-cz.json b/i18n/cs-cz.json index 3e5316c34..bd14c3079 100644 --- a/i18n/cs-cz.json +++ b/i18n/cs-cz.json @@ -375,6 +375,7 @@ "settings.bounces.countHelp": "Počet případů nedoručitelnosti na odběratele", "settings.bounces.delete": "Odstranit", "settings.bounces.enable": "Povolit zpracování nedoručitelnosti", + "settings.bounces.enableForwardemail": "Enable Forward Email", "settings.bounces.enableMailbox": "Povolit poštovní schránku v případě nedoručitelnosti", "settings.bounces.enablePostmark": "Povolit Postmark", "settings.bounces.enableSES": "Povolit SES", @@ -383,6 +384,7 @@ "settings.bounces.enabled": "Povoleno", "settings.bounces.folder": "Složka", "settings.bounces.folderHelp": "Název složky IMAP ke skenování. Např.: Došlá pošta.", + "settings.bounces.forwardemailKey": "Forward Email Key", "settings.bounces.hard": "Hard", "settings.bounces.invalidScanInterval": "Interval skenování v případě nedoručitelnosti by měl být minimálně 1 minuta.", "settings.bounces.name": "Případy nedoručitelnosti", diff --git a/i18n/cy.json b/i18n/cy.json index 5f78bdc78..1c7d66313 100644 --- a/i18n/cy.json +++ b/i18n/cy.json @@ -375,6 +375,7 @@ "settings.bounces.countHelp": "Nifer y pethau sydd wedi sboncio'n ôl fesul tanysgrifiwr", "settings.bounces.delete": "Dileu", "settings.bounces.enable": "Galluogi proses sboncio'n ôl", + "settings.bounces.enableForwardemail": "Enable Forward Email", "settings.bounces.enableMailbox": "Galluogi blwch post negeseuon sydd wedi sboncio'n ôl", "settings.bounces.enablePostmark": "Galluogi Postmark", "settings.bounces.enableSES": "Galluogi SES", @@ -383,6 +384,7 @@ "settings.bounces.enabled": "Wedi galluogi", "settings.bounces.folder": "Ffolder", "settings.bounces.folderHelp": "Enw'r ffolder IMAP i'w sganio. ee: blwch derbyn.", + "settings.bounces.forwardemailKey": "Forward Email Key", "settings.bounces.hard": "Hard", "settings.bounces.invalidScanInterval": "Dylai'r cyfnod sganio ar gyfer negeseuon sydd wedi sboncio'n ôl bara o leiaf 1 munud", "settings.bounces.name": "Wedi sboncio'n ôl", diff --git a/i18n/da.json b/i18n/da.json index d2fb0990e..aaea2d73e 100644 --- a/i18n/da.json +++ b/i18n/da.json @@ -373,6 +373,7 @@ "settings.bounces.count": "Antal afvisninger", "settings.bounces.countHelp": "Antal afvisninger pr. abonnent", "settings.bounces.enable": "Aktivér bounce behandling", + "settings.bounces.enableForwardemail": "Enable Forward Email", "settings.bounces.enableMailbox": "Aktivér bounce-postkasse", "settings.bounces.enablePostmark": "Aktivér poststempel", "settings.bounces.enableSES": "Aktiver SES", @@ -381,6 +382,7 @@ "settings.bounces.enabled": "Aktiveret", "settings.bounces.folder": "Mappe", "settings.bounces.folderHelp": "Navnet på den IMAP-mappe, der skal scannes. F.eks.: Indbakke.", + "settings.bounces.forwardemailKey": "Forward Email Key", "settings.bounces.invalidScanInterval": "Bounce skanningsinterval skal være mindst 1 minut.", "settings.bounces.name": "Fejlsendt", "settings.bounces.none": "Ingen", diff --git a/i18n/de.json b/i18n/de.json index a8aece2e0..f0e3d998a 100644 --- a/i18n/de.json +++ b/i18n/de.json @@ -373,6 +373,7 @@ "settings.bounces.count": "Bounce Anzahl", "settings.bounces.countHelp": "Anzahl von Bounces pro Abonnent", "settings.bounces.enable": "Verarbeiten von Bounces aktivieren", + "settings.bounces.enableForwardemail": "Enable Forward Email", "settings.bounces.enableMailbox": "Bounce-Postfach aktivieren", "settings.bounces.enablePostmark": "Postmark aktivieren", "settings.bounces.enableSES": "SES aktivieren", @@ -381,6 +382,7 @@ "settings.bounces.enabled": "Aktiviert", "settings.bounces.folder": "Ordner", "settings.bounces.folderHelp": "Name des zu scannenden IMAP-Ordners. z.B.: Inbox.", + "settings.bounces.forwardemailKey": "Forward Email Key", "settings.bounces.invalidScanInterval": "Der Bounce Scan-Interval sollte mindestens 1 Minute betragen.", "settings.bounces.name": "Bounces", "settings.bounces.none": "Keine", diff --git a/i18n/el.json b/i18n/el.json index 4501afe48..e6489801d 100644 --- a/i18n/el.json +++ b/i18n/el.json @@ -373,6 +373,7 @@ "settings.bounces.count": "Πλήθος bounce", "settings.bounces.countHelp": "Αριθμός bounce ανά συνδρομητή", "settings.bounces.enable": "Ενεργοποίηση επεξεργασίας bounce", + "settings.bounces.enableForwardemail": "Enable Forward Email", "settings.bounces.enableMailbox": "Ενεργοποίηση γραμματοκιβωτίου για τα bounce", "settings.bounces.enablePostmark": "Ενεργοποίηση Postmark", "settings.bounces.enableSES": "Ενεργοποίηση SES", @@ -381,6 +382,7 @@ "settings.bounces.enabled": "Ενεργοποιημένο", "settings.bounces.folder": "Φάκελος", "settings.bounces.folderHelp": "Όνομα του φακέλου IMAP προς περιοδική σάρωση. Π.χ.: Εισερχόμενα.", + "settings.bounces.forwardemailKey": "Forward Email Key", "settings.bounces.invalidScanInterval": "Το διάστημα σάρωσης για αναγνώριση των bounce πρέπει να είναι τουλάχιστον 1 λεπτό.", "settings.bounces.name": "Bounce", "settings.bounces.none": "Κανένα", diff --git a/i18n/en.json b/i18n/en.json index 5364785df..a85fd5635 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -373,6 +373,7 @@ "settings.bounces.count": "Bounce count", "settings.bounces.countHelp": "Number of bounces per subscriber", "settings.bounces.enable": "Enable bounce processing", + "settings.bounces.enableForwardemail": "Enable Forward Email", "settings.bounces.enableMailbox": "Enable bounce mailbox", "settings.bounces.enablePostmark": "Enable Postmark", "settings.bounces.enableSES": "Enable SES", @@ -381,6 +382,7 @@ "settings.bounces.enabled": "Enabled", "settings.bounces.folder": "Folder", "settings.bounces.folderHelp": "Name of the IMAP folder to scan. Eg: Inbox.", + "settings.bounces.forwardemailKey": "Forward Email Key", "settings.bounces.invalidScanInterval": "Bounce scan interval should be minimum 1 minute.", "settings.bounces.name": "Bounces", "settings.bounces.none": "None", diff --git a/i18n/eo.json b/i18n/eo.json index 3d05f2502..79c6cd053 100644 --- a/i18n/eo.json +++ b/i18n/eo.json @@ -375,6 +375,7 @@ "settings.bounces.countHelp": "Nombre de rebots per subscriptor", "settings.bounces.delete": "Esborra", "settings.bounces.enable": "Activa el processament de rebots", + "settings.bounces.enableForwardemail": "Enable Forward Email", "settings.bounces.enableMailbox": "Activa la bústia de rebots", "settings.bounces.enablePostmark": "Activa Postmark", "settings.bounces.enableSES": "Activa SES", @@ -383,6 +384,7 @@ "settings.bounces.enabled": "Activat", "settings.bounces.folder": "Carpeta", "settings.bounces.folderHelp": "Nom de la carpeta IMAP a escanejar. Ex: Safata d'entrada.", + "settings.bounces.forwardemailKey": "Forward Email Key", "settings.bounces.hard": "Hard", "settings.bounces.invalidScanInterval": "L'interval d'escaneig ha de ser com a mínim d'1 minut.", "settings.bounces.name": "Rebots", diff --git a/i18n/es.json b/i18n/es.json index fa4c26f33..6de21bb1a 100644 --- a/i18n/es.json +++ b/i18n/es.json @@ -376,6 +376,7 @@ "settings.bounces.countHelp": "Número de rebotes por suscripción", "settings.bounces.delete": "Eliminar", "settings.bounces.enable": "Activar el procesamiento de rebotes", + "settings.bounces.enableForwardemail": "Enable Forward Email", "settings.bounces.enableMailbox": "Activar el buzón de rebotes", "settings.bounces.enablePostmark": "Activar Postmark", "settings.bounces.enableSES": "Activar SES", @@ -384,6 +385,7 @@ "settings.bounces.enabled": "Activado", "settings.bounces.folder": "Carpeta", "settings.bounces.folderHelp": "Nombre de la carpeta IMAP a escanear, por ejemplo: Entrada.", + "settings.bounces.forwardemailKey": "Forward Email Key", "settings.bounces.hard": "Hard", "settings.bounces.invalidScanInterval": "El intervalo mínimo de escanéo de los rebotes debería de ser 1 minuto.", "settings.bounces.name": "Rebotes", diff --git a/i18n/fi.json b/i18n/fi.json index 7f42c481a..bf0532449 100644 --- a/i18n/fi.json +++ b/i18n/fi.json @@ -376,6 +376,7 @@ "settings.bounces.countHelp": "Palautuksien lukumäärä tilaajaa kohden", "settings.bounces.delete": "Delete", "settings.bounces.enable": "Ota käyttöön bounce-käsittely", + "settings.bounces.enableForwardemail": "Enable Forward Email", "settings.bounces.enableMailbox": "Ota käyttöön bounce-postilaatikko", "settings.bounces.enablePostmark": "Ota käyttöön Postmark", "settings.bounces.enableSES": "Ota käyttöön SES", @@ -384,6 +385,7 @@ "settings.bounces.enabled": "Käytössä", "settings.bounces.folder": "Kansio", "settings.bounces.folderHelp": "IMAP-kansion nimi, joka tarkistetaan. Esim. Saapuneet.", + "settings.bounces.forwardemailKey": "Forward Email Key", "settings.bounces.hard": "Hard", "settings.bounces.invalidScanInterval": "Palautusten skannausintervallin pitää olla vähintään 1 minuutti.", "settings.bounces.name": "Palautukset", diff --git a/i18n/fr-CA.json b/i18n/fr-CA.json index 1da5e986c..21f4d0f20 100644 --- a/i18n/fr-CA.json +++ b/i18n/fr-CA.json @@ -376,6 +376,7 @@ "settings.bounces.countHelp": "Nombre de rebonds par abonné", "settings.bounces.delete": "Effacer", "settings.bounces.enable": "Activer le traitement des rebonds", + "settings.bounces.enableForwardemail": "Enable Forward Email", "settings.bounces.enableMailbox": "Activer la boîte aux lettres de rebond", "settings.bounces.enablePostmark": "Activer Postmark", "settings.bounces.enableSES": "Activer SES", @@ -384,6 +385,7 @@ "settings.bounces.enabled": "Activer", "settings.bounces.folder": "Dossier", "settings.bounces.folderHelp": "Nom du dossier IMAP à scanner. Exple : InBox.", + "settings.bounces.forwardemailKey": "Forward Email Key", "settings.bounces.hard": "Hard", "settings.bounces.invalidScanInterval": "L'intervalle de 'scan' des rebonds doit être d'au moins 1 minute.", "settings.bounces.name": "Rebonds", diff --git a/i18n/fr.json b/i18n/fr.json index 43acc832b..8857d21ca 100644 --- a/i18n/fr.json +++ b/i18n/fr.json @@ -376,6 +376,7 @@ "settings.bounces.countHelp": "Nombre de rebonds par abonné", "settings.bounces.delete": "Effacer", "settings.bounces.enable": "Activer le traitement des rebonds", + "settings.bounces.enableForwardemail": "Enable Forward Email", "settings.bounces.enableMailbox": "Activer la boîte aux lettres de rebond", "settings.bounces.enablePostmark": "Activer Postmark", "settings.bounces.enableSES": "Activer SES", @@ -384,6 +385,7 @@ "settings.bounces.enabled": "Activer", "settings.bounces.folder": "Dossier", "settings.bounces.folderHelp": "Nom du dossier IMAP à scanner. Exple : InBox.", + "settings.bounces.forwardemailKey": "Forward Email Key", "settings.bounces.hard": "Hard", "settings.bounces.invalidScanInterval": "L'intervalle de 'scan' des rebonds doit être d'au moins 1 minute.", "settings.bounces.name": "Rebonds", diff --git a/i18n/he.json b/i18n/he.json index 4fb2d8106..aa01fe38b 100644 --- a/i18n/he.json +++ b/i18n/he.json @@ -373,6 +373,7 @@ "settings.bounces.count": "ספירת השטחות", "settings.bounces.countHelp": "מספר השטחות למנוי", "settings.bounces.enable": "הפעלת תהליך החזרת הודעות שטחות", + "settings.bounces.enableForwardemail": "Enable Forward Email", "settings.bounces.enableMailbox": "הפעלת תיבת הודעות שטחות", "settings.bounces.enablePostmark": "הפעלת Postmark", "settings.bounces.enableSES": "הפעלת SES", @@ -381,6 +382,7 @@ "settings.bounces.enabled": "מופעל", "settings.bounces.folder": "תיקייה", "settings.bounces.folderHelp": "שם התיקייה של שורת הכתובת החדשה שמתקשרת עם שימוש. לדוגמה: Inbox.", + "settings.bounces.forwardemailKey": "Forward Email Key", "settings.bounces.invalidScanInterval": "מרווח הסריקה לשטחות צריך להיות מינימום של דקה אחת.", "settings.bounces.name": "השטחות", "settings.bounces.none": "אין", diff --git a/i18n/hu.json b/i18n/hu.json index 808dc6ec1..3243a37b0 100644 --- a/i18n/hu.json +++ b/i18n/hu.json @@ -375,6 +375,7 @@ "settings.bounces.countHelp": "Visszapattanások száma tagokra lebontva", "settings.bounces.delete": "Törlés", "settings.bounces.enable": "Visszapattanások feldolgozása", + "settings.bounces.enableForwardemail": "Enable Forward Email", "settings.bounces.enableMailbox": "Visszapattanó postafiók", "settings.bounces.enablePostmark": "Postmark", "settings.bounces.enableSES": "SES", @@ -383,6 +384,7 @@ "settings.bounces.enabled": "Engedélyezve", "settings.bounces.folder": "Mappa", "settings.bounces.folderHelp": "A vizsgálandó IMAP mappa neve. Például: Beérkezett üzenetek", + "settings.bounces.forwardemailKey": "Forward Email Key", "settings.bounces.hard": "Kemény", "settings.bounces.invalidScanInterval": "Az ellenőrzés gyakorisága 1 percnél nagyobb kell legyen.", "settings.bounces.name": "Visszapattanók", @@ -606,6 +608,7 @@ "templates.subject": "Tárgy", "users.apiOneTimeToken": "Másolja ki most az API hozzáférési tokent. Nem jelenik meg újra.", "users.cantDeleteRole": "A használatban lévő szerepkör nem törölhető.", + "users.firstTime": "This is a fresh install. Pick a username and password for the Super Admin account.", "users.invalidLogin": "Érvénytelen bejelentkezési név vagy jelszó", "users.invalidRequest": "Érvénytelen hitelesítési kérelem", "users.lastLogin": "Utolsó bejelentkezés", diff --git a/i18n/it.json b/i18n/it.json index ac2086525..874148f5e 100644 --- a/i18n/it.json +++ b/i18n/it.json @@ -373,6 +373,7 @@ "settings.bounces.count": "Numero di rimbalzi", "settings.bounces.countHelp": "Numero di rimbalzi per iscritto", "settings.bounces.enable": "Abilita il processamento dei rimbalzi", + "settings.bounces.enableForwardemail": "Enable Forward Email", "settings.bounces.enableMailbox": "Abilita la casella di posta per i rimbalzi", "settings.bounces.enablePostmark": "Attiva Postmark", "settings.bounces.enableSES": "Attiva SES", @@ -381,6 +382,7 @@ "settings.bounces.enabled": "Attivato", "settings.bounces.folder": "Cartella", "settings.bounces.folderHelp": "Nome della cartella IMAP da analizzare. Ad esempio: Posta in arrivo.", + "settings.bounces.forwardemailKey": "Forward Email Key", "settings.bounces.invalidScanInterval": "L'intervallo di scansione dei rimbalzi deve essere di almeno 1 minuto.", "settings.bounces.name": "Rimbalzi", "settings.bounces.none": "Nessuno", diff --git a/i18n/jp.json b/i18n/jp.json index a3e265c18..6cfe65a95 100644 --- a/i18n/jp.json +++ b/i18n/jp.json @@ -376,6 +376,7 @@ "settings.bounces.countHelp": "加入者ごとのバウンス数", "settings.bounces.delete": "削除", "settings.bounces.enable": "バウンス処理を有効にする", + "settings.bounces.enableForwardemail": "Enable Forward Email", "settings.bounces.enableMailbox": "バウンスメールボックスを有効にする", "settings.bounces.enablePostmark": "Postmarkを有効にする", "settings.bounces.enableSES": "SESを有効にする", @@ -384,6 +385,7 @@ "settings.bounces.enabled": "有効", "settings.bounces.folder": "フォルダ", "settings.bounces.folderHelp": "スキャンするIMAPフォルダの名前。 例: Inbox.", + "settings.bounces.forwardemailKey": "Forward Email Key", "settings.bounces.hard": "Hard", "settings.bounces.invalidScanInterval": "バウンススキャン間隔は最低1分。", "settings.bounces.name": "バウンス", diff --git a/i18n/ml.json b/i18n/ml.json index 165e8a83a..6f50117bb 100644 --- a/i18n/ml.json +++ b/i18n/ml.json @@ -375,6 +375,7 @@ "settings.bounces.countHelp": "വരിക്കാർക്കു ആനുപാതികയി ബൗൺസുകളുടെ എണ്ണം", "settings.bounces.delete": "നീക്കം ചെയ്യുക", "settings.bounces.enable": "ബൗൺസ് പ്രോസസ്സിംഗ് പ്രവർത്തനക്ഷമമാക്കുക", + "settings.bounces.enableForwardemail": "Enable Forward Email", "settings.bounces.enableMailbox": "ബൗൺസ് മെയിൽബോക്സ് പ്രവർത്തനക്ഷമമാക്കുക", "settings.bounces.enablePostmark": "Postmark പ്രവർത്തനക്ഷമമാക്കുക", "settings.bounces.enableSES": "SES പ്രവർത്തനക്ഷമമാക്കുക", @@ -383,6 +384,7 @@ "settings.bounces.enabled": "പ്രവർത്തനക്ഷമമാക്കി", "settings.bounces.folder": "ഫോൾഡർ", "settings.bounces.folderHelp": "സ്കാൻ ചെയ്യാനുള്ള IMAP ഫോൾഡറിന്റെ പേര്. ഉദാ: ഇൻബോക്സ്.", + "settings.bounces.forwardemailKey": "Forward Email Key", "settings.bounces.hard": "Hard", "settings.bounces.invalidScanInterval": "ബൗൺസ് സ്കാൻ ചെയ്യാനുള്ള ഏറ്റവും കുറഞ്ഞ ഇടവേള 1 മിനിറ്റായിരിക്കണം.", "settings.bounces.name": "ബൗൺസുകൾ", diff --git a/i18n/nl.json b/i18n/nl.json index 646a49d03..01fda0460 100644 --- a/i18n/nl.json +++ b/i18n/nl.json @@ -375,6 +375,7 @@ "settings.bounces.countHelp": "Aantal bounces per abonnee", "settings.bounces.delete": "Verwijder", "settings.bounces.enable": "Bounce processing inschakelen", + "settings.bounces.enableForwardemail": "Enable Forward Email", "settings.bounces.enableMailbox": "Bounce mailbox inschakelen", "settings.bounces.enablePostmark": "Postmark inschakelen", "settings.bounces.enableSES": "SES inschakelen", @@ -383,6 +384,7 @@ "settings.bounces.enabled": "Ingeschakeld", "settings.bounces.folder": "Map", "settings.bounces.folderHelp": "Naam van de IMAP map om te scannen. Bv.: Inbox.", + "settings.bounces.forwardemailKey": "Forward Email Key", "settings.bounces.hard": "Hard", "settings.bounces.invalidScanInterval": "Bounce scan interval moet minstens 1 minuut zijn.", "settings.bounces.name": "Bounces", diff --git a/i18n/pl.json b/i18n/pl.json index 6a9136e1a..12dfe0e81 100644 --- a/i18n/pl.json +++ b/i18n/pl.json @@ -376,6 +376,7 @@ "settings.bounces.countHelp": "Liczba odbić na subskrybenta", "settings.bounces.delete": "Usuń", "settings.bounces.enable": "Włącz procesowanie odbić", + "settings.bounces.enableForwardemail": "Enable Forward Email", "settings.bounces.enableMailbox": "Włącz skrzynkę pocztową z odbiciami", "settings.bounces.enablePostmark": "Włącz Postmark", "settings.bounces.enableSES": "Włącz SES", @@ -384,6 +385,7 @@ "settings.bounces.enabled": "Włączone", "settings.bounces.folder": "Folder", "settings.bounces.folderHelp": "Nazwa folderu IMAP do skanowania. Np: Inbox.", + "settings.bounces.forwardemailKey": "Forward Email Key", "settings.bounces.hard": "Hard", "settings.bounces.invalidScanInterval": "Interwał czasu powinien być minimum 1 minuta.", "settings.bounces.name": "Odbicia", diff --git a/i18n/pt-BR.json b/i18n/pt-BR.json index d9c634b50..83a0b7ec9 100644 --- a/i18n/pt-BR.json +++ b/i18n/pt-BR.json @@ -375,6 +375,7 @@ "settings.bounces.countHelp": "Número de bounces por assinante", "settings.bounces.delete": "Deletar", "settings.bounces.enable": "Ativar processamento de bounce", + "settings.bounces.enableForwardemail": "Enable Forward Email", "settings.bounces.enableMailbox": "Ativar caixa de email de bounce", "settings.bounces.enablePostmark": "Ativar Postmark", "settings.bounces.enableSES": "Ativar SES", @@ -383,6 +384,7 @@ "settings.bounces.enabled": "Ativado", "settings.bounces.folder": "Pasta", "settings.bounces.folderHelp": "Noma da pasta IMAP para escanear. Ex: Inbox.", + "settings.bounces.forwardemailKey": "Forward Email Key", "settings.bounces.hard": "Hard", "settings.bounces.invalidScanInterval": "Intervalo de escaneamento de Bounce deve ser no mínimo 1 minuto.", "settings.bounces.name": "Rejeições", diff --git a/i18n/pt.json b/i18n/pt.json index 696395763..e3bbe937b 100644 --- a/i18n/pt.json +++ b/i18n/pt.json @@ -375,6 +375,7 @@ "settings.bounces.countHelp": "Número de bounces por subscritor", "settings.bounces.delete": "Eliminar", "settings.bounces.enable": "Ligar processamento de bounces", + "settings.bounces.enableForwardemail": "Enable Forward Email", "settings.bounces.enableMailbox": "Ligar caixa de correio de bounces", "settings.bounces.enablePostmark": "Ligar Postmark", "settings.bounces.enableSES": "Ligar SES", @@ -383,6 +384,7 @@ "settings.bounces.enabled": "Ligado", "settings.bounces.folder": "Pasta", "settings.bounces.folderHelp": "Nome da pasta IMAP para procurar. E.g.: Inbox.", + "settings.bounces.forwardemailKey": "Forward Email Key", "settings.bounces.hard": "Hard", "settings.bounces.invalidScanInterval": "Intervalo de procura de bounces deve ser, no mínimo, 1 minuto.", "settings.bounces.name": "Rejeições", diff --git a/i18n/ro.json b/i18n/ro.json index dae7cfd18..d8e12d9ec 100644 --- a/i18n/ro.json +++ b/i18n/ro.json @@ -376,6 +376,7 @@ "settings.bounces.countHelp": "Numărul de bounce-uri per abonat", "settings.bounces.delete": "settings.bounces.delete", "settings.bounces.enable": "Activați procesarea săririi", + "settings.bounces.enableForwardemail": "Enable Forward Email", "settings.bounces.enableMailbox": "Activați cutia poștală de respingere", "settings.bounces.enablePostmark": "Activați Postmark", "settings.bounces.enableSES": "Activați SES", @@ -384,6 +385,7 @@ "settings.bounces.enabled": "Activat", "settings.bounces.folder": "Director", "settings.bounces.folderHelp": "Numele folderului IMAP pentru a scana. De exemplu: Inbox.", + "settings.bounces.forwardemailKey": "Forward Email Key", "settings.bounces.hard": "settings.bounces.hard", "settings.bounces.invalidScanInterval": "Intervalul de scanare a săririi ar trebui să fie de minim 1 minut.", "settings.bounces.name": "Neachitate", diff --git a/i18n/ru.json b/i18n/ru.json index 65fb4be8b..e97fb04fa 100644 --- a/i18n/ru.json +++ b/i18n/ru.json @@ -375,6 +375,7 @@ "settings.bounces.countHelp": "Количество отказов на одного абонента", "settings.bounces.delete": "Удалить", "settings.bounces.enable": "Включить обработку отказов", + "settings.bounces.enableForwardemail": "Enable Forward Email", "settings.bounces.enableMailbox": "Включить почтовый ящик с отскоком", "settings.bounces.enablePostmark": "Включить Postmark", "settings.bounces.enableSES": "Включить SES", @@ -383,6 +384,7 @@ "settings.bounces.enabled": "Включено", "settings.bounces.folder": "Папка", "settings.bounces.folderHelp": "Имя папки IMAP для сканирования. Например: Входящие.", + "settings.bounces.forwardemailKey": "Forward Email Key", "settings.bounces.hard": "Hard", "settings.bounces.invalidScanInterval": "Интервал сканирования скачков должен составлять минимум 1 минуту.", "settings.bounces.name": "Отскоки", diff --git a/i18n/se.json b/i18n/se.json index 801f95c2c..a44a460bb 100644 --- a/i18n/se.json +++ b/i18n/se.json @@ -375,6 +375,7 @@ "settings.bounces.countHelp": "Antal studsar per prenumerant", "settings.bounces.delete": "Delete", "settings.bounces.enable": "Aktivera studsbehandling", + "settings.bounces.enableForwardemail": "Enable Forward Email", "settings.bounces.enableMailbox": "Aktivera studs-e-postlåda", "settings.bounces.enablePostmark": "Aktivera Postmark", "settings.bounces.enableSES": "Aktivera SES", @@ -383,6 +384,7 @@ "settings.bounces.enabled": "Aktiverad", "settings.bounces.folder": "Mapp", "settings.bounces.folderHelp": "Namn på IMAP-mappen att skanna. t.ex: Inkorgen.", + "settings.bounces.forwardemailKey": "Forward Email Key", "settings.bounces.hard": "Hard", "settings.bounces.invalidScanInterval": "Studsskanningsintervall bör vara minst 1 minut.", "settings.bounces.name": "Bounceadresser", diff --git a/i18n/sk.json b/i18n/sk.json index fc122118a..40eada6bf 100644 --- a/i18n/sk.json +++ b/i18n/sk.json @@ -375,6 +375,7 @@ "settings.bounces.countHelp": "Počet nedoručiteľných na odberateľa", "settings.bounces.delete": "Odstrániť", "settings.bounces.enable": "Zapnúť spracovanie nedoručiteľných", + "settings.bounces.enableForwardemail": "Enable Forward Email", "settings.bounces.enableMailbox": "Povoliť poštovú schránku pre nedoručiteľných", "settings.bounces.enablePostmark": "Zapnúť Postmark", "settings.bounces.enableSES": "Zapnúť SES", @@ -383,6 +384,7 @@ "settings.bounces.enabled": "Zapnuté", "settings.bounces.folder": "Priečinok", "settings.bounces.folderHelp": "Názov kontrolovaného priečinku IMAP. Napríklad INBOX.", + "settings.bounces.forwardemailKey": "Forward Email Key", "settings.bounces.hard": "Hard", "settings.bounces.invalidScanInterval": "Interval kontroly nedoručiteľných by mal byť minimálne 1 minúta.", "settings.bounces.name": "Nedoručiteľné", diff --git a/i18n/sl.json b/i18n/sl.json index 03e1ca82f..ec67f0024 100644 --- a/i18n/sl.json +++ b/i18n/sl.json @@ -373,6 +373,7 @@ "settings.bounces.count": "Število odklonov", "settings.bounces.countHelp": "Število odklonov na naročnika", "settings.bounces.enable": "Omogoči obdelavo odklonov", + "settings.bounces.enableForwardemail": "Enable Forward Email", "settings.bounces.enableMailbox": "Omogoči zavrnjeni nabiralnik", "settings.bounces.enablePostmark": "Omogoči poštni žig", "settings.bounces.enableSES": "Omogoči SES", @@ -381,6 +382,7 @@ "settings.bounces.enabled": "Omogočeno", "settings.bounces.folder": "Mapa", "settings.bounces.folderHelp": "Ime mape IMAP za skeniranje. Npr.: Prejeto.", + "settings.bounces.forwardemailKey": "Forward Email Key", "settings.bounces.invalidScanInterval": "Interval odbojnega skeniranja mora biti najmanj 1 minuta.", "settings.bounces.name": "Odboji", "settings.bounces.none": "Brez", diff --git a/i18n/tr.json b/i18n/tr.json index 33c88b0f5..1fbee52b6 100644 --- a/i18n/tr.json +++ b/i18n/tr.json @@ -376,6 +376,7 @@ "settings.bounces.countHelp": "Abone başına geri dönüş sayısı", "settings.bounces.delete": "Sil", "settings.bounces.enable": "Sıçrama işlemeyi etkinleştirin", + "settings.bounces.enableForwardemail": "Enable Forward Email", "settings.bounces.enableMailbox": "Geri dönen posta kutusunu etkinleştirin", "settings.bounces.enablePostmark": "Postmark'i etkinleştirin", "settings.bounces.enableSES": "SES'i etkinleştirin", @@ -384,6 +385,7 @@ "settings.bounces.enabled": "Etkinleştir", "settings.bounces.folder": "Dizin", "settings.bounces.folderHelp": "Taranacak IMAP klasörünün adı. Örn: Gelen Kutusu.", + "settings.bounces.forwardemailKey": "Forward Email Key", "settings.bounces.hard": "Hard", "settings.bounces.invalidScanInterval": "Sıçrama tarama aralığı en az 1 dakika olmalıdır.", "settings.bounces.name": "Sıçramalar", diff --git a/i18n/uk.json b/i18n/uk.json index e43d5d7e7..aff9330e6 100644 --- a/i18n/uk.json +++ b/i18n/uk.json @@ -373,6 +373,7 @@ "settings.bounces.count": "Кількість помилок", "settings.bounces.countHelp": "Кількість помилок у підписни_ці", "settings.bounces.enable": "Обробляти помилки", + "settings.bounces.enableForwardemail": "Enable Forward Email", "settings.bounces.enableMailbox": "Помилки приходять на пошту", "settings.bounces.enablePostmark": "Вебхук для Postmark", "settings.bounces.enableSES": "Вебхук для SES", @@ -381,6 +382,7 @@ "settings.bounces.enabled": "Увімкнено", "settings.bounces.folder": "Тека", "settings.bounces.folderHelp": "Назва IMAP-теки, яку слід сканувати, наприклад Inbox.", + "settings.bounces.forwardemailKey": "Forward Email Key", "settings.bounces.invalidScanInterval": "Мінімальна частота опитування скриньки помилок — 1 хвилина.", "settings.bounces.name": "Помилки", "settings.bounces.none": "Нема", diff --git a/i18n/vi.json b/i18n/vi.json index 223370968..56afd403d 100644 --- a/i18n/vi.json +++ b/i18n/vi.json @@ -376,6 +376,7 @@ "settings.bounces.countHelp": "Số trang không truy cập cho mỗi người đăng ký", "settings.bounces.delete": "Xóa", "settings.bounces.enable": "Bật xử lý số trang không truy cập", + "settings.bounces.enableForwardemail": "Enable Forward Email", "settings.bounces.enableMailbox": "Bật hộp thư bị trả lại", "settings.bounces.enablePostmark": "Bật Postmark", "settings.bounces.enableSES": "Bật SES", @@ -384,6 +385,7 @@ "settings.bounces.enabled": "Đã bật", "settings.bounces.folder": "Thư mục", "settings.bounces.folderHelp": "Tên của thư mục IMAP để quét. Vd: Hộp thư đến.", + "settings.bounces.forwardemailKey": "Forward Email Key", "settings.bounces.hard": "Hard", "settings.bounces.invalidScanInterval": "Khoảng thời gian quét bị trả lại phải tối thiểu là 1 phút.", "settings.bounces.name": "Bị trả lại", diff --git a/i18n/zh-CN.json b/i18n/zh-CN.json index e06739066..25bf6060d 100644 --- a/i18n/zh-CN.json +++ b/i18n/zh-CN.json @@ -375,6 +375,7 @@ "settings.bounces.countHelp": "每个订阅者的反弹次数", "settings.bounces.delete": "删除", "settings.bounces.enable": "启用退回处理", + "settings.bounces.enableForwardemail": "Enable Forward Email", "settings.bounces.enableMailbox": "启用退回邮箱", "settings.bounces.enablePostmark": "启用Postmark", "settings.bounces.enableSES": "启用SES", @@ -383,6 +384,7 @@ "settings.bounces.enabled": "已启用", "settings.bounces.folder": "文件夹", "settings.bounces.folderHelp": "要扫描的 IMAP 文件夹的名称。例如:收件箱。", + "settings.bounces.forwardemailKey": "Forward Email Key", "settings.bounces.hard": "Hard", "settings.bounces.invalidScanInterval": "反弹扫描间隔应至少为 1 分钟。", "settings.bounces.name": "反弹", diff --git a/i18n/zh-TW.json b/i18n/zh-TW.json index 8d09981a8..1593250d9 100644 --- a/i18n/zh-TW.json +++ b/i18n/zh-TW.json @@ -376,6 +376,7 @@ "settings.bounces.countHelp": "每個訂閱者的退回次數", "settings.bounces.delete": "刪除", "settings.bounces.enable": "啟用退回信件處理", + "settings.bounces.enableForwardemail": "Enable Forward Email", "settings.bounces.enableMailbox": "啟用退回信箱", "settings.bounces.enablePostmark": "啟用郵戳", "settings.bounces.enableSES": "啟用 SES", @@ -384,6 +385,7 @@ "settings.bounces.enabled": "已啟用", "settings.bounces.folder": "資料夾", "settings.bounces.folderHelp": "要掃描的 IMAP 資料夾名稱。例如:收件匣。", + "settings.bounces.forwardemailKey": "Forward Email Key", "settings.bounces.hard": "強制退回", "settings.bounces.invalidScanInterval": "退回信件的偵測間隔應至少為 1 分鐘。", "settings.bounces.name": "退回", diff --git a/internal/bounce/bounce.go b/internal/bounce/bounce.go index 857a50a70..932f6ba20 100644 --- a/internal/bounce/bounce.go +++ b/internal/bounce/bounce.go @@ -38,20 +38,25 @@ type Opt struct { Username string Password string } + ForwardEmail struct { + Enabled bool + Key string + } RecordBounceCB func(models.Bounce) error } // Manager handles e-mail bounces. type Manager struct { - queue chan models.Bounce - mailbox Mailbox - SES *webhooks.SES - Sendgrid *webhooks.Sendgrid - Postmark *webhooks.Postmark - queries *Queries - opt Opt - log *log.Logger + queue chan models.Bounce + mailbox Mailbox + SES *webhooks.SES + Sendgrid *webhooks.Sendgrid + Postmark *webhooks.Postmark + Forwardemail *webhooks.Forwardemail + queries *Queries + opt Opt + log *log.Logger } // Queries contains the queries. @@ -96,6 +101,11 @@ func New(opt Opt, q *Queries, lo *log.Logger) (*Manager, error) { if opt.Postmark.Enabled { m.Postmark = webhooks.NewPostmark(opt.Postmark.Username, opt.Postmark.Password) } + + if opt.ForwardEmail.Enabled { + fe := webhooks.NewForwardemail([]byte(opt.ForwardEmail.Key)) + m.Forwardemail = fe + } } return m, nil diff --git a/internal/bounce/webhooks/forwardemail.go b/internal/bounce/webhooks/forwardemail.go new file mode 100644 index 000000000..dd17dd518 --- /dev/null +++ b/internal/bounce/webhooks/forwardemail.go @@ -0,0 +1,87 @@ +package webhooks + +import ( + "crypto/hmac" + "crypto/sha256" + "crypto/subtle" + "encoding/json" + "fmt" + "strings" + "time" + + "github.com/knadh/listmonk/models" +) + +type BounceDetails struct { + Action string `json:"action"` + Message string `json:"message"` + Category string `json:"category"` + Code int `json:"code"` + Status string `json:"status"` + Line int `json:"line"` +} + +type forwardemailNotif struct { + EmailID string `json:"email_id"` + ListID string `json:"list_id"` + ListUnsubscribe string `json:"list_unsubscribe"` + FeedbackID string `json:"feedback_id"` + Recipient string `json:"recipient"` + Message string `json:"message"` + Response string `json:"response"` + ResponseCode int `json:"response_code"` + TruthSource string `json:"truth_source"` + Headers map[string]string `json:"headers"` + Bounce BounceDetails `json:"bounce"` + BouncedAt time.Time `json:"bounced_at"` +} + +// Forwardemail handles webhook notifications (mainly bounce notifications). +type Forwardemail struct { + hmacKey []byte +} + +func NewForwardemail(key []byte) *Forwardemail { + return &Forwardemail{hmacKey: key} +} + +// ProcessBounce processes Forward Email bounce notifications and returns one object. +func (p *Forwardemail) ProcessBounce(sig, b []byte) ([]models.Bounce, error) { + key := []byte(p.hmacKey) + + mac := hmac.New(sha256.New, key) + + mac.Write(b) + + signature := mac.Sum(nil) + + if subtle.ConstantTimeCompare(signature, []byte(sig)) != 1 { + return nil, fmt.Errorf("invalid signature") + } + + var n forwardemailNotif + if err := json.Unmarshal(b, &n); err != nil { + return nil, fmt.Errorf("error unmarshalling Forwardemail notification: %v", err) + } + + typ := models.BounceTypeSoft + // TODO: support `typ = models.BounceTypeComplaint` in future + switch n.Bounce.Category { + case "block", "recipient", "virus", "spam": + typ = models.BounceTypeHard + } + + campUUID := "" + if v, ok := n.Headers["X-Listmonk-Campaign"]; ok { + campUUID = v + } + + return []models.Bounce{{ + Email: strings.ToLower(n.Recipient), + CampaignUUID: campUUID, + Type: typ, + Source: "forwardemail", + Meta: json.RawMessage(b), + CreatedAt: n.BouncedAt, + }}, nil +} diff --git a/models/settings.go b/models/settings.go index ef129aab3..7ba5ea3b5 100644 --- a/models/settings.go +++ b/models/settings.go @@ -106,6 +106,10 @@ type Settings struct { Username string `json:"username"` Password string `json:"password"` } `json:"bounce.postmark"` + BounceForwardEmail struct { + Enabled bool `json:"enabled"` + Key string `json:"key"` + } `json:"bounce.forwardemail"` BounceBoxes []struct { UUID string `json:"uuid"` Enabled bool `json:"enabled"` diff --git a/schema.sql b/schema.sql index dae4ccbfd..fc0639b23 100644 --- a/schema.sql +++ b/schema.sql @@ -279,6 +279,7 @@ INSERT INTO settings (key, value) VALUES ('bounce.sendgrid_enabled', 'false'), ('bounce.sendgrid_key', '""'), ('bounce.postmark', '{"enabled": false, "username": "", "password": ""}'), + ('bounce.forwardemail', '{"enabled": false, "key": ""}'), ('bounce.mailboxes', '[{"enabled":false, "type": "pop", "host":"pop.yoursite.com","port":995,"auth_protocol":"userpass","username":"username","password":"password","return_path": "bounce@listmonk.yoursite.com","scan_interval":"15m","tls_enabled":true,"tls_skip_verify":false}]'), ('appearance.admin.custom_css', '""'),