- Add materialized views for list -> subscriber counts, dashboard chart,
and dashboard aggregate stats that slow down significantly on large
databases (with millions or tens of millions of subscribers). These
slow queries involve full table scan COUNTS().
- Add a toggle to enable caching slow results in Settings -> Performance.
- Add support for setting a cron string that crons and periodically
refreshes aggregated stats in materialized views.
Closes#1019.
- Sent count is no longer the batch size fetched from the DB but is
the actual count of messages sent.
- Pausing and resuming now accurately tracks the last subscriber that
was processed and resumes from there.
- Fix multiple concurrent campaigns blocking.
Closes#1616. Closes#905. Closes#1496. Closes#1250. Closes#1010.
This commit fully refactors the core campaign manager logic.
It applies a whole new approach to campaign state and lifecycle management.
- Create a new "pipeline" abstraction on top of campaign
for state management.
- Account for every message processed and end campaigns
based on the actual count.
- Discard in-queue messages in the pipeline of a paused
or cancelled campaign.
- Add new 'Subscriptions' table on the subscriber list form that shows subs,
IP, and other data.
- Add new `meta` JSONB field to `subscriber_lsts` table.
Closes#1329.
- `GET /api/events?type=error` opens a long-lived HTTP server side
event connection that streams error messages.
- async (typically SMTP) errors are now streamed to the frontend and
disaplyed as an error toast on the admin UI.
- Change tiled UI to table UI.
- Add support for search and pagination.
- Important: This breaks the `GET /api/media` API to introduce pagination
fields. Media items are now moved into `{ data: results[] }`.
- Adds support for arbitrary file uploads with an admin setting to select allowed file extensions.
- Adds support for attaching media (files) to campaigns.
Remove `messenger.go` and move the interface definition to `manager`
and the `Message` struct to the `models` package, removing superflous
and redundant message structs used in multiple places.
- Rename `Get()` to `GetURL()`.
- Add `GetBlob()` to retrieve the media file blobs in
filesystem and and s3 media providers.
This enables reading media files inside listmonk paving the way to
campaign file attachments.
- Add support for `complaint` to the SES bounce processor.
- Add support for `hard/soft` to Sendgrid bounce processor.
- Add new bounce actions `None` and `Unsubscribe`.
- Add per type (`soft/hard/complaint`) bounce rule configuration to
admin settings UI.
- Refactor Cypress bounce tests.