Anu.Message (Anu v0.2.0)

Copy Markdown View Source

A composable message builder for the WhatsApp Business API.

Anu.Message is a plain struct that accumulates state as you pipe through builder functions. The struct is only serialized to the Meta API format when Anu.deliver/2 is called.

Examples

# Simple text message
Anu.Message.new("+5511999999999")
|> Anu.Message.text("Hello!")
|> Anu.deliver(client)

# Interactive message with buttons
Anu.Message.new("+5511999999999")
|> Anu.Message.text("Pick a color")
|> Anu.Message.buttons([{"Red", "red"}, {"Blue", "blue"}])
|> Anu.deliver(client)

# List message with sections
Anu.Message.new("+5511999999999")
|> Anu.Message.text("Our menu")
|> Anu.Message.button_text("View menu")
|> Anu.Message.sections([
  Anu.Section.new("Drinks", [
    Anu.Row.new("coffee", "Coffee"),
    Anu.Row.new("tea", "Tea")
  ])
])
|> Anu.deliver(client)

Summary

Functions

Sets the message as an audio message.

Alias for text/2. Useful when building interactive messages where "body" is the natural term.

Sets the CTA button text for list messages.

Sets quick reply buttons on the message.

Sets the message as a standalone document.

Sets the footer text on the message.

Sets a document header on the message.

Sets an image header on the message.

Sets a text header on the message.

Sets a video header on the message.

Sets the message as a standalone image.

Sets a location on the message.

Creates a new message addressed to the given phone number.

Sets the message as a reaction to another message.

Sets this message as a reply to another message.

Sets the list sections on the message.

Sets the message as a sticker.

Sets the message as a template message.

Sets the text body of the message.

Sets the message as a standalone video.

Types

t()

@type t() :: %Anu.Message{
  body: String.t() | nil,
  button_text: String.t() | nil,
  buttons: [{String.t(), String.t() | atom()}] | nil,
  context: map() | nil,
  footer: String.t() | nil,
  header: map() | nil,
  location: map() | nil,
  media: map() | nil,
  reaction: map() | nil,
  sections: [Anu.Section.t()] | nil,
  template: map() | nil,
  to: String.t() | nil,
  type: atom() | nil
}

Functions

audio(message, url)

@spec audio(t(), String.t()) :: t()

Sets the message as an audio message.

Examples

iex> Anu.Message.new("+55") |> Anu.Message.audio("https://a.com/audio.ogg")
%Anu.Message{to: "+55", media: %{type: "audio", url: "https://a.com/audio.ogg", caption: nil, filename: nil}}

body(message, text)

@spec body(t(), String.t()) :: t()

Alias for text/2. Useful when building interactive messages where "body" is the natural term.

button_text(message, text)

@spec button_text(t(), String.t()) :: t()

Sets the CTA button text for list messages.

Examples

iex> Anu.Message.new("+55") |> Anu.Message.button_text("View options")
%Anu.Message{to: "+55", button_text: "View options"}

buttons(message, buttons)

@spec buttons(t(), [{String.t(), String.t() | atom()}]) :: t()

Sets quick reply buttons on the message.

Each button is a {title, payload} tuple. Maximum 3 buttons.

Examples

iex> Anu.Message.new("+55") |> Anu.Message.buttons([{"Yes", "yes"}, {"No", "no"}])
%Anu.Message{to: "+55", buttons: [{"Yes", "yes"}, {"No", "no"}]}

iex> Anu.Message.new("+55") |> Anu.Message.buttons([{"Track", :track}, {"Cancel", :cancel}])
%Anu.Message{to: "+55", buttons: [{"Track", :track}, {"Cancel", :cancel}]}

document(message, url, filename, opts \\ [])

@spec document(t(), String.t(), String.t(), keyword()) :: t()

Sets the message as a standalone document.

Options

  • :caption - document caption

Examples

iex> Anu.Message.new("+55") |> Anu.Message.document("https://d.com/f.pdf", "file.pdf")
%Anu.Message{to: "+55", media: %{type: "document", url: "https://d.com/f.pdf", caption: nil, filename: "file.pdf"}}

footer(message, text)

@spec footer(t(), String.t()) :: t()

Sets the footer text on the message.

Examples

iex> Anu.Message.new("+55") |> Anu.Message.footer("Powered by Anu")
%Anu.Message{to: "+55", footer: "Powered by Anu"}

header_document(message, url, filename)

@spec header_document(t(), String.t(), String.t()) :: t()

Sets a document header on the message.

Examples

iex> Anu.Message.new("+55") |> Anu.Message.header_document("https://d.com/f.pdf", "file.pdf")
%Anu.Message{to: "+55", header: %{type: "document", document: %{link: "https://d.com/f.pdf", filename: "file.pdf"}}}

header_image(message, url)

@spec header_image(t(), String.t()) :: t()

Sets an image header on the message.

Examples

iex> Anu.Message.new("+55") |> Anu.Message.header_image("https://img.com/a.png")
%Anu.Message{to: "+55", header: %{type: "image", image: %{link: "https://img.com/a.png"}}}

header_text(message, text)

@spec header_text(t(), String.t()) :: t()

Sets a text header on the message.

Examples

iex> Anu.Message.new("+55") |> Anu.Message.header_text("Welcome")
%Anu.Message{to: "+55", header: %{type: "text", text: "Welcome"}}

header_video(message, url)

@spec header_video(t(), String.t()) :: t()

Sets a video header on the message.

Examples

iex> Anu.Message.new("+55") |> Anu.Message.header_video("https://vid.com/v.mp4")
%Anu.Message{to: "+55", header: %{type: "video", video: %{link: "https://vid.com/v.mp4"}}}

image(message, url, opts \\ [])

@spec image(t(), String.t(), keyword()) :: t()

Sets the message as a standalone image.

Options

  • :caption - image caption

Examples

iex> Anu.Message.new("+55") |> Anu.Message.image("https://img.com/a.png", caption: "Look!")
%Anu.Message{to: "+55", media: %{type: "image", url: "https://img.com/a.png", caption: "Look!", filename: nil}}

location(message, latitude, longitude, opts \\ [])

@spec location(t(), number(), number(), keyword()) :: t()

Sets a location on the message.

Options

  • :name - location name
  • :address - location address

Examples

iex> Anu.Message.new("+55") |> Anu.Message.location(-23.5505, -46.6333, name: "Sao Paulo")
%Anu.Message{to: "+55", location: %{latitude: -23.5505, longitude: -46.6333, name: "Sao Paulo", address: nil}}

new(to)

@spec new(String.t()) :: t()

Creates a new message addressed to the given phone number.

Examples

iex> Anu.Message.new("+5511999999999")
%Anu.Message{to: "+5511999999999"}

react(message, emoji, opts)

@spec react(t(), String.t(), keyword()) :: t()

Sets the message as a reaction to another message.

Options

  • :message_id (required) - the ID of the message to react to

Examples

iex> Anu.Message.new("+55") |> Anu.Message.react("👍", message_id: "wamid.123")
%Anu.Message{to: "+55", reaction: %{emoji: "👍", message_id: "wamid.123"}}

reply_to(message, message_id)

@spec reply_to(t(), String.t()) :: t()

Sets this message as a reply to another message.

Examples

iex> Anu.Message.new("+55") |> Anu.Message.reply_to("wamid.123")
%Anu.Message{to: "+55", context: %{message_id: "wamid.123"}}

sections(message, sections)

@spec sections(t(), [Anu.Section.t()]) :: t()

Sets the list sections on the message.

Examples

iex> sections = [Anu.Section.new("S", [Anu.Row.new("a", "A")])]
iex> Anu.Message.new("+55") |> Anu.Message.sections(sections)
%Anu.Message{to: "+55", sections: [%Anu.Section{title: "S", rows: [%Anu.Row{id: "a", title: "A", description: nil}]}]}

sticker(message, url)

@spec sticker(t(), String.t()) :: t()

Sets the message as a sticker.

Examples

iex> Anu.Message.new("+55") |> Anu.Message.sticker("https://s.com/sticker.webp")
%Anu.Message{to: "+55", media: %{type: "sticker", url: "https://s.com/sticker.webp", caption: nil, filename: nil}}

template(message, name, language, components \\ [])

@spec template(t(), String.t(), String.t(), [map()]) :: t()

Sets the message as a template message.

components is a list of component maps built with Anu.Template helpers.

Examples

Anu.Message.new("+55")
|> Anu.Message.template("hello_world", "en_US", [
  Anu.Template.body_param("John")
])

text(message, body)

@spec text(t(), String.t()) :: t()

Sets the text body of the message.

Examples

iex> Anu.Message.new("+5511999999999") |> Anu.Message.text("Hello!")
%Anu.Message{to: "+5511999999999", body: "Hello!"}

video(message, url, opts \\ [])

@spec video(t(), String.t(), keyword()) :: t()

Sets the message as a standalone video.

Options

  • :caption - video caption

Examples

iex> Anu.Message.new("+55") |> Anu.Message.video("https://vid.com/v.mp4")
%Anu.Message{to: "+55", media: %{type: "video", url: "https://vid.com/v.mp4", caption: nil, filename: nil}}