AshDispatch.Config (AshDispatch v0.5.1)
View SourceCentralized configuration access for AshDispatch.
This module provides a single source of truth for all configuration values, with consistent defaults and clear documentation of each option.
Why This Exists
Configuration lookups were scattered across 30+ files, each with potentially different default values. This module ensures:
- Consistent defaults - Each config key has one canonical default
- Single source of truth - Change defaults in one place
- Discoverability - All config options documented together
- Type safety - Functions return expected types
Usage
# Instead of:
Application.get_env(:ash_dispatch, :user_module)
# Use:
AshDispatch.Config.user_module()Configuration
All options are configured under the :ash_dispatch application:
config :ash_dispatch,
user_module: MyApp.Accounts.User,
domains: [MyApp.Orders, MyApp.Tickets],
otp_app: :my_app,
# ... see individual functions for all options
Summary
Functions
The PubSub topic for admin/firehose broadcasts.
Audience configuration for recipient resolution (legacy).
Base URL for the application (fallback when endpoint not available).
The Phoenix channel topic prefix for user channels.
Whether to compile templates at build time.
The counter broadcast function (alternative to counter_broadcaster module).
The counter broadcaster module.
Default from email address.
Default from name (sender name displayed in email clients).
Default locale for template resolution and content.
The delivery receipt resource module.
List of Ash domains that have dispatch-enabled resources.
The email backend module for sending emails.
The Phoenix endpoint module for URL generation.
List of explicitly registered event modules.
Custom format extensions for template resolution.
Optional Gettext backend for translating content strings.
Default Gettext domain used to translate DSL content strings.
The notification resource module.
The OTP application name.
The permission checker module for policy checks.
The preference provider module (legacy, prefer user_preference).
The PubSub module for broadcasting notifications.
Recipient field configuration for extracting email/name from user structs.
The recipient resolver module.
The Ecto repo module.
Output path for generated SDK files.
Authorizer module for the send_now action on delivery receipts.
Whether to skip actual email delivery.
The SMS backend module — should implement AshDispatch.SMSBackend.
Returns nil when no backend is configured, in which case the SMS
transport marks receipts :skipped.
The Swoosh mailer module (when using Swoosh backend).
The URL builder module for generating admin/source URLs.
The domain containing the user resource.
The user module for recipient resolution and preferences.
The user preference checker module.
The user resource module (alias for user_module for clarity in some contexts).
Functions
@spec admin_channel_topic() :: String.t()
The PubSub topic for admin/firehose broadcasts.
Used by the :broadcast transport when audience is :admin.
Example
config :ash_dispatch,
admin_channel_topic: "admin:firehose"
@spec audiences() :: keyword()
Audience configuration for recipient resolution (legacy).
Maps audience atoms to filter configurations.
Note: If recipient_resolver is configured, this option is ignored.
Prefer using recipient_resolver for new applications.
Example
config :ash_dispatch,
audiences: [
admin: [admin: true],
user: :user,
support: [role: :support]
]
@spec base_url() :: String.t() | nil
Base URL for the application (fallback when endpoint not available).
@spec channel_topic() :: String.t()
The Phoenix channel topic prefix for user channels.
Defaults to "user" which creates topics like "user:user_id".
Configure to match your channel setup, e.g., "inbox" for "inbox:user_id".
Example
config :ash_dispatch,
channel_topic: "inbox"
@spec compile_templates?() :: boolean()
Whether to compile templates at build time.
Defaults to false.
@spec counter_broadcast_fn() :: function() | nil
The counter broadcast function (alternative to counter_broadcaster module).
@spec counter_broadcaster() :: module() | nil
The counter broadcaster module.
Should implement broadcast/3 for counter updates.
@spec default_from_email() :: String.t()
Default from email address.
Used when no from is specified in event module or inline DSL.
Defaults to "noreply@example.com".
@spec default_from_name() :: String.t()
Default from name (sender name displayed in email clients).
Used when no from is specified in event module or inline DSL.
Defaults to the OTP app name (titlecased) or "System" if not configured.
Example
config :ash_dispatch,
default_from_name: "Fyndgrossisten"
@spec default_locale() :: String.t()
Default locale for template resolution and content.
Used as the ultimate fallback when no locale is specified. The full locale resolution priority is:
- Channel-level
locale(static, e.g.,locale: "sv") - Channel-level
locale_from(dynamic from record field) - Event-level
locale_fromconfiguration - Resource-level
locale_fromconfiguration - Auto-detected common fields:
visitor_locale,locale - This config default
Template resolution then tries locale-specific templates first
(e.g., email.sv.html.heex), falling back to non-localized templates.
Defaults to "en".
Example
config :ash_dispatch,
default_locale: "sv"See Also
AshDispatch.Resource.Dsl- Resource-levellocalesconfigurationAshDispatch.TemplateResolver- Template fallback chain
@spec delivery_receipt_resource() :: module() | nil
The delivery receipt resource module.
Must be configured - returns nil if not set.
Example
config :ash_dispatch,
delivery_receipt_resource: MyApp.Deliveries.DeliveryReceipt
@spec domains() :: [module()]
List of Ash domains that have dispatch-enabled resources.
Used for:
- Event discovery via DSL introspection
- Counter loading
- SDK generation
Example
config :ash_dispatch,
domains: [MyApp.Orders, MyApp.Tickets, MyApp.Requests]
@spec email_backend() :: module() | nil
The email backend module for sending emails.
Should implement the email backend behaviour.
Example
config :ash_dispatch,
email_backend: AshDispatch.EmailBackend.Swoosh
@spec endpoint() :: module() | nil
The Phoenix endpoint module for URL generation.
@spec event_modules() :: [module()]
List of explicitly registered event modules.
These are discovered in addition to DSL-based events.
@spec format_extensions() :: map()
Custom format extensions for template resolution.
@spec gettext_backend() :: module() | nil
Optional Gettext backend for translating content strings.
When configured, all content: block strings (notification_title,
notification_message, etc.) are run through Gettext before variable
interpolation. The locale is resolved via the dispatch locale chain.
The content string IS the gettext msgid. Translations are looked up in the "notifications" domain.
Example
config :ash_dispatch,
gettext_backend: MyAppWeb.GettextThen content strings like notification_title: "Usage Alert" will
be translated via Gettext.dgettext(MyAppWeb.Gettext, "notifications", "Usage Alert").
@spec gettext_domain() :: String.t()
Default Gettext domain used to translate DSL content strings.
When a channel's :notification_title, :notification_message,
:subject, etc. is defined as a literal in dispatch do ... end,
Dispatcher.translate_content/2 looks up the string via
Gettext.dgettext(backend, gettext_domain(), msgid) before variable
interpolation runs.
Defaults to "notifications" so existing projects keep working.
Override per app:
config :ash_dispatch, :gettext_domain, "default"Projects that already extract i18n strings to default.po (e.g.
multi-locale Phoenix apps) can consolidate their DSL content
alongside the rest of their translations.
@spec notification_resource() :: module() | nil
The notification resource module.
Must be configured - returns nil if not set.
Example
config :ash_dispatch,
notification_resource: MyApp.Notifications.Notification
@spec otp_app() :: atom() | nil
The OTP application name.
Used for:
- Template resolution
- Event module discovery
@spec permission_checker() :: module() | nil
The permission checker module for policy checks.
@spec preference_provider() :: module() | nil
The preference provider module (legacy, prefer user_preference).
@spec pubsub_module() :: module() | nil
The PubSub module for broadcasting notifications.
Contract
Must be an endpoint-shaped module exposing both:
subscribe(topic)— for server-side consumers (e.g.Mosis.Dispatch.Subscriberor any GenServer that reacts to AshDispatch broadcasts in-process)broadcast(topic, event, payload)— used byAshDispatch.Transports.Broadcastto publish to user / admin channels and byTransports.InAppfor new-notification pushes
Phoenix endpoints generate both functions automatically — set this to your application's endpoint module:
config :ash_dispatch, pubsub_module: MyAppWeb.EndpointDo NOT set this to a bare Phoenix.PubSub registered name (e.g.
MyApp.PubSub). Those expose Phoenix.PubSub.subscribe/2 (arity 2)
and Phoenix.PubSub.broadcast/3 as functions on the Phoenix.PubSub
module itself, not on the registered-name atom — and consumers that
call pubsub.subscribe(topic) or pubsub.broadcast(topic, …)
directly would fail with UndefinedFunctionError.
@spec recipient_fields() :: keyword()
Recipient field configuration for extracting email/name from user structs.
Example
config :ash_dispatch,
recipient_fields: [
email: [
default: :email,
audiences: [admin: :work_email]
],
name: [
default: :display_name
]
]
@spec recipient_resolver() :: module() | nil
The recipient resolver module.
When configured, this module is used for all recipient resolution,
replacing the legacy audiences configuration.
Should implement AshDispatch.RecipientResolver behaviour.
Example
config :ash_dispatch,
recipient_resolver: MyApp.RecipientResolver
@spec repo() :: module() | nil
The Ecto repo module.
Used for Oban job queries and other database operations.
@spec sdk_output_path() :: String.t() | nil
Output path for generated SDK files.
@spec send_now_authorizer() :: module() | nil
Authorizer module for the send_now action on delivery receipts.
The module should implement authorize/1 which receives the actor and returns:
:okif authorized{:error, message}if not authorized
When nil (default), send_now is allowed for any authenticated actor.
System calls (no actor) are always allowed regardless of this setting.
Example
# Define authorizer module
defmodule MyApp.SendNowAuthorizer do
def authorize(nil), do: :ok # System calls always allowed
def authorize(%{super_admin: true}), do: :ok
def authorize(_), do: {:error, "Only super admins can trigger send now"}
end
# Configure in config.exs
config :ash_dispatch,
send_now_authorizer: MyApp.SendNowAuthorizer
@spec skip_email_delivery?() :: boolean()
Whether to skip actual email delivery.
When true, emails will not be sent and delivery receipts will be marked
as :skipped with reason "email delivery disabled". Useful for development
to prevent sending real emails while still testing the full dispatch flow.
Defaults to false.
Example
# config/dev.exs
config :ash_dispatch,
skip_email_delivery: true
@spec sms_backend() :: module() | nil
The SMS backend module — should implement AshDispatch.SMSBackend.
Returns nil when no backend is configured, in which case the SMS
transport marks receipts :skipped.
Example
config :ash_dispatch,
sms_backend: MyApp.SMS
@spec swoosh_mailer() :: module() | nil
The Swoosh mailer module (when using Swoosh backend).
@spec url_builder() :: module() | nil
The URL builder module for generating admin/source URLs.
Should implement admin_url/2, source_url/2, and optionally resource_label/1.
@spec user_domain() :: module() | nil
The domain containing the user resource.
@spec user_module() :: module() | nil
The user module for recipient resolution and preferences.
Used by:
AshDispatch.Event.Helpersfor recipient resolutionAshDispatch.Dispatcherfor user extraction from context- Counter calculations
Example
config :ash_dispatch,
user_module: MyApp.Accounts.User
@spec user_preference() :: module()
The user preference checker module.
Defaults to AshDispatch.UserPreference.Default which allows all notifications.
@spec user_resource() :: module() | nil
The user resource module (alias for user_module for clarity in some contexts).