Jido.Messaging.Persistence behaviour (Jido Messaging v1.0.0)

Copy Markdown View Source

Behaviour for Jido.Messaging storage adapters.

Adapters provide persistence for rooms, participants, threads, and messages. Each adapter instance maintains its own state (e.g., ETS table references) to enable multiple isolated messaging instances in the same BEAM.

Implementing an Adapter

defmodule MyApp.CustomAdapter do
  @behaviour Jido.Messaging.Persistence

  @impl true
  def init(opts) do
    # Initialize adapter state
    {:ok, %{}}
  end

  # ... implement other callbacks
end

Summary

Callbacks

Create a binding between an internal room and an external platform room.

Delete bridge config.

Delete stored ingress subscription metadata.

Delete a message by ID

Delete a participant by ID

Delete a room by ID

Delete a room binding by ID.

Delete routing policy by room id.

Lookup a single directory entry by target and query.

Search directory entries by target and query.

Fetch bridge config by id.

Get a message by ID

Get a message by its external ID within a channel/instance context.

Get messages for a room with options (limit, before, after)

Fetch onboarding flow state by onboarding ID.

Get a participant by ID

Get a room by ID

Fetch routing policy by room id.

Get a thread by ID

Get a thread by room and external thread ID

Initialize the adapter with options. Returns adapter state.

List bridge configs with optional filters.

List stored ingress subscription metadata for a bridge.

List all bindings for a room.

List rooms with optional filters

List threads for a room

Persist bridge config.

Persist normalized ingress subscription metadata.

Save a message

Persist onboarding flow state.

Save a participant (insert or update)

Save a room (insert or update)

Persist routing policy.

Save a thread

Update a message's external_id after successful channel delivery.

Types

bridge_id()

@type bridge_id() :: String.t()

channel()

@type channel() :: atom()

directory_query()

@type directory_query() :: map()

directory_target()

@type directory_target() :: :participant | :room

external_id()

@type external_id() :: String.t()

message_id()

@type message_id() :: String.t()

onboarding_flow()

@type onboarding_flow() :: map()

onboarding_id()

@type onboarding_id() :: String.t()

participant_id()

@type participant_id() :: String.t()

room_id()

@type room_id() :: String.t()

state()

@type state() :: term()

Callbacks

create_room_binding(state, room_id, channel, bridge_id, external_id, attrs)

@callback create_room_binding(
  state(),
  room_id(),
  channel(),
  bridge_id(),
  external_id(),
  attrs :: map()
) :: {:ok, Jido.Messaging.RoomBinding.t()} | {:error, term()}

Create a binding between an internal room and an external platform room.

delete_bridge_config(state, t)

@callback delete_bridge_config(state(), String.t()) :: :ok | {:error, :not_found}

Delete bridge config.

delete_ingress_subscription(state, bridge_id, t)

(optional)
@callback delete_ingress_subscription(state(), bridge_id(), String.t()) ::
  :ok | {:error, :not_found}

Delete stored ingress subscription metadata.

delete_message(state, message_id)

@callback delete_message(state(), message_id()) :: :ok | {:error, term()}

Delete a message by ID

delete_participant(state, participant_id)

@callback delete_participant(state(), participant_id()) :: :ok | {:error, term()}

Delete a participant by ID

delete_room(state, room_id)

@callback delete_room(state(), room_id()) :: :ok | {:error, term()}

Delete a room by ID

delete_room_binding(state, binding_id)

@callback delete_room_binding(state(), binding_id :: String.t()) :: :ok | {:error, term()}

Delete a room binding by ID.

delete_routing_policy(state, t)

@callback delete_routing_policy(state(), String.t()) :: :ok | {:error, :not_found}

Delete routing policy by room id.

directory_lookup(state, directory_target, directory_query, opts)

@callback directory_lookup(
  state(),
  directory_target(),
  directory_query(),
  opts :: keyword()
) ::
  {:ok, map()} | {:error, :not_found | {:ambiguous, [map()]} | term()}

Lookup a single directory entry by target and query.

Returns {:error, {:ambiguous, matches}} when multiple entries satisfy the query.

directory_search(state, directory_target, directory_query, opts)

@callback directory_search(
  state(),
  directory_target(),
  directory_query(),
  opts :: keyword()
) ::
  {:ok, [map()]} | {:error, term()}

Search directory entries by target and query.

get_bridge_config(state, t)

@callback get_bridge_config(state(), String.t()) ::
  {:ok, Jido.Messaging.BridgeConfig.t()} | {:error, :not_found}

Fetch bridge config by id.

get_message(state, message_id)

@callback get_message(state(), message_id()) ::
  {:ok, Jido.Messaging.Message.t()} | {:error, :not_found}

Get a message by ID

get_message_by_external_id(state, channel, bridge_id, external_id)

@callback get_message_by_external_id(state(), channel(), bridge_id(), external_id()) ::
  {:ok, Jido.Messaging.Message.t()} | {:error, :not_found}

Get a message by its external ID within a channel/instance context.

Used for resolving reply_to references from external platforms.

get_messages(state, room_id, opts)

@callback get_messages(state(), room_id(), opts :: keyword()) ::
  {:ok, [Jido.Messaging.Message.t()]}

Get messages for a room with options (limit, before, after)

get_onboarding(state, onboarding_id)

@callback get_onboarding(state(), onboarding_id()) ::
  {:ok, onboarding_flow()} | {:error, :not_found}

Fetch onboarding flow state by onboarding ID.

get_or_create_participant_by_external_id(state, channel, external_id, attrs)

@callback get_or_create_participant_by_external_id(
  state(),
  channel(),
  external_id(),
  attrs :: map()
) :: {:ok, Jido.Chat.Participant.t()}

Get or create a participant by external ID.

Used when receiving messages from external channels to map external user IDs to internal participant IDs.

get_or_create_room_by_external_binding(state, channel, bridge_id, external_id, attrs)

@callback get_or_create_room_by_external_binding(
  state(),
  channel(),
  bridge_id(),
  external_id(),
  attrs :: map()
) :: {:ok, Jido.Chat.Room.t()}

Get or create a room by external binding.

Used when receiving messages from external channels to map external chat IDs to internal room IDs.

get_participant(state, participant_id)

@callback get_participant(state(), participant_id()) ::
  {:ok, Jido.Chat.Participant.t()} | {:error, :not_found}

Get a participant by ID

get_room(state, room_id)

@callback get_room(state(), room_id()) :: {:ok, Jido.Chat.Room.t()} | {:error, :not_found}

Get a room by ID

get_room_by_external_binding(state, channel, bridge_id, external_id)

@callback get_room_by_external_binding(state(), channel(), bridge_id(), external_id()) ::
  {:ok, Jido.Chat.Room.t()} | {:error, :not_found}

Get a room by its external binding.

Returns the room if a binding exists, otherwise :not_found.

get_routing_policy(state, t)

@callback get_routing_policy(state(), String.t()) ::
  {:ok, Jido.Messaging.RoutingPolicy.t()} | {:error, :not_found}

Fetch routing policy by room id.

get_thread(state, t)

@callback get_thread(state(), String.t()) ::
  {:ok, Jido.Messaging.Thread.t()} | {:error, :not_found}

Get a thread by ID

get_thread_by_external_id(state, room_id, t)

@callback get_thread_by_external_id(state(), room_id(), String.t()) ::
  {:ok, Jido.Messaging.Thread.t()} | {:error, :not_found}

Get a thread by room and external thread ID

get_thread_by_root_message(state, room_id, message_id)

@callback get_thread_by_root_message(state(), room_id(), message_id()) ::
  {:ok, Jido.Messaging.Thread.t()} | {:error, :not_found}

Get a thread by root message ID

init(opts)

@callback init(opts :: keyword()) :: {:ok, state()} | {:error, term()}

Initialize the adapter with options. Returns adapter state.

list_bridge_configs(state, keyword)

@callback list_bridge_configs(
  state(),
  keyword()
) :: {:ok, [Jido.Messaging.BridgeConfig.t()]}

List bridge configs with optional filters.

list_ingress_subscriptions(state, bridge_id, keyword)

(optional)
@callback list_ingress_subscriptions(state(), bridge_id(), keyword()) ::
  {:ok, [Jido.Messaging.IngressSubscription.t()]}

List stored ingress subscription metadata for a bridge.

list_room_bindings(state, room_id)

@callback list_room_bindings(state(), room_id()) ::
  {:ok, [Jido.Messaging.RoomBinding.t()]}

List all bindings for a room.

list_rooms(state, opts)

@callback list_rooms(state(), opts :: keyword()) :: {:ok, [Jido.Chat.Room.t()]}

List rooms with optional filters

list_threads(state, room_id, opts)

@callback list_threads(state(), room_id(), opts :: keyword()) ::
  {:ok, [Jido.Messaging.Thread.t()]}

List threads for a room

save_bridge_config(state, t)

@callback save_bridge_config(state(), Jido.Messaging.BridgeConfig.t()) ::
  {:ok, Jido.Messaging.BridgeConfig.t()} | {:error, term()}

Persist bridge config.

save_ingress_subscription(state, t)

(optional)
@callback save_ingress_subscription(state(), Jido.Messaging.IngressSubscription.t()) ::
  {:ok, Jido.Messaging.IngressSubscription.t()} | {:error, term()}

Persist normalized ingress subscription metadata.

save_message(state, t)

@callback save_message(state(), Jido.Messaging.Message.t()) ::
  {:ok, Jido.Messaging.Message.t()} | {:error, term()}

Save a message

save_onboarding(state, onboarding_flow)

@callback save_onboarding(state(), onboarding_flow()) ::
  {:ok, onboarding_flow()} | {:error, term()}

Persist onboarding flow state.

save_participant(state, t)

@callback save_participant(state(), Jido.Chat.Participant.t()) ::
  {:ok, Jido.Chat.Participant.t()} | {:error, term()}

Save a participant (insert or update)

save_room(state, t)

@callback save_room(state(), Jido.Chat.Room.t()) ::
  {:ok, Jido.Chat.Room.t()} | {:error, term()}

Save a room (insert or update)

save_routing_policy(state, t)

@callback save_routing_policy(state(), Jido.Messaging.RoutingPolicy.t()) ::
  {:ok, Jido.Messaging.RoutingPolicy.t()} | {:error, term()}

Persist routing policy.

save_thread(state, t)

@callback save_thread(state(), Jido.Messaging.Thread.t()) ::
  {:ok, Jido.Messaging.Thread.t()} | {:error, term()}

Save a thread

update_message_external_id(state, message_id, external_id)

@callback update_message_external_id(state(), message_id(), external_id()) ::
  {:ok, Jido.Messaging.Message.t()} | {:error, term()}

Update a message's external_id after successful channel delivery.

Used to record the external platform's message ID after sending.