Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Odoo Mail Deliverability

Odoo 18.0 License: LGPL-3

Two small, dependency-free modules that keep Odoo Email Marketing from burning your sender reputation. Both are production-proven and fully tested.

Module What it does
mass_mailing_throttle Global send-rate caps (per rolling hour + per rolling minute) for mass mailings. Configurable in Settings. Large mailings drain themselves in slices, hands-free.
mail_list_headers_raw Fixes the RFC 2047-mangled List-Unsubscribe header so Gmail/Outlook/Yahoo show their native Unsubscribe button and one-click unsubscribe (RFC 8058) actually counts.

They are independent — install either or both.

Why these exist

Problem 1 — Odoo has no send-rate limit. Every mass-send path in Odoo hands all remaining recipients to the composer in one pass. There is internal batching, but no time-based cap: a 5,000-recipient mailing leaves as fast as your relay accepts it. On Gmail/Google Workspace, Office 365, or any relay with hourly caps, that means deferrals, rate-limit bounces, spam foldering — and a domain reputation that takes weeks to recover. mass_mailing_throttle adds the missing knob: a global budget per rolling hour (default 200) plus optional per-minute burst smoothing (default 10), enforced at the one method every send path funnels through. Throttled mailings just sit in Sending and finish by themselves.

Problem 2 — your unsubscribe header is silently broken. Odoo builds messages with email.policy.SMTP, and Python's header folder RFC 2047-encodes any header line it cannot fold — which is every List-Unsubscribe URL, since URLs contain no whitespace to break on. The result on the wire:

List-Unsubscribe: =?utf-8?q?=3Chttps=3A//mycompany=2Eexample=2Ecom/mailing/42/?=
 =?utf-8?q?unsubscribe=5Foneclick=3F...?=

List-* headers are structured fields (RFC 2369) where encoded-words are illegal, so mailbox providers find no URI: no native Unsubscribe button, and no credit for the one-click unsubscribe Gmail and Yahoo have required from bulk senders since 2024. mail_list_headers_raw disables folding on exactly the messages that carry List-* headers (with guard rails against the RFC 5321 line limit), so the URL goes out verbatim.

Installation

  1. Clone into your addons path:

    git clone https://github.com/ConStrut/odoo-mail-deliverability.git
    

    or copy the module folder(s) you want into a directory already listed in addons_path.

  2. Restart Odoo, update the Apps list (Apps → Update Apps List, with developer mode on).

  3. Install Mass Mailing Send Throttle and/or Raw List-Unsubscribe Headers from Apps.

Note: the throttle ships enabled at 200 emails/hour and 10/minute — that is its job. Review the limits in Settings → Email Marketing → Send Throttle right after installing, especially if you already send at higher volumes.

Compatibility

  • Odoo 18.0, Community and Enterprise.
  • No external Python dependencies. No JavaScript. No new models.
  • mass_mailing_throttle depends on mass_mailing; mail_list_headers_raw depends on base only.

Running the tests

odoo-bin -d <your-db> --test-tags /mass_mailing_throttle,/mail_list_headers_raw --stop-after-init

Scope and non-goals

These modules deliberately stay small:

  • No per-mailing or per-server limits — the budget is global, because relay caps are per account, not per campaign.
  • No warm-up schedules, no reputation scoring, no analytics. Pair the throttle with proper SPF/DKIM/DMARC and list hygiene; it controls volume, nothing else.
  • The header fix does not add List-* headers — Odoo's mass_mailing already sets them; this module just stops them being mangled in transit.

Contributing

Issues and PRs welcome, especially version ports (the header-folding bug affects any Odoo version that builds messages with email.policy.SMTP). Please keep PRs in the spirit of the modules: minimal surface, no new dependencies, tests included.

License

LGPL-3.

About

Deliverability guard-rails for Odoo 18 Email Marketing: global send-rate throttle for mass mailings + a fix for the RFC 2047-mangled List-Unsubscribe header that hides Gmail's native unsubscribe button.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages