Commit graph

74 commits

Author SHA1 Message Date
Kailash Nadh dc43e9cb8b Configure Markdown parser to not escape double quotes. Closes #1698. 2024-02-04 11:32:33 +05:30
Kailash Nadh 5a3664aee2 Add support for caching slow queries on large databases.
- 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.
2024-01-27 15:51:12 +05:30
Kailash Nadh 0d319ad9fd Add 'slug' (permalink) support for campaign archives. Closes #1394. 2024-01-09 23:34:08 +05:30
Kailash Nadh ef77a7e10f Replace c3js with chart.js for major dep size reduction. 2023-12-29 22:17:53 +05:30
Kailash Nadh 2b95c88188
Add Postmark bounce webhook support (refactor #1385) (#1485)
Co-authored-by: Thomas Siebers <tom@tsiebers.de>
2023-08-31 21:27:34 +05:30
Kailash Nadh ad80c716f9 Add new privacy option 'Record opt-in IP' to record IP address of optin confirmation.
- 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.
2023-07-26 23:00:32 +05:30
Kailash Nadh c581fe2f3a Add GET /api/about that returns useful system info. Closes #1354. 2023-06-24 13:07:13 +05:30
Kailash Nadh d359ad27aa Refactor media management.
- 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[] }`.
2023-05-21 15:19:12 +05:30
Kailash Nadh 3b9a0f782e
Add support for file attachments on campaigns (#1341)
- Adds support for arbitrary file uploads with an admin setting to select allowed file extensions.
- Adds support for attaching media (files) to campaigns.
2023-05-18 16:55:59 +05:30
Kailash Nadh 917696a543 Refactor Messenger interface.
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.
2023-05-08 22:43:25 +05:30
Kailash Nadh 5fc28a733c Add support for variable bounce processing actions.
- 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.
2023-04-11 11:33:40 +05:30
Justin Beaty 476d5bebf2
Add support for publishing full content in public archive RSS feed body (#1262)
- Introduces a new option on the settings UI to optionally publish the full campaign body in
  public archive RSS feeds.

Closes #1033 

Co-authored-by: Kailash Nadh <kailash@nadh.in>
2023-04-08 09:39:10 +05:30
Kailash Nadh 55f7eca2e8
Add support for file attachments in the transactional (tx) API. (#1243)
The original PR accepts files to the `/tx` endpoints as Base64 encoded
strings in the JSON payload. This isn't ideal as the payload size
increase caused by Base64 for larger files can be significant,
in addition to the added clientside API complexity.

This PR adds supports for multipart form posts to `/tx` where the
JSON data (name: `data`) and multiple files can be posted simultaenously
(one or more `file` fields).

--- PR: #1166
* Attachment model for TxMessage
* Don't reassign values, just pass the manager.Messgage
* Read attachment info from API; create attachment Header
* Refactor tx attachments to use multipart form files. Closes #1166.
---

Co-authored-by: MatiSSL <matiss.lidaka@nic.lv>
2023-03-19 15:50:44 +05:30
Kailash Nadh 8985e5c24a
Add hCaptcha.com support to public subscription form. (#1152)
Bots easily bypass the simple `nonce` hack. This commit adds support
for the hcaptcha.com widget.

- New `Security` tab in the admin settings UI.
- Enable/disable CAPTCHA.
- Render CAPTCHA on the public subscription form.

Closes #1116.
2023-01-23 21:50:10 +05:30
Kailash Nadh 3cfbc646e3 Add support for multiple subscribers in a single transactional message call.
This patch adds new array fields on `POST /tx`: `subscriber_emails[]`, `subscriber_ids[]`.
Either of these array fields can be sent with multiple subscribers.

The individual non-array fields `subscriber_id` and `subscriber_email` are deprecated.

Closes #994.
2022-12-25 17:32:01 +05:30
Kailash Nadh a555fd3876 Fix nil tpl when campaign body is empty. Closes #1085. 2022-12-06 19:47:05 +05:30
Kailash Nadh 818f2c9d8e Add public archive on/off toggle to settings. 2022-11-10 23:30:53 +05:30
Kailash Nadh 438568eeb0 Add global site name setting to render name on public pages. 2022-11-10 23:30:53 +05:30
Kailash Nadh 9add728b08 WIP: Add support for publishing campaigns to publish archives. 2022-11-10 23:30:11 +05:30
Romain 6d3ae4cc73
Add subscription created_at, updated_at when listing subscribers list (#1018) 2022-11-09 21:40:11 +05:30
Kailash Nadh ef1f84ee7c Add new description field to lists. Closes #925. 2022-11-01 21:04:35 +05:30
Kailash Nadh 3b0083190e Add ability for subscribers to manage preferences on the unsub form.
- Ability to change name.
- Ability to unsubscribe from individual lists.
- Toggle option to enable this in Admin Settings -> Privacy.

Closes #455.
2022-10-29 15:23:28 +05:30
Kailash Nadh c3d04a5490 Refactor models.SubscriberAttribs JSON wrapper to generic name JSON. 2022-10-02 22:53:38 +05:30
Kailash Nadh 6d820f4f6e Add maintenance options.
- Add new maintenance UI with options to garbage collect (delete)
  orphan subscriber and analytics records.
2022-09-03 14:58:25 +05:30
Kailash Nadh 76df9c8d76 Refactor and simply function name. 2022-08-26 16:49:58 +05:30
Kailash Nadh 6b11020a67 Fix empty subject on non-tpl tx subject. Closes #898. 2022-08-20 19:57:30 +05:30
Kailash Nadh 3550d5453d Fix incorrect analytics count. Closes #712. 2022-07-30 19:01:20 +05:30
Kailash Nadh 463e92d1e1 Add transactional (tx) messaging capability.
This commit adds a new API `POST /api/tx` that sends an ad-hoc message
to a subscriber based on a pre-defined transactional template. This is
a large commit that adds the following:

- New campaign / tx template types on the UI. tx templates have an
  additional subject field.
- New fields `type` and `subject` to the templates table.
- Refactor template CRUD operations and models.
- Refactor template func assignment in manager.
- Add pre-compiled template caching to manager runtime.
- Pre-compile all tx templates into memory on program boot to avoid
  expensive template compilation on ad-hoc tx messages.
2022-07-09 10:36:12 +05:30
Kailash Nadh 959541f8ee Rename unsub query to match the core method name. 2022-05-08 14:45:45 +05:30
Kailash Nadh b5cd9498b1 Refactore all CRUD functions to a new core package.
This is a long pending refactor. All the DB, query, CRUD, and related
logic scattered across HTTP handlers are now moved into a central
`core` package with clean, abstracted methods, decoupling HTTP
handlers from executing direct DB queries and other business logic.

eg: `core.CreateList()`, `core.GetLists()` etc.

- Remove obsolete subscriber methods.
- Move optin hook queries to core.
- Move campaign methods to `core`.
- Move all campaign methods to `core`.
- Move public page functions to `core`.
- Move all template functions to `core`.
- Move media and settings function to `core`.
- Move handler middleware functions to `core`.
- Move all bounce functions to `core`.
- Move all dashboard functions to `core`.
- Fix GetLists() not honouring type
- Fix unwrapped JSON responses.
- Clean up obsolete pre-core util function.
- Replace SQL array null check with cardinality check.
- Fix missing validations in `core` queries.
- Remove superfluous deps on internal `subimporter`.
- Add dashboard functions to `core`.
- Fix broken domain ban check.
- Fix broken subscriber check middleware.
- Remove redundant error handling.
- Remove obsolete functions.
- Remove obsolete structs.
- Remove obsolete queries and DB functions.
- Document the `core` package.
2022-05-03 10:50:29 +05:30
Kailash Nadh 89eca5f14b Changed email subject template from HTML to text. Fixes #785. 2022-05-03 10:41:46 +05:30
Kailash Nadh 73e4c1cf28 Fix POP mail parsing in multipart bounce e-mails.
This was originally authored by @stevesavanna in #707. This commit
contains changes and refactors that could not be pushed to the original PR.

Changes from #707

- Don't ignore bounce mails missing campaign / subscriber UUIDs. The
  original behaviour falls back to looking up subscribers by e-mail.
- Refactor repetetive header.get + regexp conditions per header into
  a simpler lookup map.
- Trim e-mail header values of `\r`.

Closes #707, #763

Co-authored-by: stevesavanna <steven@savannacorp.com>
2022-04-03 11:37:11 +05:30
Kailash Nadh 8fb459dc48 Fix custom DB type scan failing when nil. 2022-02-05 18:48:41 +05:30
Kailash Nadh da30d4688e Add subscriber status counts to the lists UI.
- Change `query-lists` query to aggregate the subscriber count by
  status (confirmed, unsubscribed etc.) and expose them under a new
  `subscriber_statuses: {}` field in the `GET /lists` API.
- Display the statuses and counts in the lists table on the UI.

Closes #616
2022-02-03 00:03:31 +05:30
Kailash Nadh d2cf6e0f14 Fix TrackLink template code to accept Go template variables. Closes #667. 2022-01-30 22:41:45 +05:30
Kailash Nadh e1d3dd4a65 Merge branch 'master' of github.com:knadh/listmonk 2022-01-04 22:33:58 +05:30
Kailash Nadh 583dab4bc6 Add support for per-campaign custom headers.
- Add new `headers[]` column to the campain table.
- Add new headers box to the campaign UI that takes a JSON array of
  custom headers like the headers on the SMTP settings UI.
- Headers are added to e-mails and messenger postback webhooks.
- Add cypress tests.

Closes #514.
2022-01-04 22:27:40 +05:30
Luc Didry 73e6668d20
Add AutoHeadingID option to Markdown parser 2022-01-04 09:36:14 +01:00
Kailash Nadh e9709e54ee Upgrade labstack/echo webserver to major version v4.
- echo is now on v4 with major changes including a few breaking changes
- bind() behaviour is now strict. JSON / form etc. unmarshalling of
  request data need appropriate `json`, `form` tags. Missing tags for
  the public subscription page is added in this commit.
- This also closes #602.
2021-12-09 20:51:07 +05:30
Kailash Nadh d86438bde9 Introduce @TrackLink shorthand for generating tracking links.
The default `{{ TrackLink "https://listmonk.app" }}` template function
is clumsy to write and does breaks WYSIWYG editors and HTML syntax
highlighting because of the quotes. The new syntax doesn't break HTML
and is easier to write.

Eg: `<a href="https://listmonk.app@TrackLink">Link</a>`

- Introduce @TrackLink shorthand.
- Add first-class support for tracking links in the WYSIWYG (TinyMCE)
  editor by introducing an on/off checkbox on the link dialog.
- Improve default dummy campaign content to highlight this.
2021-09-26 16:03:05 +05:30
Kailash Nadh 8733b205a0 Refactor SQL schema and queries for performance improvements.
- Add indexes.
- Refactor dashboard charts and view/click count queries.
  (~10x speed bump on a setup of 7mn subscribers and 80mn views)
- Refactor get subscriber queries.
  (~10x speed bump on 7mn subscribers)
- Make subscriber UI issue an equality query for email seach strings.
2021-09-18 17:25:08 +05:30
Kailash Nadh 923b882f05 Add migration to remove obsolete subscribers.campaigns field 2021-08-14 17:23:05 +05:30
Kailash Nadh 1ae98699e7 Add support for bounce processing.
- Blocklist or unsubscribe subscribers based on a bounce threshold
- Add /bounces UI for viewing bounces and in the subscriber view
- Add settings UI for managing bounce settings
- Add support for scanning POP3 bounce mailboxes
- Add a generic webhook for posting custom bounces at /webhooks/bounce
- Add SES bounce webhook support at /webhooks/services/ses
- Add Sendgrid bounce webhook support at /webhooks/services/sendgrid
2021-08-14 15:35:29 +05:30
Kailash Nadh 65d25fc3f9 Improve campaign content format conversion.
Previously, converting between formats simply copied over raw content.
This update does actual conversion between different formats. While
lossy, this seems to a good enough approximation for even reasonbly
rich HTML content. Closes #348.

- richtext, html => plain
  Strips HTML and converts content to plain text.

- richtext, html => markdown
  Uses turndown (JS) lib to convert HTML to Markdown.

- plain => richtext, html
  Converts line breaks in plain text to HTML breaks.

- richtext => html
  "Beautifies" the HTML generated by the WYSIWYG editor unlike the
  earlier behaviour of dumping one long line of HTML.

- markdown => richtext, html
  Makes an API call to the backend to use the Goldmark lib to convert
  Markdown to HTML.
2021-05-09 15:36:31 +05:30
Kailash Nadh 49c747d7d0 Allow HTML and additional syntax in the Markdown parser. 2021-05-08 16:55:48 +05:30
Kailash Nadh 1e59d53135 Add markdown support to campaign content. 2021-04-14 12:26:09 +05:30
Kailash Nadh 68afd61024 Add support for alternate plaintext body for e-mails.
This commit removes the Go html2text lib that would automatically
convert all HTML messages to plaintext and add them as the alt
text body to outgoing e-mails. This lib also had memory leak
issues with certain kinds of HTML templates.

A new UI field for optionally adding an alt plaintext body to
a campaign is added. On enabling, it converts the HTML message in
the campaign editor into plaintext (using the textversionjs lib).

This introduces breaking changes in the campaigns table schema,
model, and template compilation.
2021-01-30 18:49:47 +05:30
Kailash Nadh ec1c4f30ed Add subscriber export feature 2021-01-23 18:23:29 +05:30
Kailash Nadh 6cf43ea674 Add generic HTTP postback Messenger support.
This is a major feature that builds upon the `Messenger` interface
that has been in listmonk since its inception (with SMTP as the only
messenger). This commit introduces a new Messenger implementation, an
HTTP "postback", that can post campaign messages as a standard JSON
payload to arbitrary HTTP servers. These servers can in turn push them
to FCM, SMS, or any or any such upstream, enabling listmonk to be a
generic campaign messenger for any type of communication, not just
e-mails.

Postback HTTP endpoints can be defined in settings and they can be
selected on campaigns.
2020-10-10 18:52:08 +05:30
Kailash Nadh 8c0804ba9f Refactor blacklist to blocklist 2020-08-01 16:45:29 +05:30