# `KapsoEx.WhatsApp.Messages`
[🔗](https://github.com/rocket4ce/kapso_ex/blob/v0.1.0/lib/kapso_ex/whatsapp/messages.ex#L1)

Send WhatsApp messages and read stored message history.

## Recipients

Every `send_*` function takes a `to` argument, which is either:

  * a phone number string, such as `"56961567267"`, or
  * a map or keyword list with `:to` (phone number) and/or `:recipient`
    (a business-scoped user ID, such as `"US.13491208655302741918"`).
    When both are given, Meta delivers to the phone number.

## Common options

Every `send_*` function accepts:

  * `:reply_to` - WhatsApp message ID (`wamid...`) to quote as a reply.
  * `:biz_opaque_callback_data` - string echoed back in status webhooks.
  * `:take_control` - on a [shared number](https://docs.kapso.ai/docs/whatsapp/conversation-routing),
    send even though another app handles the conversation (and take it).
    Only works when Kapso is your escalation app.

## Media

Media arguments accept a URL (sent as `link`), a media ID returned by
`KapsoEx.WhatsApp.Media.upload/4` (sent as `id`), or a map with Meta's
fields (`%{id: ..., caption: ...}`).

## Responses

Sends return Meta's response:

    {:ok, %{"messaging_product" => "whatsapp",
            "contacts" => [%{"input" => "56961567267", "wa_id" => "56961567267"}],
            "messages" => [%{"id" => "wamid.HBgL..."}]}}

# `media`

```elixir
@type media() :: String.t() | map()
```

# `phone_number_id`

```elixir
@type phone_number_id() :: String.t()
```

# `result`

```elixir
@type result() :: {:ok, map()} | {:error, KapsoEx.Error.t()}
```

# `to`

```elixir
@type to() ::
  String.t()
  | %{optional(:to) =&gt; String.t(), optional(:recipient) =&gt; String.t()}
  | keyword()
```

# `get`

```elixir
@spec get(KapsoEx.Client.t(), phone_number_id(), String.t(), map() | keyword()) ::
  result()
```

Gets a stored message by its WhatsApp message ID. Params: `fields`.

# `list`

```elixir
@spec list(KapsoEx.Client.t(), phone_number_id(), map() | keyword()) :: result()
```

Lists stored messages for a phone number, newest first.

## Params

`conversation_id`, `direction` (`"inbound"`/`"outbound"`), `status`,
`since`, `until`, `limit`, `before`, `after` and `fields` (see
`KapsoEx.WhatsApp.kapso_fields/1`).

Paginates with cursors under `paging.cursors`; see `KapsoEx.Pagination`.

# `mark_read`

```elixir
@spec mark_read(KapsoEx.Client.t(), phone_number_id(), String.t(), keyword()) ::
  result()
```

Marks an inbound message as read.

## Options

  * `:typing_indicator` - when `true`, also shows a typing indicator until
    you reply (or for about 25 seconds).

# `send`

```elixir
@spec send(KapsoEx.Client.t(), phone_number_id(), map() | keyword(), keyword()) ::
  result()
```

Sends a raw message payload, as documented by Meta.

`messaging_product: "whatsapp"` is added when missing. Use this for message
types without a dedicated helper. Accepts the `:take_control` option.

    Messages.send(client, phone_number_id, %{
      to: "56961567267",
      type: "interactive",
      interactive: %{type: "product", body: %{text: "Look"}, action: %{catalog_id: "1", product_retailer_id: "sku"}}
    })

# `send_audio`

```elixir
@spec send_audio(KapsoEx.Client.t(), phone_number_id(), to(), media(), keyword()) ::
  result()
```

Sends an audio file.

## Options

  * `:voice` - send as a voice note (`.ogg` file with the OPUS codec).

Plus the common options.

# `send_buttons`

```elixir
@spec send_buttons(
  KapsoEx.Client.t(),
  phone_number_id(),
  to(),
  String.t(),
  [{String.t(), String.t()} | map()],
  keyword()
) :: result()
```

Sends up to three reply buttons.

`buttons` is a list of `{id, title}` tuples or of full button maps.

## Options

  * `:header` - a string (text header) or a header map (image, video, document).
  * `:footer` - footer text.

Plus the common options.

## Examples

    Messages.send_buttons(client, phone_number_id, "56961567267", "Confirm your order?",
      [{"yes", "Yes"}, {"no", "No"}], footer: "Reply within 24h")

# `send_contacts`

```elixir
@spec send_contacts(KapsoEx.Client.t(), phone_number_id(), to(), [map()], keyword()) ::
  result()
```

Sends one or more contact cards.

    Messages.send_contacts(client, phone_number_id, "56961567267", [
      %{name: %{formatted_name: "Ada Lovelace"}, phones: [%{phone: "+44123456789", type: "WORK"}]}
    ])

# `send_cta_url`

```elixir
@spec send_cta_url(
  KapsoEx.Client.t(),
  phone_number_id(),
  to(),
  String.t(),
  String.t(),
  String.t(),
  keyword()
) :: result()
```

Sends a call-to-action button that opens `url`.

Options: `:header`, `:footer`, plus the common options.

# `send_document`

```elixir
@spec send_document(KapsoEx.Client.t(), phone_number_id(), to(), media(), keyword()) ::
  result()
```

Sends a document. Options: `:caption`, `:filename`, plus the common options.

# `send_flow`

```elixir
@spec send_flow(
  KapsoEx.Client.t(),
  phone_number_id(),
  to(),
  String.t(),
  map() | keyword(),
  keyword()
) ::
  result()
```

Sends a WhatsApp Flow.

`parameters` are the flow action parameters, such as `:flow_id`,
`:flow_cta`, `:flow_token`, `:mode`, `:flow_action` and
`:flow_action_payload`. `flow_message_version` defaults to `"3"`.

Options: `:header`, `:footer`, plus the common options.

    Messages.send_flow(client, phone_number_id, "56961567267", "Book your appointment",
      %{flow_id: "123456789", flow_cta: "Book now", flow_action: "navigate",
        flow_action_payload: %{screen: "BOOKING"}})

# `send_image`

```elixir
@spec send_image(KapsoEx.Client.t(), phone_number_id(), to(), media(), keyword()) ::
  result()
```

Sends an image. Options: `:caption`, plus the common options.

# `send_interactive`

```elixir
@spec send_interactive(
  KapsoEx.Client.t(),
  phone_number_id(),
  to(),
  map() | keyword(),
  keyword()
) ::
  result()
```

Sends an interactive message with a raw `interactive` object, for types
without a dedicated helper (product, product list, catalog, carousel,
address, call permission request, voice call, ...).

# `send_list`

```elixir
@spec send_list(
  KapsoEx.Client.t(),
  phone_number_id(),
  to(),
  String.t(),
  String.t(),
  [map()],
  keyword()
) ::
  result()
```

Sends a list picker.

`sections` is a list of `%{title: ..., rows: [%{id: ..., title: ..., description: ...}]}`
(up to 10 rows in total). `button` is the label of the button that opens
the list.

Options: `:header`, `:footer`, plus the common options.

# `send_location`

```elixir
@spec send_location(
  KapsoEx.Client.t(),
  phone_number_id(),
  to(),
  map() | keyword(),
  keyword()
) ::
  result()
```

Sends a location pin.

    Messages.send_location(client, phone_number_id, "56961567267",
      %{latitude: -33.4489, longitude: -70.6693, name: "Santiago", address: "CL"})

# `send_location_request`

```elixir
@spec send_location_request(
  KapsoEx.Client.t(),
  phone_number_id(),
  to(),
  String.t(),
  keyword()
) ::
  result()
```

Asks the user to share their current location.

# `send_marketing_template`

```elixir
@spec send_marketing_template(
  KapsoEx.Client.t(),
  phone_number_id(),
  to(),
  String.t(),
  String.t(),
  keyword()
) :: result()
```

Sends a marketing template through Meta's Marketing Messages API
(`POST /{phone_number_id}/marketing_messages`).

Takes the same arguments and options as `send_template/6`.

# `send_reaction`

```elixir
@spec send_reaction(
  KapsoEx.Client.t(),
  phone_number_id(),
  to(),
  String.t(),
  String.t(),
  keyword()
) ::
  result()
```

Reacts to `message_id` with `emoji`. Send `""` to remove a reaction.

# `send_sticker`

```elixir
@spec send_sticker(KapsoEx.Client.t(), phone_number_id(), to(), media(), keyword()) ::
  result()
```

Sends a sticker (`.webp`).

# `send_template`

```elixir
@spec send_template(
  KapsoEx.Client.t(),
  phone_number_id(),
  to(),
  String.t(),
  String.t(),
  keyword()
) ::
  result()
```

Sends an approved template.

`language` is a language code such as `"es"` or `"en_US"`. Build
`:components` by hand or with `KapsoEx.WhatsApp.TemplateComponents`.

## Options

  * `:components` - list of template components with parameters.

Plus the common options.

## Examples

    Messages.send_template(client, phone_number_id, "56961567267", "order_update", "es",
      components: [
        %{type: "body", parameters: [%{type: "text", text: "Ana"}, %{type: "text", text: "#1234"}]}
      ]
    )

# `send_text`

```elixir
@spec send_text(KapsoEx.Client.t(), phone_number_id(), to(), String.t(), keyword()) ::
  result()
```

Sends a text message.

## Options

  * `:preview_url` - render a preview for the first URL in `body`.

Plus the common options in the module docs.

# `send_video`

```elixir
@spec send_video(KapsoEx.Client.t(), phone_number_id(), to(), media(), keyword()) ::
  result()
```

Sends a video. Options: `:caption`, plus the common options.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
