Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Postmark bounce support (refactor #1385) #1485

Merged
merged 14 commits into from
Aug 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions cmd/bounce.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,19 @@ func handleBounceWebhook(c echo.Context) error {
}
bounces = append(bounces, bs...)

// Postmark.
case service == "postmark" && app.constants.BouncePostmarkEnabled:
bs, err := app.bounce.Postmark.ProcessBounce(rawReq, c)
if err != nil {
app.log.Printf("error processing postmark 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"))
}
Expand Down
13 changes: 12 additions & 1 deletion cmd/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ type constants struct {
BounceWebhooksEnabled bool
BounceSESEnabled bool
BounceSendgridEnabled bool
BouncePostmarkEnabled bool
}

type notifTpls struct {
Expand Down Expand Up @@ -400,6 +401,8 @@ func initConstants() *constants {
c.BounceWebhooksEnabled = ko.Bool("bounce.webhooks_enabled")
c.BounceSESEnabled = ko.Bool("bounce.ses_enabled")
c.BounceSendgridEnabled = ko.Bool("bounce.sendgrid_enabled")
c.BouncePostmarkEnabled = ko.Bool("bounce.postmark.enabled")

return &c
}

Expand Down Expand Up @@ -668,7 +671,15 @@ func initBounceManager(app *App) *bounce.Manager {
SESEnabled: ko.Bool("bounce.ses_enabled"),
SendgridEnabled: ko.Bool("bounce.sendgrid_enabled"),
SendgridKey: ko.String("bounce.sendgrid_key"),

Postmark: struct {
Enabled bool
Username string
Password string
}{
ko.Bool("bounce.postmark.enabled"),
ko.String("bounce.postmark.username"),
ko.String("bounce.postmark.password"),
},
RecordBounceCB: app.core.RecordBounce,
}

Expand Down
4 changes: 4 additions & 0 deletions cmd/settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ func handleGetSettings(c echo.Context) error {
s.UploadS3AwsSecretAccessKey = strings.Repeat(pwdMask, utf8.RuneCountInString(s.UploadS3AwsSecretAccessKey))
s.SendgridKey = strings.Repeat(pwdMask, utf8.RuneCountInString(s.SendgridKey))
s.SecurityCaptchaSecret = strings.Repeat(pwdMask, utf8.RuneCountInString(s.SecurityCaptchaSecret))
s.BouncePostmark.Password = strings.Repeat(pwdMask, utf8.RuneCountInString(s.BouncePostmark.Password))

return c.JSON(http.StatusOK, okResp{s})
}
Expand Down Expand Up @@ -183,6 +184,9 @@ func handleUpdateSettings(c echo.Context) error {
if set.SendgridKey == "" {
set.SendgridKey = cur.SendgridKey
}
if set.BouncePostmark.Password == "" {
set.BouncePostmark.Password = cur.BouncePostmark.Password
}
if set.SecurityCaptchaSecret == "" {
set.SecurityCaptchaSecret = cur.SecurityCaptchaSecret
}
Expand Down
1 change: 1 addition & 0 deletions cmd/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ var migList = []migFunc{
{"v2.3.0", migrations.V2_3_0},
{"v2.4.0", migrations.V2_4_0},
{"v2.5.0", migrations.V2_5_0},
{"v2.6.0", migrations.V2_6_0},
}

// upgrade upgrades the database to the current version by running SQL migration files
Expand Down
6 changes: 3 additions & 3 deletions docs/docs/content/bounces.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ Some mail servers may also return the bounce to the `Reply-To` address, which ca
The bounce webhook API can be used to record bounce events with custom scripting. This could be by reading a mailbox, a database, or mail server logs.

| Method | Endpoint | Description |
|--------|------------------|------------------------|
| ------ | ---------------- | ---------------------- |
| `POST` | /webhooks/bounce | Record a bounce event. |


| Name | Data type | Required/Optional | Description |
|-------------------|-----------|-------------------|--------------------------------------------------------------------------------------|
| ----------------- | --------- | ----------------- | ------------------------------------------------------------------------------------ |
| `subscriber_uuid` | String | Optional | The UUID of the subscriber. Either this or `email` is required. |
| `email` | String | Optional | The e-mail of the subscriber. Either this or `subscriber_uuid` is required. |
| `campaign_uuid` | String | Optional | UUID of the campaign for which the bounce happened. |
Expand All @@ -46,7 +46,7 @@ listmonk supports receiving bounce webhook events from the following SMTP provid
|-----------------------------|------------------|-----------|
| `https://listmonk.yoursite.com/webhooks/service/ses` | Amazon (AWS) SES | You can use these [Mautic steps](https://docs.mautic.org/en/channels/emails/bounce-management#amazon-webhook) as a general guide, but use your listmonk's endpoint instead. <ul> <li>When creating the *topic* select "standard" instead of the preselected "FIFO". You can put a name and leave everything else at default.</li> <li>When creating a *subscription* choose HTTPS for "Protocol", and leave *"Enable raw message delivery"* UNCHECKED.</li> <li>On the _"SES -> verified identities"_ page, make sure to check **"[include original headers](https://github.com/knadh/listmonk/issues/720#issuecomment-1046877192)"**.</li> <li>The Mautic screenshot suggests you should turn off _email feedback forwarding_, but that's completely optional depending on whether you want want email notifications.</li></ul> |
| `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)


## Verification
Expand Down
14 changes: 14 additions & 0 deletions docs/swagger/collections.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2703,6 +2703,8 @@ components:
type: string
settings.bounces.enableSendgrid:
type: string
settings.bounces.enablePostmark:
type: string
settings.bounces.enableWebhooks:
type: string
settings.bounces.enabled:
Expand All @@ -2721,6 +2723,12 @@ components:
type: string
settings.bounces.sendgridKey:
type: string
settings.bounces.postmarkUsername:
type: string
settings.bounces.postmarkUsernameHelp:
type: string
settings.bounces.postmarkPassword:
type: string
settings.bounces.type:
type: string
settings.bounces.username:
Expand Down Expand Up @@ -3398,6 +3406,12 @@ components:
type: boolean
bounce.sendgrid_key:
type: string
bounce.postmark_enabled:
type: boolean
bounce.postmark_username:
type: string
bounce.postmark_password:
type: string
bounce.mailboxes:
type: array
items:
Expand Down
6 changes: 6 additions & 0 deletions frontend/src/views/Settings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,12 @@ export default Vue.extend({
hasDummy = 'captcha';
}

if (this.isDummy(form['bounce.postmark'].password)) {
form['bounce.postmark'].password = '';
} else if (this.hasDummy(form['bounce.postmark'].password)) {
hasDummy = 'postmark';
}

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)) {
Expand Down
27 changes: 27 additions & 0 deletions frontend/src/views/settings/bounces.vue
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,33 @@
</b-field>
</div>
</div>
<div class="columns">
<div class="column is-3">
<b-field :label="$t('settings.bounces.enablePostmark')">
<b-switch v-model="data['bounce.postmark'].enabled"
name="postmark_enabled" :native-value="true"
data-cy="btn-enable-bounce-postmark" />
</b-field>
</div>
<div class="column">
<b-field :label="$t('settings.bounces.postmarkUsername')"
:message="$t('settings.bounces.postmarkUsernameHelp')">
<b-input v-model="data['bounce.postmark'].username" type="text"
:disabled="!data['bounce.postmark'].enabled"
name="postmark_username"
data-cy="btn-enable-bounce-postmark" />
</b-field>
</div>
<div class="column">
<b-field :label="$t('settings.bounces.postmarkPassword')"
:message="$t('globals.messages.passwordChange')">
<b-input v-model="data['bounce.postmark'].password" type="password"
:disabled="!data['bounce.postmark'].enabled"
name="postmark_password"
data-cy="btn-enable-bounce-postmark" />
</b-field>
</div>
</div>
</div>
</div>

Expand Down
3 changes: 2 additions & 1 deletion i18n/ca.json
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@
"settings.bounces.enableSES": "Activa SES",
"settings.bounces.enableSendgrid": "Activa SendGrid",
"settings.bounces.enableWebhooks": "Activa els webhooks pels rebots",
"settings.bounces.enablePostmark": "Activa Postmark",
"settings.bounces.enabled": "Activat",
"settings.bounces.folder": "Carpeta",
"settings.bounces.folderHelp": "Nom de la carpeta IMAP a escanejar. Ex: Safata d'entrada.",
Expand Down Expand Up @@ -577,4 +578,4 @@
"templates.subject": "Assumpte",
"users.login": "Inicia sessió",
"users.logout": "Tanca sessió"
}
}
3 changes: 2 additions & 1 deletion i18n/cs-cz.json
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@
"settings.bounces.enableSES": "Povolit SES",
"settings.bounces.enableSendgrid": "Povolit SendGrid",
"settings.bounces.enableWebhooks": "Povolit webhooky v případě nedoručitelnosti",
"settings.bounces.enablePostmark": "Povolit Postmark",
"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.",
Expand Down Expand Up @@ -577,4 +578,4 @@
"templates.subject": "Předmět",
"users.login": "Přihlásit",
"users.logout": "Odhlásit"
}
}
3 changes: 2 additions & 1 deletion i18n/cy.json
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@
"settings.bounces.enableSES": "Galluogi SES",
"settings.bounces.enableSendgrid": "Galluogi SendGrid",
"settings.bounces.enableWebhooks": "Galluogi bachau gwe sydd wedi sboncio'n ôl",
"settings.bounces.enablePostmark": "Galluogi Postmark",
"settings.bounces.enabled": "Wedi galluogi",
"settings.bounces.folder": "Ffolder",
"settings.bounces.folderHelp": "Enw'r ffolder IMAP i'w sganio. ee: blwch derbyn.",
Expand Down Expand Up @@ -577,4 +578,4 @@
"templates.subject": "Pwnc",
"users.login": "Mewngofnodi",
"users.logout": "Allgofnodi"
}
}
3 changes: 2 additions & 1 deletion i18n/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@
"settings.bounces.enableSES": "SES aktivieren",
"settings.bounces.enableSendgrid": "SendGrid aktivieren",
"settings.bounces.enableWebhooks": "Bounce-Webhooks aktivieren",
"settings.bounces.enablePostmark": "Postmark aktivieren",
"settings.bounces.enabled": "Aktiviert",
"settings.bounces.folder": "Ordner",
"settings.bounces.folderHelp": "Name des zu scannenden IMAP-Ordners. z.B.: Inbox.",
Expand Down Expand Up @@ -577,4 +578,4 @@
"templates.subject": "Betreff",
"users.login": "Anmelden",
"users.logout": "Abmelden"
}
}
6 changes: 5 additions & 1 deletion i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,7 @@
"settings.bounces.enableSES": "Enable SES",
"settings.bounces.enableSendgrid": "Enable SendGrid",
"settings.bounces.enableWebhooks": "Enable bounce webhooks",
"settings.bounces.enablePostmark": "Enable Postmark",
"settings.bounces.enabled": "Enabled",
"settings.bounces.folder": "Folder",
"settings.bounces.folderHelp": "Name of the IMAP folder to scan. Eg: Inbox.",
Expand All @@ -372,6 +373,9 @@
"settings.bounces.scanInterval": "Scan interval",
"settings.bounces.scanIntervalHelp": "Interval at which the bounce mailbox should be scanned for bounces (s for second, m for minute).",
"settings.bounces.sendgridKey": "SendGrid Key",
"settings.bounces.postmarkUsername": "Postmark Username",
"settings.bounces.postmarkUsernameHelp": "Postmark allows you to enable basic authorization for webhooks. Make sure to enter the same credentials here and in your Postmark webhook settings.",
"settings.bounces.postmarkPassword": "Postmark Password",
"settings.bounces.type": "Type",
"settings.bounces.username": "Username",
"settings.confirmRestart": "Ensure running campaigns are paused. Restart?",
Expand Down Expand Up @@ -573,4 +577,4 @@
"templates.subject": "Subject",
"users.login": "Login",
"users.logout": "Logout"
}
}
3 changes: 2 additions & 1 deletion i18n/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,7 @@
"settings.bounces.enableSES": "Activar SES",
"settings.bounces.enableSendgrid": "Activar SendGrid",
"settings.bounces.enableWebhooks": "Activar webhooks de rebotes",
"settings.bounces.enablePostmark": "Activar Postmark",
"settings.bounces.enabled": "Activado",
"settings.bounces.folder": "Carpeta",
"settings.bounces.folderHelp": "Nombre de la carpeta IMAP a escanear, por ejemplo: Entrada.",
Expand Down Expand Up @@ -578,4 +579,4 @@
"templates.subject": "Asunto",
"users.login": "Ingresar",
"users.logout": "Salir"
}
}
3 changes: 2 additions & 1 deletion i18n/fi.json
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@
"settings.bounces.enableMailbox": "Ota käyttöön bounce-postilaatikko",
"settings.bounces.enableSES": "Ota käyttöön SES",
"settings.bounces.enableSendgrid": "Ota käyttöön SendGrid",
"settings.bounces.enablePostmark": "Ota käyttöön Postmark",
"settings.bounces.enableWebhooks": "Ota käyttöön palautusten webhookit",
"settings.bounces.enabled": "Käytössä",
"settings.bounces.folder": "Kansio",
Expand Down Expand Up @@ -578,4 +579,4 @@
"templates.subject": "Aihe",
"users.login": "Kirjaudu sisään",
"users.logout": "Kirjaudu ulos"
}
}
3 changes: 2 additions & 1 deletion i18n/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,7 @@
"settings.bounces.enableSES": "Activer SES",
"settings.bounces.enableSendgrid": "Activer SendGrid",
"settings.bounces.enableWebhooks": "Activez les 'webhooks' de rebond",
"settings.bounces.enablePostmark": "Activer Postmark",
"settings.bounces.enabled": "Activer",
"settings.bounces.folder": "Dossier",
"settings.bounces.folderHelp": "Nom du dossier IMAP à scanner. Exple : InBox.",
Expand Down Expand Up @@ -578,4 +579,4 @@
"templates.subject": "Objet",
"users.login": "Connecter",
"users.logout": "Déconnecter"
}
}
3 changes: 2 additions & 1 deletion i18n/hu.json
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@
"settings.bounces.enableSES": "SES",
"settings.bounces.enableSendgrid": "SendGrid",
"settings.bounces.enableWebhooks": "Visszapattanó webhook",
"settings.bounces.enablePostmark": "Postmark",
"settings.bounces.enabled": "Engedélyezve",
"settings.bounces.folder": "Mappa",
"settings.bounces.folderHelp": "A vizsgálandó IMAP mappa neve. Például: 'Inbox'",
Expand Down Expand Up @@ -577,4 +578,4 @@
"templates.subject": "Tárgy",
"users.login": "Belépés",
"users.logout": "Kijelentkezés"
}
}
3 changes: 2 additions & 1 deletion i18n/it.json
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,7 @@
"settings.bounces.enableSES": "Attiva SES",
"settings.bounces.enableSendgrid": "Attiva SendGrid",
"settings.bounces.enableWebhooks": "Attiva bounce webhooks",
"settings.bounces.enablePostmark": "Attiva Postmark",
"settings.bounces.enabled": "Attivato",
"settings.bounces.folder": "Cartella",
"settings.bounces.folderHelp": "Nome della cartella IMAP da analizzare. Ad esempio: Posta in arrivo.",
Expand Down Expand Up @@ -578,4 +579,4 @@
"templates.subject": "Oggeto",
"users.login": "Accesso",
"users.logout": "Esci"
}
}
3 changes: 2 additions & 1 deletion i18n/jp.json
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,7 @@
"settings.bounces.enableSES": "SESを有効にする",
"settings.bounces.enableSendgrid": "SendGridを有効にする",
"settings.bounces.enableWebhooks": "バウンスウェブフックを有効にする",
"settings.bounces.enablePostmark": "Postmarkを有効にする",
"settings.bounces.enabled": "有効",
"settings.bounces.folder": "フォルダ",
"settings.bounces.folderHelp": "スキャンするIMAPフォルダの名前。 例: Inbox.",
Expand Down Expand Up @@ -578,4 +579,4 @@
"templates.subject": "件名",
"users.login": "ログイン",
"users.logout": "ログアウト"
}
}
3 changes: 2 additions & 1 deletion i18n/ml.json
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@
"settings.bounces.enableSES": "SES പ്രവർത്തനക്ഷമമാക്കുക",
"settings.bounces.enableSendgrid": "SendGrid പ്രവർത്തനക്ഷമമാക്കുക",
"settings.bounces.enableWebhooks": "ബൗൺസ് വെബ്‌ഹുക്കുകൾ പ്രവർത്തനക്ഷമമാക്കുക",
"settings.bounces.enablePostmark": "Postmark പ്രവർത്തനക്ഷമമാക്കുക",
"settings.bounces.enabled": "പ്രവർത്തനക്ഷമമാക്കി",
"settings.bounces.folder": "ഫോൾഡർ",
"settings.bounces.folderHelp": "സ്കാൻ ചെയ്യാനുള്ള IMAP ഫോൾഡറിന്റെ പേര്. ഉദാ: ഇൻബോക്സ്.",
Expand Down Expand Up @@ -577,4 +578,4 @@
"templates.subject": "വിഷയം",
"users.login": "പ്രവേശിക്കുക",
"users.logout": "പുറത്തുകടക്കുക"
}
}
3 changes: 2 additions & 1 deletion i18n/nl.json
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@
"settings.bounces.enableSES": "SES inschakelen",
"settings.bounces.enableSendgrid": "SendGrid inschakelen",
"settings.bounces.enableWebhooks": "Bounce webhooks inschakelen",
"settings.bounces.enablePostmark": "Postmark inschakelen",
"settings.bounces.enabled": "Ingeschakeld",
"settings.bounces.folder": "Map",
"settings.bounces.folderHelp": "Naam van de IMAP map om te scannen. Bv.: Inbox.",
Expand Down Expand Up @@ -577,4 +578,4 @@
"templates.subject": "Onderwerp",
"users.login": "Inloggen",
"users.logout": "Uitloggen"
}
}
Loading