sgcSocial in five minutes

Two messaging clients ship in this package: WhatsApp Business Cloud and Telegram on the official TDLib. WhatsApp is the shorter path, because it is pure HTTPS with nothing to deploy, so this page sends a WhatsApp text message first and then tells you what Telegram additionally needs.

WhatsApp Business Cloud API
Telegram on the official TDLib
WhatsApp from Professional, Telegram from Standard

What the first message needs

One component, two values from your Meta app, and one method call that returns the API response as a string.

Component

TsgcWhatsApp_Client on the SGC Social palette page, declared in sgcLibs.pas as a published wrapper around TsgcWhatsApp_Client_Base.

The two values you need

WhatsAppOptions.PhoneNumberId and WhatsAppOptions.Token, both taken from your Meta developer app. Nothing else is required to send.

The call

SendMessageText(aTo, aMessage) returns a string, the raw response body from the Meta Graph API. Log it and you can see immediately whether the send was accepted.

Telegram is different

TsgcTDLib_Telegram wraps the official TDLib, so it needs the native library beside your executable. That is the one extra step, and the table below names the file per platform.

Requirements and editions

The edition column is the define that gates each client, with the line it sits on in Source/sgcVer.inc.

What Value
IDE Delphi 7 through RAD Studio 13, and C++Builder 2007 through 13.
Uses clause sgcLibs for the palette classes. The demo adds sgcLib_WhatsApp_Client for the options and message types.
WhatsApp edition SGC_WHATSAPP is defined on line 728, the first line inside the {$IFDEF SGC_EDT_PRO} block that runs from line 727 to line 758. So Professional and up.
Telegram edition SGC_TELEGRAM is defined on lines 677, 680, 683, 687, 691 and 694, all inside the {$IFDEF SGC_EDT_STD} block that runs from line 675 to line 724. Six lines because each is guarded by a platform. So Standard and up, on the platforms listed there.
Edition, standalone package The sgcSocial product defines SGC_PACK_SOCIAL on line 860, and its own block on lines 968 to 971 defines SGC_TELEGRAM on line 969 and SGC_WHATSAPP on line 970. Same two clients, without the rest of the library.
WhatsApp platforms No native dependency and no platform guard. It is HTTPS to the Meta Graph API, so every target that has a TLS back end works.
Telegram platforms Needs the TDLib JSON library beside the binary: tdjson.dll on Windows, libtdjson.dylib on macOS 64 bit, libtdjson.so on Linux 64 bit and on Lazarus Linux, libtdjsonandroid.so on Android. On iOS 64 the library is linked statically as libtdjson.a instead of loaded at runtime.

A WhatsApp Business Cloud test number, a permanent token and a phone number id all come from the Meta developer console. Nothing in the component creates them for you.

Install and find the palette page

sgcSocial ships inside the sgcWebSockets installer and also as its own package. The install is the same shape either way.

1. Unzip

Unzip the download to a folder, called {$DIR} below.

2. Library path

Tools, Options, Library. Add {$DIR}\source and the lib folder for your IDE, for example {$DIR}\libD13\$(Platform).

3. Build the packages

Open the package group for your IDE version under {$DIR}\Packages\. Compile the runtime .dpk first, then install the design-time dcl one.

4. Check the palette

A page called SGC Social appears. On a Standard build it holds TsgcTDLib_Telegram. On Professional and up it also holds TsgcWhatsApp_Client.

5. For Telegram only, ship TDLib

Copy the TDLib JSON library for your platform beside the executable. The shipped Telegram demo has tdjson.dll together with libcrypto-3.dll, libssl-3.dll and zlib1.dll in its folder, which is the set Windows needs.

Send a WhatsApp message, in about ten lines

Set the phone number id and the token, call SendMessageText, and read the response the Graph API sent back.

FWhatsApp.pas
uses
  Classes, SysUtils,
  // sgc
  sgcLibs, sgcLib_WhatsApp_Client;

procedure TFRMWhatsApp.btnSendMessageClick(Sender: TObject);
begin
  whatsapp.WhatsAppOptions.PhoneNumberId := '1234567890';
  whatsapp.WhatsAppOptions.Token := GetToken;

  // returns the raw Graph API response body, so log it:
  // a rejected send comes back in there, not as an exception
  DoLog('Message Sent: ' + whatsapp.SendMessageText(
    '+34600000000', 'Hello from Delphi'));
end;

That is the whole send path. Nothing else has to be configured, and no server has to be running. SendMessageImage, SendMessageDocument, SendMessageLocation, SendMessageContact, SendMessageInteractiveButtons and SendMessageTemplate follow the same shape.

FWhatsApp.pas
procedure TFRMWhatsApp.FormCreate(Sender: TObject);
begin
  // ... using neAsynchronous to update the memo control
  // ... in production set the value neNoSync
  whatsapp.NotifyEvents := neAsynchronous;

  // the component hosts the Meta webhook itself
  whatsapp.StartServer;
end;

procedure TFRMWhatsApp.whatsappMessageReceived(Sender: TObject;
  const aMessage: TsgcWhatsApp_Receive_Message; var aMarkAsRead: Boolean);
begin
  if aMessage.Messages.Count > 0 then
  begin
    DoLog(aMessage.Messages._Message[0].Text.Body);
    aMarkAsRead := True;
  end;
end;

Receiving is optional. StopServer shuts the listener down again, and OnBeforeSubscribe is where you accept or reject Meta's verification request, through its var Accept: Boolean parameter.

uTelegram.pas
uses
  Classes, SysUtils,
  // sgc
  sgcLibs, sgcLib_Telegram;

procedure TFRMSGCTelegram.btnStartClick(Sender: TObject);
begin
  // The one thing no other component in the library needs:
  // TDLib is a native library, so say where it is when it is
  // not already beside the executable.
  SetTDJsonPath(ExtractFilePath(ParamStr(0)));

  sgcTelegram.Telegram.API.ApiId := GetApiId;
  sgcTelegram.Telegram.API.ApiHash := GetApiHash;
  sgcTelegram.Telegram.PhoneNumber := '+34600000000';

  sgcTelegram.Active := True;
end;

To sign in as a bot instead, leave PhoneNumber empty and set Telegram.BotToken. Authorisation is event driven from there: OnAuthorizationStatus, OnAuthenticationCode and OnAuthenticationPassword ask you for what TDLib needs next.

The first two tabs are the shipped demo Demos\50.Other\05.WhatsApp\FWhatsApp.pas, with the form controls replaced by literals. That demo's send button actually calls SendMessageLocation; the text call shown here is the same file's SendMessageText path. The Telegram tab shows the one line that is different from every other component in the library.

Check the message was accepted

Two levels of proof: what the send call returns, and what the webhook tells you afterwards.

The return value

SendMessageText returns the Graph API response body as a string. Log it. An error from Meta arrives in that body rather than as an exception, so a send that appears to do nothing usually has its explanation right there.

OnMessageSent

Reports what happened to a message afterwards, through a status value that moves from unknown to sent, delivered and read. It needs the webhook server running, because the status arrives as an inbound callback.

OnMessageReceived

procedure(Sender: TObject; const aMessage: TsgcWhatsApp_Receive_Message; var aMarkAsRead: Boolean). Set aMarkAsRead to acknowledge the message, which is what puts the blue ticks on the sender's screen.

Telegram

OnConnectionStatus and OnAuthorizationStatus are the two to watch. TDLib signs in over several steps, so the status events are the only reliable way to know where you are in that sequence.

What usually goes wrong the first time

Six problems account for nearly every failed first send.

The component is not on the palette

TsgcWhatsApp_Client is compiled only when SGC_WHATSAPP is defined, which happens on line 728 inside the Professional block. On a Standard build you get Telegram and not WhatsApp.

The send returns an error about a template

WhatsApp only allows a free-form text message inside the customer service window that opens when the user messages you first. Outside it you must send an approved template, which is SendMessageTemplate, not SendMessageText.

Nothing arrives and no error is raised

Read the return value. SendMessageText returns the raw Graph API response as a string, and the demo logs it directly. An error from Meta comes back in that body.

The token expires after a day

The temporary token in the Meta console is short lived. Generate a permanent token for a system user before you leave the sample behind.

Telegram raises a library error at startup

TDLib was not found. The component loads it at runtime with dlopen or LoadLibrary and raises when that fails. Put the file next to your executable, or set the search path with SetTDJsonPath.

Events fire on the wrong thread

The demo sets NotifyEvents := neAsynchronous so it can touch the form directly, and its own comment says to use neNoSync in production and marshal to the UI thread yourself.

Beyond the first message

Four directions the work usually takes, all inside the same package.

Richer WhatsApp messages

Images, documents, locations, contacts, interactive button messages and approved templates each have their own send method on the same component.

WhatsApp reference

Receive, not just send

The component can host the webhook endpoint itself. StartServer brings it up, OnBeforeSubscribe accepts or rejects the verification handshake, and OnMessageReceived hands you each inbound message.

WhatsApp reference

Full Telegram apps, not just bots

TDLib is the same library the official Telegram clients use, so the component reaches user accounts, chats, media and sponsored messages rather than only the bot API.

Telegram reference

Delivery status

OnMessageSent reports the progress of a message you sent, through the states the API defines: unknown, sent, delivered and read.

WhatsApp reference

Reference, demos and documentation

The reference pages document every method and event. Demo projects ship inside the download, under Demos\50.Other.

Reference, WhatsApp client Every send method, option and event on TsgcWhatsApp_Client.
Reference, Telegram client Authorisation, chats, messages and media on TsgcTDLib_Telegram.
TsgcWhatsApp_Client component page Every send method and event, with the Telegram client linked from it.
Download the trial The same installer as production, time limited.
Online help The generated reference, always in step with the current release.
User manual (PDF) The full manual covering every component in the library.

Related reading: the WhatsApp component, sending local files over WhatsApp, the Telegram client and Telegram behind a proxy. Every product has its own quick start, listed on the getting started page.

sgcSocial quick start questions

TsgcWhatsApp_Client, on the SGC Social palette page. It is declared in sgcLibs.pas as a published wrapper around TsgcWhatsApp_Client_Base, which is declared in sgcLib_WhatsApp_Client.pas and carries the send methods. Set WhatsAppOptions.PhoneNumberId and WhatsAppOptions.Token, then call SendMessageText.
WhatsApp is gated by SGC_WHATSAPP, defined on line 728 of sgcVer.inc, the first line of the SGC_EDT_PRO block that runs from line 727 to line 758. That is Professional and above. Telegram is gated by SGC_TELEGRAM, defined six times on lines 677 to 694 inside the SGC_EDT_STD block, lines 675 to 724, once per platform. So Telegram starts one tier lower. The standalone sgcSocial package turns both on through SGC_PACK_SOCIAL, line 860, whose block on lines 968 to 971 defines them without a platform guard.
A string, which is the raw response body from the Meta Graph API. Its full signature is function SendMessageText(const aTo, aMessage: string; aPhoneNumberId: string = ''; const aOptions: TsgcWhatsApp_Message_Options = nil): string. The shipped demo logs the return value directly, and that is the fastest way to see an error from Meta, because a rejected send comes back in the body rather than as an exception.
The component can be the server. Call StartServer and it listens for the Meta webhook itself. OnBeforeSubscribe lets you accept or reject the verification request, and OnMessageReceived gives you each inbound message plus a var aMarkAsRead flag you can set to acknowledge it. StopServer shuts it down. Sending needs none of that.
The native TDLib JSON library beside your executable. The component loads it at runtime and names it per platform: tdjson.dll on Windows, libtdjson.dylib on macOS 64 bit, libtdjson.so on Linux 64 bit and on Lazarus Linux, and libtdjsonandroid.so on Android. iOS 64 is the exception, where the library is linked statically as libtdjson.a. If it is missing, the component raises on first use. SetTDJsonPath points it at a different folder.
Yes, each has its own method on the same component: SendMessageImage, SendMessageDocument, SendMessageLocation, SendMessageContact, SendMessageInteractiveButtons and SendMessageTemplate, which is overloaded. MarkMessageRead marks an inbound message as read.
Because of the threading mode. The shipped demo sets NotifyEvents := neAsynchronous so its handlers can touch VCL controls, and its own comment says to use neNoSync in production. With neNoSync the event fires on the worker thread, which is faster and correct for a service, and it becomes your job to marshal anything that touches the UI.
Yes. It is a standalone package with the sgcWebSockets Core runtime included, and it is also part of sgcWebSockets from Professional up for WhatsApp and Standard up for Telegram. In the source the standalone route is SGC_PACK_SOCIAL on line 860 of sgcVer.inc, whose block on lines 968 to 971 defines both clients.
Best value: All-AccessEvery eSeGeCe product, Premium Support included, from €1,059/year.
See All-Access pricing

Ready to message your customers from Delphi?

Download the trial and send your first WhatsApp message today.