# amarula v0.5.7 - Table of Contents

> An independent, OTP-native WhatsApp Web client for Elixir — Noise handshake, Signal end-to-end encryption, multi-device.

## Pages

- [Amarula](readme.md)
- [Infrastructure](infrastructure.md)
- [SessionCustodian Concurrency Benchmarks](custodian_benchmarks.md)
- [LID vs PN — Identity in Amarula](lid_pn.md)
- [Going to Production](going_prod.md)
- [Upstream References](parity.md)
- [Pitfalls &amp; Diagnostics](pitfalls.md)
- [Changelog](changelog.md)
- [LICENSE](license.md)
- [NOTICE](notice.md)

## Modules

- [Amarula](Amarula.md): Amarula — a WhatsApp Web client for Elixir.
- [Amarula.Address](Amarula.Address.md): A WhatsApp address — the consumer-facing way to name *who/what* a message is
for or from. A friendly value you can build, inspect, and pass to sends, instead
of juggling raw `"user@server"` jid strings.
- [Amarula.AppState](Amarula.AppState.md): Consumer-facing app-state sync controls.
- [Amarula.Chat](Amarula.Chat.md): A chat update derived from app-state sync — the consumer view of a mutation to
a conversation. `address` is the chat (`Amarula.Address`: 1:1 or group); the
other fields are the change carried by the mutation (nil = unchanged).
- [Amarula.Config](Amarula.Config.md): Connection config + the single source of truth for protocol/connection defaults.
- [Amarula.Conn](Amarula.Conn.md): A connection handle: everything Amarula knows about one connection, built once
from its config at connect time and threaded through the protocol layer.
- [Amarula.Connection](Amarula.Connection.md): The per-connection process that owns the entire server conversation: the
`WebSocketClient`, the noise cipher (frame encode/decode + counters), IQ
correlation, login/handshake, send dispatch, and server-notification handling.
- [Amarula.Contact](Amarula.Contact.md): A contact update from app-state sync — the consumer view of a `contactAction`
(a saved name) or the local push-name setting. `address` is the contact.

- [Amarula.Contacts](Amarula.Contacts.md): Contact discovery via USync. The consumer-facing half of Baileys' `onWhatsApp`
/ `fetchStatus`.
- [Amarula.Group](Amarula.Group.md): Group chats — the `%Amarula.Group{}` struct *and* every group operation.
- [Amarula.MessageSecretStore](Amarula.MessageSecretStore.md): Pluggable store of inbound messages' `messageContextInfo.messageSecret`, keyed
by message id — the key material needed to decrypt a later
`secretEncryptedMessage` MESSAGE_EDIT envelope targeting that message (issue
#30; see `Amarula.Protocol.Messages.EditEnvelope`).
- [Amarula.Msg](Amarula.Msg.md): A received message in consumer terms — the friendly view of a decrypted
`%Proto.Message{}`. Delivered in `{:amarula, :messages_upsert, %{messages:
[%Msg{}]}}`, so consumers never pattern-match the large WA protobuf.
- [Amarula.Plugin](Amarula.Plugin.md): Req-style plugin pipelines for a connection.
- [Amarula.Plugins.MessageStore](Amarula.Plugins.MessageStore.md): Example/reference plugin: a persistent message store.
- [Amarula.Profile](Amarula.Profile.md): Profile reads and writes: fetch a profile-picture URL, set/remove your (or a
group's) picture, and set your status/bio. The consumer-facing half of Baileys'
`profilePictureUrl` / `updateProfilePicture` / `removeProfilePicture` /
`updateProfileStatus`.
- [Amarula.ProfileRegistry](Amarula.ProfileRegistry.md): The app-level `profile -> Connection pid` registry: the seam that enforces one
connection per profile and lets a consumer refer to a connection by its
`:profile` (restart-safe) rather than a raw pid.
- [Amarula.Protocol.Call](Amarula.Protocol.Call.md): Parse inbound `<call>` stanzas, ported from Baileys `handleCall` /
`getCallStatusFromNode` (`src/Socket/messages-recv.ts`).
- [Amarula.Protocol.Messages.Poll](Amarula.Protocol.Messages.Poll.md): Poll vote tally, ported from Baileys `getAggregateVotesInPollMessage`
(`src/Utils/messages.ts`).
- [Amarula.Protocol.Messages.PollCrypto](Amarula.Protocol.Messages.PollCrypto.md): Decrypt poll votes, ported from Baileys `decryptPollVote`
(`src/Utils/process-message.ts`).
- [Amarula.RetryCache](Amarula.RetryCache.md): Pluggable cache of recently-sent messages, so the library can re-encrypt and
resend when a recipient asks for a retry (`<receipt type="retry">`).
- [Amarula.Storage](Amarula.Storage.md): Pluggable, connection-scoped persistence for a connection's protocol state.
- [Amarula.SupervisedConnection](Amarula.SupervisedConnection.md): The process behind `Amarula.child_spec/1` — a thin owner that ties one Amarula
connection to *your* supervision tree, so a fixed set of (already-paired)
profiles come up at boot.
- [Amarula.Supervisor](Amarula.Supervisor.md): Amarula's shared process tree — you add this to your supervision tree.
- [Amarula.Telemetry](Amarula.Telemetry.md): `:telemetry` events emitted by Amarula — the operational-observability surface.
- [Amarula.Testing](Amarula.Testing.md): Test support for **consumers** of Amarula — drive your bot with synthetic
inbound messages, with no WhatsApp connection.
- [Amarula.Content.Contact](Amarula.Content.Contact.md): A received contact card (`content` of a `%Amarula.Msg{type: :contact}`, and
each element of a `:contacts` array).
- [Amarula.Content.Contacts](Amarula.Content.Contacts.md): A received multi-contact card (`content` of a `%Amarula.Msg{type: :contacts}`).
- [Amarula.Content.Edit](Amarula.Content.Edit.md): A received message edit (`content` of a `%Amarula.Msg{type: :edit}`).
- [Amarula.Content.Event](Amarula.Content.Event.md): A received event (`content` of a `%Amarula.Msg{type: :event}`).
- [Amarula.Content.GroupInvite](Amarula.Content.GroupInvite.md): A received group-invite card (`content` of a
`%Amarula.Msg{type: :group_invite}`) — a tap-to-join invite for a group.
- [Amarula.Content.Keep](Amarula.Content.Keep.md): A received keep-in-chat / undo (`content` of a `%Amarula.Msg{type: :keep}`).
- [Amarula.Content.LinkPreview](Amarula.Content.LinkPreview.md): The link-preview metadata a text message carries for a URL it contains — the
title/description/thumbnail card WhatsApp shows under a link. Rides on an
`extendedTextMessage`; a plain text message (or a reply/mention with no link)
has none.
- [Amarula.Content.Location](Amarula.Content.Location.md): A received location (`content` of a `%Amarula.Msg{type: :location}`, and the
`:location` of an event).
- [Amarula.Content.Media](Amarula.Content.Media.md): A received media attachment (`content` of a `%Amarula.Msg{type: :media}`) — an
inbound image / video / audio / document / sticker. A plain snake_case struct,
not the raw protobuf. Pass it (or the whole `%Amarula.Msg{}`) to
`Amarula.download_media/1` to fetch and decrypt the bytes — no live connection
needed; the keys ride in this struct.
- [Amarula.Content.MemberTag](Amarula.Content.MemberTag.md): A received group member-label change (`content` of a
`%Amarula.Msg{type: :member_tag}`).
- [Amarula.Content.Options](Amarula.Content.Options.md): An incoming **interactive message that presents a set of choices** — a list
menu, a buttons message, a template-button message, or a native-flow
interactive message. These are what WhatsApp Business / call-center / automated
flows send to ask "pick one of these". A normal linked-device client can't send
them, but it receives them; the user's reply comes back as an
`%Amarula.Content.Response{}`.
- [Amarula.Content.Order](Amarula.Content.Order.md): A received order message (WhatsApp Business). Surfaces the few useful fields; for
full detail read `msg.raw`.
- [Amarula.Content.Pin](Amarula.Content.Pin.md): A received pin / unpin (`content` of a `%Amarula.Msg{type: :pin}`).
- [Amarula.Content.Poll](Amarula.Content.Poll.md): A received poll (`content` of a `%Amarula.Msg{type: :poll}`).
- [Amarula.Content.PollVote](Amarula.Content.PollVote.md): A received poll vote (`content` of a `%Amarula.Msg{type: :poll_vote}`).
- [Amarula.Content.Product](Amarula.Content.Product.md): A received product message (WhatsApp Business). A linked-device client can
receive these but not send them; this surfaces the few useful fields. For full
catalog detail, read `msg.raw`.
- [Amarula.Content.Protocol](Amarula.Content.Protocol.md): A received control frame (`content` of a `%Amarula.Msg{type: :protocol}`) — a
bare `protocolMessage` Amarula doesn't surface as a user message (ephemeral /
setting changes and other unhandled types). Delivered on the `:protocol_update`
event, not `:messages_upsert`.
- [Amarula.Content.Reaction](Amarula.Content.Reaction.md): A received reaction (`content` of a `%Amarula.Msg{type: :reaction}`).
- [Amarula.Content.Response](Amarula.Content.Response.md): A reply a user made to an interactive message — a button tap, list selection,
template-button reply, or interactive response. Unified into one shape since they
all share one shape: the user picked an option identified by `id`, shown as `text`.
- [Amarula.Content.Revoke](Amarula.Content.Revoke.md): A received delete-for-everyone (`content` of a `%Amarula.Msg{type: :revoke}`).
- [Amarula.MessageSecretStore.ETS](Amarula.MessageSecretStore.ETS.md): In-memory `Amarula.MessageSecretStore` adapter — the default.
- [Amarula.MessageSecretStore.ReadOnly](Amarula.MessageSecretStore.ReadOnly.md): A read-only `Amarula.MessageSecretStore` adapter backed by **your** message
store.
- [Amarula.MessageSecretStore.Scope](Amarula.MessageSecretStore.Scope.md): A message-secret-store scope: the resolved adapter plus its state. Handed to an
adapter (with the connection `profile`) on each call. Mirrors
`Amarula.RetryCache.Scope` but for the message-secret concern (issue #30).

- [Amarula.RetryCache.DETS](Amarula.RetryCache.DETS.md): On-disk `Amarula.RetryCache` adapter — survives restart.
- [Amarula.RetryCache.ETS](Amarula.RetryCache.ETS.md): In-memory `Amarula.RetryCache` adapter — the default.
- [Amarula.RetryCache.ReadOnly](Amarula.RetryCache.ReadOnly.md): A read-only `Amarula.RetryCache` adapter backed by **your** message store.
- [Amarula.RetryCache.Scope](Amarula.RetryCache.Scope.md): A retry-cache scope: the resolved adapter plus its state. Handed to a cache
adapter (with the connection `profile`) on each call. Mirrors
`Amarula.Storage.Scope` but for the separate retry-cache concern.

- [Amarula.RetryCache.Step](Amarula.RetryCache.Step.md): The built-in send-pipeline step that records each outgoing message in the
`Amarula.RetryCache`, so it can be re-encrypted and resent if the recipient
asks for a retry. Attached by default (see `Amarula.Conn`); a side-effect step
that never transforms or halts.
- [Amarula.Storage.Adapter](Amarula.Storage.Adapter.md): Ergonomic base for writing an `Amarula.Storage` adapter.
- [Amarula.Storage.DETS](Amarula.Storage.DETS.md): DETS `Amarula.Storage` adapter for durable account state — a peer to
`Amarula.Storage.File`.
- [Amarula.Storage.File](Amarula.Storage.File.md): Filesystem `Amarula.Storage` adapter — the default plugin.
- [Amarula.Storage.Scope](Amarula.Storage.Scope.md): A storage scope: the resolved adapter plus its per-connection state.

## Mix Tasks

- [mix amarula.pair](Mix.Tasks.Amarula.Pair.md): Link (pair) a WhatsApp account to a named profile — by QR code or phone code.

