B4J Tutorial WABA (WhatsApp Business API)

I want to start with a clarification, META offers three WhatsApp services: WhatsApp, WhatsApp Business, WhatsApp Business API. The first two are applications, the first of which is intended for a common user, the second for a user who trades and therefore with marketing and trade options even if it is possible to use it for common use. Finally I will talk about the last service (from now on I will call it WABA) which is not accompanied by an application but are APIs and microservices.

Basically, by registering a number that is not connected with the first two services, messages destined for this number will be sent with a POST call to one of your 'webhook', i.e. a PHP link (or similar) that will receive a JSON with the message and all the characteristics of the message (images, files, status, etc.). From this you can populate a DB with received messages. One of your Apps (desktop, mobile, etc.) can perform functions by scanning messages, such as replying, etc.

Who is it for?
Typically management programs, ERP, CRM use this method to populate their DBs with customer orders, reports, communications, marketing. Or with micro devices (arduino, esp32,...) you can control the devices, burglar alarms, gates and so on remotely and with WhatsApp. You can create catalogs, menus and reply buttons. There are too many ideas on how to use them to list them all but I think the concept is clear

The advantage?
You don't have to have your clients install another application because they already have WhatsApp. You can create a BOT, you can avoid reading and examining all the text, you can automate communications and registrations.

In the next posts we will talk about the technical part
 
Last edited:

Star-Dust

Expert
Licensed User
Longtime User
1️⃣ Registration and Preparation

1.1 Sign up for Meta for Developers
- Go to: https://developers.facebook.com/
- Log in with your Facebook/Meta account.
- Complete the developer registration.

1.2 Business Manager
- Go to: https://business.facebook.com/
- Create or select your Business Manager and enter full business details.
- Complete business verification if required.

2️⃣ Create the App
- Go to the app dashboard: https://developers.facebook.com/apps
- Click Create App, select type Business, enter name and contact email.
- Associate your Business Manager and create the app.

3️⃣ Essential App Settings

3.1 App Icon
- Go to App Settings > Basic, upload an icon of 512×512 px (PNG).

3.2 Privacy Policy and Terms
- Enter publicly accessible URLs for Privacy Policy and Terms of Service.
- These are required to switch the app to Live mode.

4️⃣ Add WhatsApp APP Product
- In the app dashboard: Add Products → WhatsApp → Set Up
- Follow the quickstart to configure WhatsApp Cloud API.

5️⃣ WhatsApp Number Setup
- Add a valid phone number for the API (not already active on WhatsApp).
- Verify the number via SMS or call.
- You will receive WABA ID, Phone Number ID, and test token.

6️⃣ System User and Permanent Token
- Go to Business Settings → System Users, create an Admin/Developer user.
- Assign permissions to the app and generate a permanent access token with permissions:
  • whatsapp_business_management
  • whatsapp_business_messaging
  • business_management

7️⃣ Switch App to Live Mode
- Make sure icon, Privacy Policy URL, and Terms of Service URL are set.
- Activate App Live in App Settings > Basic.
- Associate valid domains if required.

Useful URLs

 

Star-Dust

Expert
Licensed User
Longtime User
WEBHOOK
This is a sample code to insert received messages with webhooks in JSON format into the DB. I split the text-only messages with the mixed ones.

The DB fields are as follows:
SQL:
CREATE TABLE nome_tabella (
    id INT(11) NOT NULL AUTO_INCREMENT,
    wa_message_id VARCHAR(100) DEFAULT NULL,
    phone VARCHAR(20) DEFAULT NULL,
    message TEXT DEFAULT NULL,
    timestamp DATETIME DEFAULT NULL,
    raw_json JSON DEFAULT NULL,
    PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

1768996084898.png


PHP CODE
PHP:
<?php

// Connect DB
$mysqli = new mysqli("host","my_user","my_password","my_db");
if ($mysqli->connect_error) {
    http_response_code(500);
    exit;
}

// Verify webhook (GET)
$verify_token = 'your_token_chosen';

if ($_SERVER['REQUEST_METHOD'] === 'GET') {
    if (
        $_GET['hub_mode'] === 'subscribe' &&
        $_GET['hub_verify_token'] === $verify_token
    ) {
        echo $_GET['hub_challenge'];
        exit;
    }
    http_response_code(403);
    exit;
}

// Receved message (POST)
$input = file_get_contents('php://input');
$data = json_decode($input, true);

// sicurity log
file_put_contents('log.txt', $input . PHP_EOL, FILE_APPEND);

// messagge verify
if (
    isset($data['entry'][0]['changes'][0]['value']['messages'][0])
) {
    $msg = $data['entry'][0]['changes'][0]['value']['messages'][0];

    // only text message
    if ($msg['type'] === 'text') {

        $phone = $msg['from'];
        $message = $msg['text']['body'];
        $wa_message_id = $msg['id'];
        $timestamp = date('Y-m-d H:i:s', $msg['timestamp']);

        // Insert DB
        $stmt = $mysqli->prepare("
            INSERT INTO whatsapp_messages
            (wa_message_id, phone, message, timestamp, raw_json)
            VALUES (?, ?, ?, ?, ?)
        ");

        $stmt->bind_param(
            "sssss",
            $wa_message_id,
            $phone,
            $message,
            $timestamp,
            $input
        );

        $stmt->execute();
        $stmt->close();
    } else {
        // mixed message
        $phone = $msg['from'];
        $message = $msg['text']['body'] ?? '';
        $wa_message_id = $msg['id'];
        $timestamp = date('Y-m-d H:i:s', $msg['timestamp']);

        // Insert DB
        $stmt = $mysqli->prepare("
            INSERT INTO whatsapp_messages
            (wa_message_id, phone, message, timestamp, raw_json)
            VALUES (?, ?, ?, ?, ?)
        ");

        $stmt->bind_param(
            "sssss",
            $wa_message_id,
            $phone,
            $message,
            $timestamp,
            $input
        );

        $stmt->execute();
        $stmt->close();
    }
}

http_response_code(200);

OBVIOUSLY THIS IS JUST AN EXAMPLE.
you can design the webHook code and the DB structure as you think is best
 
Last edited:

Star-Dust

Expert
Licensed User
Longtime User
B4X code
Reading messages from the DB and Grid population

B4X:
Public Sub ReadMessage
    Dim nrow As Int = 0
    Wait For (php.ReadQuery("SELECT * FROM `whatsapp_messages`",Array As String("id","wa_message_id","phone","message","timestamp","raw_json"))) Complete (Result As List)

    FlexGridMessage.ClearRows
    For Each row As Map In Result
        Log(row.Get("raw_json"))
        Dim DB_ID As String = row.Get("id")
        Dim msg_id As String = row.Get("wa_message_id")
        Dim timestamp As String = row.Get("timestamp")
        Dim msg As Map = ReadMessageMap(row.Get("raw_json"))
        Dim dt As Long = DateTime.Now-msg.Get("timestamp")*1000
        Dim image As Map = msg.Get("image")
        Dim tpe As String = msg.Get("type")
        Dim mime_type As String = msg.Get("mime_type") 'ignore
        Dim name As String = contatto(row.Get("raw_json")).Get("name")
        Dim text As String = IIf(tpe="text",row.Get("message"),msg.Get(tpe).As(Map).GetDefault("caption",""))
        ' tpe: text, document, image, video [documet -> pdf, mp3 , ecc..]

        ' SD FLEX GRID
        FlexGridMessage.AddRow(Array(Null,DB_ID,msg_id,name,text,timestamp,row.Get("raw_json")),True)

        If image.IsInitialized Then LoadImage(nrow,image.Get("id")) ' If the message contains an image, upload it
        nrow=nrow+1
    Next
End Sub

Private Sub LoadImage(row As Int, ID As String)
    Dim j As HttpJob
 
    j.Initialize("", Me)
    j.Download($"https://graph.facebook.com/v24.0/${ID}"$)
    J.GetRequest.SetHeader("Authorization", $"Bearer ${Tk}"$)
    Wait For (j) JobDone(j As HttpJob)
    If j.Success Then
        Dim M As Map = j.GetString.As(JSON).ToMap
        Dim url As String = M.Get("url")
            
        Dim j2 As HttpJob
        j2.Initialize("", Me)
        j2.Download(url)
        j2.GetRequest.SetHeader("Authorization", $"Bearer ${Tk}"$)
        Wait For (j2) JobDone(j2 As HttpJob)
        If j2.Success Then
            Dim img As B4XBitmap = j2.GetBitmap
            FlexGridMessage.SetCellValue(row,0,img)
        End If
        j.Release
    End If
    j.Release
End Sub

TK contains the USER TOKEN. Go to the users page and generate a definitive TOKEN
Make sure the resources and the App are connected to the user
1768997681552.png
 
Last edited:

Star-Dust

Expert
Licensed User
Longtime User
B4X func code
Mark as read, Send text messages, images, videos, audio and PDF documents

B4X:
private Sub SendWhatsAppText(Phone As String, Message As String) 'ignore
    Dim Job As HttpJob
    Job.Initialize("WA", Me)
    Phone=Phone.Replace("+","")
   
    Dim json As String = $"{"messaging_product": "whatsapp","to": "${Phone}","type": "text","text": {"body": "${Message}"}}"$

    Job.PostString($"https://graph.facebook.com/v24.0/${PhoneNumberID}/messages"$, json)
    Job.GetRequest.SetHeader("Authorization", $"Bearer ${Tk}"$)
    Job.GetRequest.SetContentType("application/json")
End Sub

private Sub SendWhatsAppImage(Phone As String, ImageUrl As String, Caption As String) 'ignore
   ' top secret
End Sub

private Sub SendWhatsAppDocument(Phone As String, FileUrl As String, FileName As String) 'ignore
   ' top secret
End Sub

private Sub SendWhatsAppAsRead(MessageID As String) 'ignore
    Dim Job As HttpJob
    Job.Initialize("WA", Me)
   
    Dim json As String = $"{"messaging_product": "whatsapp","status":"read","message_id":"${MessageID}"}"$

    Job.PostString($"https://graph.facebook.com/v24.0/${PhoneNumberID}/messages"$, json)
    Job.GetRequest.SetHeader("Authorization", $"Bearer ${Tk}"$)
    Job.GetRequest.SetContentType("application/json")
End Sub


To find out the PhoneNumberID By going to the Application panel by selecting the use cases, go to API CONFIGURATION and after entering the number and verifying, you can get the ID
1768998526640.png
 
Last edited:

Star-Dust

Expert
Licensed User
Longtime User
How to create a Menu with Buttons or a product catalog from code? All the other more complex functions? Do I need a phone number for each service? Can I create a survey?
Maybe this in the future, or some research on the web and you will find the answer.

WABA - FREE OR PAID
If a user writes to you, you can send one or more free messages within 24 hours, otherwise they will cost you. If you invite a message on your own initiative, it will have a cost. If you prepare a catalog on meta from the panel this will have a cost.
So everything that is marketing will have a cost.

1769011388968.png
 
Last edited:
Top