sgcSocial 五分钟上手

这个包中附带两个消息客户端:WhatsApp Business Cloud,以及基于官方 TDLib 的 Telegram。WhatsApp 是更短的路径,因为它是纯 HTTPS,无需部署任何东西,所以本页先发送一条 WhatsApp 文本消息,然后告诉您 Telegram 还需要什么。

WhatsApp Business Cloud API
基于官方 TDLib 的 Telegram
WhatsApp 从 Professional 版起,Telegram 从 Standard 版起

第一条消息所需的内容

一个组件,来自您的 Meta 应用的两个值,以及一次返回字符串形式 API 响应的方法调用。

组件

SGC Social 组件面板页上的 TsgcWhatsApp_Client,声明在 sgcLibs.pas 中,是 TsgcWhatsApp_Client_Base 的已发布封装。

您需要的两个值

WhatsAppOptions.PhoneNumberId 和 WhatsAppOptions.Token,两者都取自您的 Meta 开发者应用。发送时不需要其他任何东西。

调用

SendMessageText(aTo, aMessage) 返回一个 string,即来自 Meta Graph API 的原始响应正文。把它记录下来,您就能立即看出发送是否被接受。

Telegram 有所不同

TsgcTDLib_Telegram 封装了官方的 TDLib,因此需要把原生库放在可执行文件旁边。这是唯一多出来的一步,下表按平台列出了文件名。

要求与版本

版本列给出的是控制各个客户端的定义,以及它在 Source/sgcVer.inc 中所在的行号。

项目 值
IDE Delphi 7 到 RAD Studio 13,以及 C++Builder 2007 到 13。
uses 子句 组件面板类使用 sgcLibs。演示还添加了 sgcLib_WhatsApp_Client,用于选项和消息类型。
WhatsApp 版本 SGC_WHATSAPP 定义在第 728 行,即从第 727 行延伸到第 758 行的 {$IFDEF SGC_EDT_PRO} 块内的第一行。因此是 Professional 及以上版本。
Telegram 版本 SGC_TELEGRAM 定义在第 677、680、683、687、691 和 694 行,都位于从第 675 行延伸到第 724 行的 {$IFDEF SGC_EDT_STD} 块内。共六行,因为每一行都受某个平台的保护。因此是 Standard 及以上版本,适用于那里列出的平台。
版本,独立包 sgcSocial 产品在第 860 行定义 SGC_PACK_SOCIAL,其自己的第 968 行到第 971 行的块在第 969 行定义 SGC_TELEGRAM,在第 970 行定义 SGC_WHATSAPP。同样的两个客户端,不含库的其余部分。
WhatsApp 平台 没有原生依赖,也没有平台保护。它是通往 Meta Graph API 的 HTTPS,因此任何有 TLS 后端的目标都可以工作。
Telegram 平台 需要把 TDLib JSON 库放在二进制文件旁边:Windows 上是 tdjson.dll,64 位 macOS 上是 libtdjson.dylib,64 位 Linux 和 Lazarus Linux 上是 libtdjson.so,Android 上是 libtdjsonandroid.so。在 iOS 64 上,该库以 libtdjson.a 的形式静态链接,而不是在运行时加载。

WhatsApp Business Cloud 测试号码、永久令牌和电话号码 ID 都来自 Meta 开发者控制台。组件不会替您创建它们。

安装并找到组件面板页

sgcSocial 包含在 sgcWebSockets 安装程序中,也作为独立的包提供。无论哪种方式,安装流程都相同。

1. 解压

将下载文件解压到一个文件夹,下文称之为 {$DIR}。

2. 库路径

依次选择 Tools、Options、Library。添加 {$DIR}\source 以及与您的 IDE 对应的 lib 文件夹,例如 {$DIR}\libD13\$(Platform)。

3. 构建包

在 {$DIR}\Packages\ 下,打开与您的 IDE 版本对应的包组。先编译运行时 .dpk,再安装设计时 dcl 包。

4. 检查组件面板

会出现一个名为 SGC Social 的页面。在 Standard 构建中,它包含 TsgcTDLib_Telegram。在 Professional 及以上版本中,还包含 TsgcWhatsApp_Client。

5. 仅 Telegram 需要,部署 TDLib

将适用于您平台的 TDLib JSON 库复制到可执行文件旁边。随包附带的 Telegram 演示在其文件夹中包含 tdjson.dll,以及 libcrypto-3.dll、libssl-3.dll 和 zlib1.dll,这是 Windows 所需的整套文件。

发送一条 WhatsApp 消息,大约十行代码

设置电话号码 ID 和令牌,调用 SendMessageText,并读取 Graph API 返回的响应。

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;

这就是完整的发送路径。无需配置其他任何东西,也不需要运行任何服务器。SendMessageImage、SendMessageDocument、SendMessageLocation、SendMessageContact、SendMessageInteractiveButtons 和 SendMessageTemplate 的形式都与此相同。

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;

接收是可选的。StopServer 会再次关闭监听器,而 OnBeforeSubscribe 是您通过其 var Accept: Boolean 参数接受或拒绝 Meta 验证请求的地方。

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;

如果要以机器人身份登录,请将 PhoneNumber 留空,并设置 Telegram.BotToken。此后授权由事件驱动:OnAuthorizationStatus、OnAuthenticationCode 和 OnAuthenticationPassword 会向您索取 TDLib 接下来所需的内容。

前两个选项卡来自随包附带的演示 Demos\50.Other\05.WhatsApp\FWhatsApp.pas,其中的窗体控件已替换为字面量。该演示的发送按钮实际调用的是 SendMessageLocation;这里展示的文本调用是同一个文件中的 SendMessageText 路径。Telegram 选项卡展示了与库中所有其他组件不同的那一行。

检查消息是否已被接受

两个层次的证明:发送调用返回什么,以及之后 Webhook 告诉您什么。

返回值

SendMessageText 以 string 形式返回 Graph API 的响应正文。把它记录下来。来自 Meta 的错误会出现在该正文中,而不是以异常的形式出现,因此看起来什么都没做的发送,通常在那里就能找到原因。

OnMessageSent

通过一个从未知变为已发送、已送达和已读的状态值,报告消息之后的情况。它需要 Webhook 服务器处于运行状态,因为状态是作为入站回调到达的。

OnMessageReceived

procedure(Sender: TObject; const aMessage: TsgcWhatsApp_Receive_Message; var aMarkAsRead: Boolean)。设置 aMarkAsRead 以确认该消息,这样发送者的屏幕上就会出现蓝色对勾。

Telegram

OnConnectionStatus 和 OnAuthorizationStatus 是需要关注的两个事件。TDLib 通过多个步骤登录,因此状态事件是了解您处于该序列中哪一步的唯一可靠方法。

第一次通常会出什么问题

六个问题几乎涵盖了所有失败的第一次发送。

组件面板上没有该组件

TsgcWhatsApp_Client 只有在定义了 SGC_WHATSAPP 时才会编译,这发生在 Professional 块内的第 728 行。在 Standard 构建中,您会得到 Telegram,而没有 WhatsApp。

发送返回一个与模板有关的错误

WhatsApp 只允许在客户服务窗口内发送自由格式的文本消息,该窗口在用户先给您发消息时才会打开。在窗口之外,您必须发送已批准的模板,即 SendMessageTemplate,而不是 SendMessageText。

什么都没有到达,也没有抛出错误

请读取返回值。SendMessageText 以字符串形式返回原始的 Graph API 响应,演示会直接记录它。来自 Meta 的错误会出现在该正文中。

令牌一天后过期

Meta 控制台中的临时令牌有效期很短。在您告别示例之前,请为系统用户生成一个永久令牌。

Telegram 在启动时抛出库错误

未找到 TDLib。组件在运行时通过 dlopen 或 LoadLibrary 加载它,失败时就会抛出异常。请把该文件放在可执行文件旁边,或使用 SetTDJsonPath 设置搜索路径。

事件在错误的线程上触发

演示设置了 NotifyEvents := neAsynchronous,以便可以直接操作窗体,它自己的注释也说明在生产环境中应使用 neNoSync,并自行切换到 UI 线程。

第一条消息之后

工作通常会延伸的四个方向,都在同一个包内。

更丰富的 WhatsApp 消息

图片、文档、位置、联系人、交互式按钮消息和已批准的模板,在同一个组件上各有自己的发送方法。

WhatsApp 参考

不仅发送,还要接收

组件可以自己托管 Webhook 端点。StartServer 启动它,OnBeforeSubscribe 接受或拒绝验证握手,OnMessageReceived 把每条入站消息交给您。

WhatsApp 参考

完整的 Telegram 应用,而不仅仅是机器人

TDLib 与官方 Telegram 客户端使用的是同一个库,因此组件可以访问用户账户、聊天、媒体和赞助消息,而不仅仅是机器人 API。

Telegram 参考

送达状态

OnMessageSent 通过 API 定义的状态报告您所发送消息的进展:未知、已发送、已送达和已读。

WhatsApp 参考

参考、演示和文档

参考页面记录了每个方法和事件。演示项目包含在下载包内,位于 Demos\50.Other 下。

参考:WhatsApp 客户端 TsgcWhatsApp_Client 上的每个发送方法、选项和事件。
参考:Telegram 客户端 TsgcTDLib_Telegram 上的授权、聊天、消息和媒体。
TsgcWhatsApp_Client 组件页面 每个发送方法和事件,Telegram 客户端也可从中链接访问。
下载试用版 与正式版相同的安装程序,有时间限制。
在线帮助 自动生成的参考,始终与当前版本保持同步。
用户手册(PDF) 涵盖库中每个组件的完整手册。

相关阅读:WhatsApp 组件、通过 WhatsApp 发送本地文件、Telegram 客户端和代理后面的 Telegram。每个产品都有自己的快速入门,列在入门页面上。

sgcSocial 快速入门常见问题

SGC Social 组件面板页上的 TsgcWhatsApp_Client。它在 sgcLibs.pas 中声明,是 TsgcWhatsApp_Client_Base 的已发布封装,后者声明在 sgcLib_WhatsApp_Client.pas 中,并携带发送方法。设置 WhatsAppOptions.PhoneNumberId 和 WhatsAppOptions.Token,然后调用 SendMessageText。
WhatsApp 由 SGC_WHATSAPP 控制,它定义在 sgcVer.inc 的第 728 行,即从第 727 行延伸到第 758 行的 SGC_EDT_PRO 块的第一行。也就是 Professional 及以上版本。Telegram 由 SGC_TELEGRAM 控制,它在 SGC_EDT_STD 块(第 675 行到第 724 行)内的第 677 行到第 694 行之间定义了六次,每个平台一次。因此 Telegram 低一个层级即可使用。独立的 sgcSocial 包通过第 860 行的 SGC_PACK_SOCIAL 同时开启两者,其第 968 行到第 971 行的块在没有平台保护的情况下定义了它们。
一个 string,即来自 Meta Graph API 的原始响应正文。其完整签名是 function SendMessageText(const aTo, aMessage: string; aPhoneNumberId: string = ''; const aOptions: TsgcWhatsApp_Message_Options = nil): string。随包附带的演示直接记录返回值,这是查看来自 Meta 的错误的最快方法,因为被拒绝的发送会出现在正文中,而不是以异常的形式出现。
组件本身就可以充当服务器。调用 StartServer,它就会自己监听 Meta Webhook。OnBeforeSubscribe 让您接受或拒绝验证请求,OnMessageReceived 为您提供每条入站消息,以及一个可设置以确认该消息的 var aMarkAsRead 标志。StopServer 会将其关闭。发送并不需要这些。
把原生的 TDLib JSON 库放在您的可执行文件旁边。组件在运行时加载它,并按平台命名:Windows 上是 tdjson.dll,64 位 macOS 上是 libtdjson.dylib,64 位 Linux 和 Lazarus Linux 上是 libtdjson.so,Android 上是 libtdjsonandroid.so。iOS 64 是个例外,该库以 libtdjson.a 的形式静态链接。如果缺失,组件会在首次使用时抛出异常。SetTDJsonPath 可以把它指向另一个文件夹。
可以,每种在同一个组件上都有自己的方法:SendMessageImage、SendMessageDocument、SendMessageLocation、SendMessageContact、SendMessageInteractiveButtons 和 SendMessageTemplate(它有重载)。MarkMessageRead 会把入站消息标记为已读。
因为线程模式的缘故。随包附带的演示设置了 NotifyEvents := neAsynchronous,以便它的处理程序可以操作 VCL 控件,它自己的注释也说明在生产环境中应使用 neNoSync。使用 neNoSync 时,事件在工作线程上触发,这样更快,对服务来说也是正确的,而所有涉及 UI 的内容都需要由您自己切换到 UI 线程。
是的。它是一个独立的包,其中包含 sgcWebSockets Core 运行时,同时它也是 sgcWebSockets 的一部分:WhatsApp 从 Professional 起,Telegram 从 Standard 起。在源代码中,独立路径是 sgcVer.inc 第 860 行的 SGC_PACK_SOCIAL,其第 968 行到第 971 行的块定义了两个客户端。
超值之选:All-AccesseSeGeCe 全部产品,含高级支持,每年 €1,059 起。
查看 All-Access 价格

准备好从 Delphi 向您的客户发送消息了吗?

今天就下载试用版,发送您的第一条 WhatsApp 消息。