Receive Inbound Messages and Interactions

Overview

This guide explains how to handle webhook responses when you receive inbound messages or interactions from your users on your WhatsApp number. The following use cases are covered in the code snippets below:

  • Your WhatsApp number is receiving a text message.
  • Your WhatsApp number is receiving a media message.
  • Your WhatsApp number is receiving a location message.
  • Your WhatsApp number is receiving a response when a user clicks a quick reply button sent in an interactive templated message.
  • Your WhatsApp number is receiving a response when a user clicks an interactive button message you sent.
  • Your WhatsApp number is receiving a response when a user clicks an interactive list message you sent.

Prerequisites

To get started, you need a Plivo account — sign up with your work email address if you don’t have one already. If this is your first time using Plivo APIs, follow our instructions to set up a Python development environment.

You must have an onboarded WhatsApp account to receive inbound messages. If a number is listed as connected, it can receive inbound messages.

Create a Flask application to receive messages.

Create a file called receive_whatsapp.py and paste into it this code.


package main

import (
    "encoding/json"
    "fmt"
    "net/http"
)

type Webhook struct {
    From        string `json:"From"`
    To          string `json:"To"`
    ContentType string `json:"ContentType"`
    Body        string `json:"Body"`
    Media0      string `json:"Media0"`
    Button      struct {
        Text    string `json:"Text"`
        Payload string `json:"Payload"`
    } `json:"Button"`
    Interactive struct {
        Type       string `json:"Type"`
        ButtonReply struct {
            Id    string `json:"Id"`
            Title string `json:"Title"`
        } `json:"ButtonReply"`
        ListReply struct {
            Id          string `json:"Id"`
            Title       string `json:"Title"`
            Description string `json:"Description"`
        } `json:"ListReply"`
    } `json:"Interactive"`
    Location struct {
        Latitude  string `json:"Latitude"`
        Longitude string `json:"Longitude"`
        Name      string `json:"Name"`
        Address   string `json:"Address"`
    } `json:"Location"`
}

func whatsappHandler(w http.ResponseWriter, r *http.Request) {
    var webhook Webhook
    err := json.NewDecoder(r.Body).Decode(&webhook)
    if err != nil {
        http.Error(w, "Invalid JSON", http.StatusBadRequest)
        return
    }

    fromNumber := webhook.From
    toNumber := webhook.To
    contentType := webhook.ContentType

    switch contentType {
    case "text":
        fmt.Printf("Text Message received - From: %s, To: %s, Text: %s\n", fromNumber, toNumber, webhook.Body)
    case "media":
        fmt.Printf("Media Message received - From: %s, To: %s, Media Attachment: %s, Caption: %s\n", fromNumber, toNumber, webhook.Media0, webhook.Body)
    case "button":
        fmt.Printf("Button Message received - From: %s, To: %s, Button Text: %s, Button Payload: %s\n", fromNumber, toNumber, webhook.Button.Text, webhook.Button.Payload)
    case "interactive":
        switch webhook.Interactive.Type {
        case "button_reply":
            fmt.Printf("Interactive Button - From: %s, To: %s, ID: %s, Title: %s\n", fromNumber, toNumber, webhook.Interactive.ButtonReply.Id, webhook.Interactive.ButtonReply.Title)
        case "list_reply":
            fmt.Printf("Interactive List - From: %s, To: %s, ID: %s, Title: %s, Description: %s\n", fromNumber, toNumber, webhook.Interactive.ListReply.Id, webhook.Interactive.ListReply.Title, webhook.Interactive.ListReply.Description)
        }
    case "location":
        fmt.Printf("Location - From: %s, To: %s, Latitude: %s, Longitude: %s, Name: %s, Address: %s\n", fromNumber, toNumber, webhook.Location.Latitude, webhook.Location.Longitude, webhook.Location.Name, webhook.Location.Address)
    }

    w.WriteHeader(http.StatusOK)
    w.Write([]byte("Message Received"))
}

func main() {
    http.HandleFunc("/receive_whatsapp/", whatsappHandler)
    http.ListenAndServe(":8080", nil)
}

Configure a webhook URL in your WhatsApp Business Account

Add or update a webhook URL from this link to a WhatsApp Business Account. Once you’ve done this, you should be able to receive inbound messages.

Test

Send a WhatsApp message to the Plivo number you specified using WhatsApp application.