Skip to content

Whatsapp

Our preferred partner for using Whatsapp is 360dialog.

Contact card

Using show contact(...) it is possible to send a contact card. More info.

Sending template messages

Template messages are messages that can be sent outside the 24h window of Whatsapp interaction. They need to be pre-approved by Whatsapp and are managed in the Facebook Business manager.

In Bubblescript, sending templates is supported through the show template("text", ...) construct:

show template("text", template_id: "order_prompt", parameters: %{"1" => "John"})

This assumes a text template named order_prompt is available in Whatsapp, that has one parameter (for instance the template contents could be "Hi {{1}}, your order is ready").

Whatsapp templates can also contain a header, body, footer, and actions. For complex templates like this, you can use the show template("whatsapp", ...) construct:

show template("whatsapp", template_id: "complex_template", language_code: "en", components: [
  %{
    "type" => "header",
    "parameters" => [
      %{"type" => "image", "image" => %{"link" => "https://example.com/some_image.jpeg"}}
    ]
  },
  %{
    "type" => "body",
    "parameters" => [
      %{"type" => "text", "text" => "John Doe"},
      %{"type" => "text", "text" => "The message that I want you to see"}
    ]
  }
])

This will send a template named complex_template with the specified header and body parameters.

For complete documentation, refer to the Whatsapp template documentation

Parameters on template messages

Example of setting custom payload on template buttons:

dialog button_payloads do
  show template("whatsapp", template_id: "sample_issue_resolution", language_code: "en_US", components: [
    %{
      "type" => "body",
      "parameters" => [
        %{"type" => "text", "text" => "John Doe"},
      ]
    },
    %{
      "type" => "button",
      "sub_type" => "quick_reply",
      "index" => 0,
      "parameters" => [
        %{"type" => "payload", "payload" => "click-yes"}
      ]
    },
    %{
      "type" => "button",
      "sub_type" => "quick_reply",
      "index" => 1,
      "parameters" => [
        %{"type" => "payload", "payload" => "click-no"}
      ]
    }
  ])
end

Incoming button clicks with a payload set in the template components will be converted into $button_click events with a payload containing 2 parts: text and payload.

Example of sending custom URL parts in URL button template:

dialog url_button_text do
  show template("whatsapp", template_id: "sample_purchase_feedback", language_code: "en_US", components: [
    %{
      "type" => "body",
      "parameters" => [
        %{"type" => "text", "text" => "Asus DJI drone mk II"},
      ]
    },
    %{
      "type" => "button",
      "sub_type" => "url",
      "index" => 0,
      "parameters" => [
        %{"type" => "text", "text" => "survey1"}
      ]
    }
  ])
end

Interactive messages

The supported templates are: buttons, list, card, whatsapp, whatsapp_product, and whatsapp_product_list.

Buttons

The Bubblescript buttons template is sent as a Whatsapp interactive message:

_buttons = [
  %{title: "Order", type: "event", event: "order", payload: 1234},
  %{title: "Browse", type: "event", event: "browse"}
]
show template("buttons", buttons: _buttons, text: "What do you want to do next?")

Only buttons of type event are supported. When a button is clicked, the corresponding event is fired. An event payload can be added as well, which will be sent along. However, the payload must be kept very small, do not send big objects or lists as Whatsapp will give an error.

Item picker

The default item picker is supported natively on whatsapp. However, it only supports picking single items, picking multiple items is not possible.

List template

An alternative way of showing whatsapp's list picker is through using the list template.

Note that a text: argument has to be given to the list template, in contrast with other channels that support lists (Web/FB messenger).

  _items = [
    %{title: "Item number 1", subtitle: "This is is something about nr 1"},
    %{title: "Number 2", subtitle: "This is number 2"},
    %{title: "Number 3", subtitle: "The final item"}
  ]
  _button = [type: "event", title: "Choose", event: "choose"]
  show template("list", elements: _items, text: "Please choose an item", button: _button)

The list button has to be of the type event. The given event is used to indicate that a list item has been selected, where the payload is the element index in the list.

In the above example, when the second item in the list is chosen, the event "choose" is fired, with a payload of 1.

Product template

Show a single product that's registered in the product catalog.

show template("whatsapp_product", %{
  "body" => %{"text" => "This amazing new product"},
  "action" => %{
    "catalog_id" => "1234567...",
    "product_retailer_id" => "item1"
  }
})

Refer to the Whatsapp documentation for the complete structure.

Product list template

Shows a listing of products.

show template("whatsapp_product_list", %{
  "header" => %{
    "type" => "text",
    "text" => "Check out our new products"
  },
  "action" => %{
    "catalog_id" => "1234567...",
    "sections" => [
      %{
        "title" => "Shirts",
        "product_items" => [
          %{"product_retailer_id" => "shirt1"},
          %{"product_retailer_id" => "shirt2"}
        ]
      },
      %{
        "title" => "Pants",
        "product_items" => [
          %{"product_retailer_id" => "pants1"},
          %{"product_retailer_id" => "pants2"}
        ]
      }
    ]
  }
})

Refer to the Whatsapp documentation for the complete structure.

Adapter limitations

Incoming (user-sent) messages:

  • Contact cards are converted into text messages
  • Location pins drop the address, name and url field
  • Live locations are not supported. Instead an event called $unsupported_message is sent into the bot.

Outgoing (platform-sent) messages:

  • Stickers are converted into image attachments. Sticker metadata is kept inside attachment.metadata

Deliver status tracking

The delivery of whatsapp messages can be tracked in realtime using REST API webhooks, for the 360dialog adapter.

Error handling

After sending a message, the Whatsapp adapter waits on a message from the Whatsapp webhooks delivery status channel to check whether the message was successfully sent.

If the message failed to send, the __error__ dialog is invoked, which can be used to fall back to an alternative medium like sending an SMS message. The error.action global will be set (filled with the last outbound message, template or other payload) to indicate that the error was related to a delivery failure:

dialog __error__ when error.action do
  tag "delivery-error"
  sms(user.user_id, "Hi we cannot reach you on Whatsapp, here is a SMS fallback message")
end