Chime.Config (Chime v0.1.0-dev)

Copy Markdown View Source

The options of Chime, given to its child in the app's supervision tree, after the repo, the PubSub and Oban:

children = [
  MyApp.Repo,
  {Phoenix.PubSub, name: MyApp.PubSub},
  {Oban, Application.fetch_env!(:my_app, Oban)},
  {Chime,
   repo: MyApp.Repo,
   pubsub: MyApp.PubSub,
   resolver: MyApp.ChimeResolver,
   mailer: MyApp.Mailer,
   email_from: {"Atelier", "hello@atelier.app"},
   secret_key_base: Application.fetch_env!(:my_app, MyAppWeb.Endpoint)[:secret_key_base],
   mail_url: "https://atelier.app/notifications/mail",
   categories: [
     comments: [label: "Comments on your stories"],
     followers: [label: "New followers", defaults: [email: :weekly]],
     billing: [label: "Billing", required: true]
   ]},
  MyAppWeb.Endpoint
]

Options:

  • :repo - the app's Ecto repo, where the notifications are (required).

  • :pubsub - the app's Phoenix.PubSub, on which the app's pages hear of a notification as it comes (required).

  • :resolver - the app's Chime.Resolver: who the people of the app are, by id, and who reads the feed of a request (required).

  • :oban - the app's Oban, which runs every delivery but the feed's: Oban (the default), or [name: MyApp.Oban, queue: :notifications] for another instance or queue (:default). The queue must be one the app runs.

  • :prefix - the schema of the tables, in PostgreSQL.

  • :categories - the kinds of notification a person can turn on and off, in the order the preferences show them. Each is a key with its options:

    • :label - its name in the preferences (the key, capitalized).
    • :description - a line under the label.
    • :required - a notification of the category goes whatever the person's preferences, and its emails have no link to unsubscribe: receipts, security, the account (false).
    • :defaults - the setting of each channel for a person who has not changed it: [email: :daily, feed: :on]. A channel not named is :on.

    Without it, every notifier's category is taken, with every channel on, and the preferences show none.

  • :channels - the app's own channels, by name, each a module of Chime.Channel or {module, opts}: [telegram: MyApp.Chime.Telegram, sms: {MyApp.Chime.SMS, from: "+351..."}]. :feed and :email are Chime's.

  • :mailer - the app's Swoosh.Mailer, which sends the emails of the :email channel and the digests (required with it).

  • :email_from - who the emails are from: {"Atelier", "hello@atelier.app"} or an address (required with :mailer).

  • :secret_key_base - the secret that signs the links to unsubscribe and the tokens of the JSON API (Chime.Token). At least 32 bytes.

  • :mail_url - the address where chime_mail is mounted, whole ("https://atelier.app/notifications/mail"), for the links of the emails: to unsubscribe (and the List-Unsubscribe headers), and to open a notification, which reads it (Chime.link/2). With :secret_key_base; without them, the emails have no such links.

  • :digest - when the digests go, in each person's time zone (UTC for a person without one):

    • :at - the hour (9, for 09:00).
    • :weekly_on - the day of the weekly digest (:monday).
    • :email - the app's module that writes the digest's email, with email(recipient, items, period) (see Chime.Digest). Without it, Chime's own: a list of the notifications as the feed shows them.
  • :url - the app's address ("https://atelier.app"), for the links of the digests to the notifications whose feed :url is a path.

  • :gettext - the app's Gettext backend (MyAppWeb.Gettext), in which Chime's words are translated, in the "chime" domain (see Chime.Messages). Without it, they are English.

  • :limits - the most each person gets by a channel in a time, by channel: [email: {3, :hour}, sms: {5, :day}]. One past the limit waits until it is under again. Required notifications do not count against it, and are not held by it.

  • :quiet_hours - the hours of the night, in each person's time zone, when nothing but the feed goes: {22, 8}, from 22:00 to 08:00. What comes then waits for the end. A person's own (:quiet_hours of Chime.Recipient) comes first. Required notifications go all the same (none).

  • :push - the push services of the :push channel, each with its keys (see the Push guide); the channel is there with one:

    • :web - Web Push, for browsers: :public_key and :private_key, the app's VAPID keys, URL-safe Base64 (mix chime.gen.vapid), :subject, a mailto: or https: address of the app's, and :ttl, how long a push waits for a browser that is off, in seconds (one day).
    • :apns - Apple's: :key, the .p8 key (its text), :key_id, :team_id, :topic, the app's bundle id, and :env, :production or :sandbox (:production).
    • :fcm - Firebase's: :service_account, its JSON (the text, or a map), from Firebase's console.
    • :req_options - options of the requests to the services, for Req ([]).
  • :keep_days - how long a notification is kept, with its deliveries, after it came (180). nil keeps them for ever.

  • :scheduler - false starts nothing that runs by itself: no digest job, no cleanup. For an app's tests (true).

Summary

Functions

Builds the config from the options of the child, and checks them.

Types

category()

@type category() :: %{
  key: String.t(),
  label: String.t(),
  description: String.t() | nil,
  required: boolean(),
  defaults: %{required(String.t()) => String.t()}
}

t()

@type t() :: %Chime.Config{
  categories: [category()] | nil,
  channels: %{required(String.t()) => {module(), keyword()}},
  digest: %{at: 0..23, weekly_on: atom(), email: module() | nil},
  email_from: String.t() | {String.t(), String.t()} | nil,
  gettext: module() | nil,
  keep_days: pos_integer() | nil,
  limits: %{required(String.t()) => {pos_integer(), pos_integer()}},
  mail_url: String.t() | nil,
  mailer: module() | nil,
  oban: %{name: term(), queue: atom()},
  prefix: String.t() | nil,
  pubsub: atom(),
  push: map() | nil,
  quiet_hours: {0..23, 0..23} | nil,
  repo: module(),
  resolver: module(),
  scheduler: boolean(),
  secret_key_base: String.t() | nil,
  url: String.t() | nil
}

Functions

new(opts)

@spec new(keyword()) :: t()

Builds the config from the options of the child, and checks them.