Messaging Guide
When To Use It
Use messaging when your project needs a reusable Django-side messaging layer with:
- content models for editable email text
- payload builders and dispatch engines
- queue/direct delivery adapters
- abstract models for recipients, threads, messages, and campaigns
- audience and campaign batching primitives
codex_django.messaging is the canonical package.
codex_django.notifications remains available for one minor release as a deprecated compatibility path.
Stable Entry Points
codex_django.messagingcodex_django.messaging.adapterscodex_django.messaging.mixinscodex_django.messaging.cabinetcodex_django.messaging.audiencecodex_django.messaging.campaigns
Migration From notifications
Replace:
from codex_django.notifications import BaseNotificationEngine, NotificationPayloadBuilder
with:
from codex_django.messaging import BaseMessagingEngine, MessagingPayloadBuilder
Other key migrations:
codex_django.notifications->codex_django.messagingBaseNotificationEngine->BaseMessagingEngineNotificationPayloadBuilder->MessagingPayloadBuilderCONVERSATIONS_RECIPIENT_MODEL->MESSAGING_RECIPIENT_MODEL
Delivery Modes
The runtime keeps the existing two-mode contract:
template: worker renders the template fromtemplate_namerendered: host renders HTML/text before enqueueing
Decorator helpers make that split explicit:
@email_template(...)@email_rendered(...)@notification_handler(...)for the fully generic path
Related Reading
- Architecture:
messaging - API reference:
codex_django.messaging - Legacy compatibility:
notifications
Messaging Cabinet Integration
Use the cabinet feature layer when a project needs a staff mailbox and campaign surface without coupling library code to project models.
- Add concrete models by subclassing the abstract messaging models you need:
AbstractThread,AbstractMessage,AbstractMessageReply,AbstractCampaign,AbstractCampaignRecipient,AbstractSystemRecipient,AbstractEmailLog, andAbstractEmailSettings. - Implement
MessagingBridgein the project. The bridge reads concrete ORM data and returns typed state such asMailboxState,CampaignListState,RecipientListState,DeliveryLogState, andMessagingSettingsState. - Keep cabinet views thin: read query parameters, call the bridge, pass the
state through
MessagingCabinetPresenter, setrequest.cabinet_module = "messaging", and render a project template. - Register navigation with
build_messaging_topbar()andbuild_messaging_sidebar(). Pass settings throughdeclare(..., settings_url="cabinet:messaging_settings"); settings are not a normal sidebar item. - Override
cabinet/messaging/...templates when the project needs custom markup. The library ships fallback pages and reusable components under the same paths.
The default cabinet navigation is:
- Mailbox: operator inbox, thread detail, actions, and reply composer.
- Campaigns: broadcast list and campaign composer.
- Recipients: audience/recipient table.
- Delivery log: technical delivery audit table.
Templates is intentionally not a default top-level item. Template management
should become a campaign sub-flow or optional module only after a real
email/content template model exists.
Minimal Atlas-like registration:
from codex_django.cabinet import declare
from codex_django.messaging.cabinet import build_messaging_sidebar, build_messaging_topbar
from django.urls import reverse_lazy
declare(
module="messaging",
space="staff",
topbar=build_messaging_topbar(reverse_lazy("cabinet:messaging_mailbox")),
sidebar=build_messaging_sidebar(
mailbox_url=reverse_lazy("cabinet:messaging_mailbox"),
campaigns_url=reverse_lazy("cabinet:messaging_campaigns"),
recipients_url=reverse_lazy("cabinet:messaging_recipients"),
delivery_log_url=reverse_lazy("cabinet:messaging_delivery_log"),
),
settings_url="cabinet:messaging_settings",
)