TWhatsApp

Source: source/classes/twhatsapp.prg

Hierarchy: TWhatsApp (standalone class, no inheritance)

TWhatsApp is a WhatsApp Cloud API client that communicates with Meta's Business Platform via HTTPS requests using the cURL library. It requires a Meta Business Account, a registered phone number ID, and a permanent system access token generated from the Meta App Dashboard. All message types are sent as JSON payloads through the Graph API.

New to the WhatsApp Cloud API? Follow the illustrated step-by-step setup guide to create the Meta app, get your access token and phone number ID, and send your first message in about 15 minutes.

Key DATA Members

DATATypeDefaultDescription
cTokenCharacterBearer access token for API authentication
cPhoneIdCharacterSender phone number ID (Meta numeric ID, not the phone number)
cVersionCharacter"v24.0"Graph API version string
cBaseUrlCharacter"https://graph.facebook.com"Base URL for all API calls
cResponseCharacterRaw JSON response from the last API call
nErrorNumeric0cURL error code from the last operation
nHttpCodeNumeric0HTTP status code from the last response

Methods

MethodDescription
New( cToken, cPhoneId, cVersion )Constructor. Initializes cURL handle and stores credentials. Optionally sets API version.
End()Clean up the cURL handle. Call when done with the object.
SendText( cTo, cMsg, lPreviewUrl )Send a plain text message. lPreviewUrl enables link preview generation.
SendTemplate( cTo, cName, cLang, aBodyParams, hHeader, aButtons )Send a pre-approved message template. All parameters are optional: aBodyParams is an array of body values, hHeader is { "type" => "text"|"image"|"document"|"video", ... } (text header takes "text"; media headers take "link" or "id", document also "filename") and aButtons is { { "sub_type" => "quick_reply", "payload" => c }, { "sub_type" => "url", "text" => cDynamicSuffix } }. Phone number buttons need no parameters.
SendImage( cTo, cLinkOrId, cCaption )Send an image by URL or previously uploaded media ID.
SendDocument( cTo, cLinkOrId, cFilename, cCaption )Send a document by URL or media ID with optional filename and caption.
SendAudio( cTo, cLinkOrId )Send an audio file by URL or media ID.
SendVideo( cTo, cLinkOrId, cCaption )Send a video by URL or media ID with optional caption.
SendLocation( cTo, nLat, nLong, cName, cAddress )Send a location pin with latitude, longitude, and optional name/address.
SendButtons( cTo, cBody, aButtons, cHeader, cFooter )Send an interactive message with up to 3 reply buttons: aButtons is { { "id" => cId, "title" => cLabel }, ... } (labels max 20 characters). cHeader and cFooter are optional text.
SendList( cTo, cBody, cButton, aRows, cHeader, cFooter )Send an interactive list message: cButton is the label that opens the list and aRows is { { "id" => cId, "title" => cTitle, "description" => cDesc }, ... } (max 10 rows). cHeader and cFooter are optional text.
SendReaction( cTo, cMsgId, cEmoji )React with an emoji to a received message. An empty cEmoji removes the reaction.
SendContact( cTo, aContacts )Send one or more contact cards. Each contact is { "name" => cFullName, "first" => c, "last" => c, "phones" => { cPhone, ... }, "emails" => { cEmail, ... }, "company" => c, "title" => c }; only "name" is required.
MarkAsRead( cMsgId, lTyping )Mark a received message as read (blue checks). With lTyping = .T. it also shows the typing indicator. cMsgId is the id of a message received via webhook.
UploadMedia( cFileName, cMimeType )Upload a media file to WhatsApp servers. Returns the media ID string, or nil on failure.
DownloadMedia( cMediaId, cTargetFile )Download a media file from WhatsApp servers and save to disk. Returns .T. on success.
GetMessageId()Extract the message ID from the last API response. Returns empty string on failure.
GetError()Extract the error message from the last API response. Returns empty string if no error.
GetErrorCode()Numeric Meta error code from the last API response, 0 if none.
GetFbTraceId()Meta fbtrace_id from the last error response, useful when reporting problems to Meta support.

Example: Send Text Message

#include "FiveWin.ch"

function Main()

   local oWA := TWhatsApp():New( "EAAx...token", "123456789", "v24.0" )
   local cResp, cMsgId

   // Send a simple text message
   cResp := oWA:SendText( "5215512345678", "Hello from FiveWin!" )

   cMsgId := oWA:GetMessageId()
   if ! Empty( cMsgId )
      MsgInfo( "Message sent. ID: " + cMsgId )
   else
      MsgInfo( "Error: " + oWA:GetError() )
   endif

   oWA:End()

return nil

Example: Template Message

#include "FiveWin.ch"

function SendTemplate()

   local oWA  := TWhatsApp():New( "EAAx...token", "123456789" )
   local aParams := { "John", "FWH 26.05", "Monday" }

   // "welcome_message" must be pre-approved by Meta
   oWA:SendTemplate( "5215512345678", "welcome_message", "en_US", aParams )
   oWA:End()

return nil

Example: Template with Header and Buttons

#include "FiveWin.ch"

function SendTemplateFull()

   local oWA := TWhatsApp():New( "EAAx...token", "123456789" )

   // "order_update" must exist and be approved in the Meta app:
   // body with 2 parameters, image header, quick reply + dynamic URL buttons
   oWA:SendTemplate( "5215512345678", "order_update", "es_ES", ;
      { "Ana", "1234" }, ;
      { "type" => "image", "link" => "https://www.fivetechsoft.com/images/fivewin_logo.png" }, ;
      { { "sub_type" => "quick_reply", "payload" => "track_1234" }, ;
        { "sub_type" => "url", "text" => "order/1234" } } )
   oWA:End()

return nil

Example: Interactive Buttons

#include "FiveWin.ch"

function SendButtons()

   local oWA := TWhatsApp():New( "EAAx...token", "123456789" )

   oWA:SendButtons( "5215512345678", "Do you confirm the appointment tomorrow at 10:00?", ;
      { { "id" => "confirm_yes", "title" => "Confirm" }, ;
        { "id" => "confirm_no",  "title" => "Cancel" } }, ;
      "Appointment", "Reply with one tap" )
   oWA:End()

return nil

Notes

See Also