Chime.Resolver behaviour (Chime v0.1.0-dev)

Copy Markdown View Source

How Chime knows the people of the app. The app writes one module, from the users it already has, and gives it to Chime's config:

defmodule MyApp.ChimeResolver do
  @behaviour Chime.Resolver

  import Ecto.Query

  alias MyApp.{Repo, User}

  @impl true
  def recipient(%User{} = user) do
    %Chime.Recipient{
      id: "user:#{user.id}",
      email: user.email,
      name: user.name,
      locale: user.locale,
      time_zone: user.time_zone
    }
  end

  @impl true
  def recipients(ids) do
    ids = for "user:" <> id <- ids, do: String.to_integer(id)

    from(u in User, where: u.id in ^ids and is_nil(u.deleted_at))
    |> Repo.all()
    |> Enum.map(&recipient/1)
  end

  @impl true
  def resolve_recipient(%Plug.Conn{assigns: %{current_user: %User{} = user}}),
    do: recipient(user)

  def resolve_recipient(%Phoenix.LiveView.Socket{assigns: %{current_user: %User{} = user}}),
    do: recipient(user)

  def resolve_recipient(_nobody), do: nil
end

recipient/1 turns what a notifier's recipients/1 gives (the app's users) into a Chime.Recipient. recipients/1 finds the people by their ids when a delivery goes, which may be later than the notification (an email ten minutes after, a digest the next morning), so that it writes to their address of then; a person it does not give back gets nothing, and the log says why. resolve_recipient/1 says who reads the feed: from a Plug.Conn (the JSON API, after the app's own pipeline) or a LiveView socket (Chime.Live, after the app's own on_mount hooks). Nil is nobody: the API answers 401, and the bell is not shown.

Make the ids from the database, never from what a browser sends.

Summary

Callbacks

The recipient of something a notifier's recipients/1 gives.

The people of these ids that still are, in any order.

The person of a request or a LiveView, or nil.

The workspace of a request or a LiveView (a team, an organisation of the app's), or nil for the whole feed. With it, the bell, the feed, its counts and the preferences of Chime.Live and the JSON API are that workspace's. Without this function, the whole feed.

Callbacks

recipient(term)

(optional)
@callback recipient(term()) :: Chime.Recipient.t()

The recipient of something a notifier's recipients/1 gives.

recipients(list)

@callback recipients([String.t()]) :: [Chime.Recipient.t()]

The people of these ids that still are, in any order.

resolve_recipient(arg1)

@callback resolve_recipient(Plug.Conn.t() | Phoenix.LiveView.Socket.t()) ::
  Chime.Recipient.t() | nil

The person of a request or a LiveView, or nil.

resolve_workspace(arg1)

(optional)
@callback resolve_workspace(Plug.Conn.t() | Phoenix.LiveView.Socket.t()) ::
  String.t() | nil

The workspace of a request or a LiveView (a team, an organisation of the app's), or nil for the whole feed. With it, the bell, the feed, its counts and the preferences of Chime.Live and the JSON API are that workspace's. Without this function, the whole feed.