telegram的客户端有开源的api可以给开发者使用,用来开发客户端。

相关地址是https://core.telegram.org/tdlib/docs/

接下来我展示如何在windows环境在cmake项目使用td。

https://tdlib.github.io/td/build展示我们在windows环境如何编译td。

git clone https://github.com/tdlib/td.git
cd td
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
git checkout bc3512a509f9d29b37346a7e7e929f9a26e66c7e
./bootstrap-vcpkg.bat
./vcpkg.exe install gperf:x64-windows openssl:x64-windows zlib:x64-windows
cd ..
Remove-Item build -Force -Recurse -ErrorAction SilentlyContinue
mkdir build
cd build
cmake -A x64 -DCMAKE_INSTALL_PREFIX:PATH=../tdlib -DCMAKE_TOOLCHAIN_FILE:FILEPATH=../vcpkg/scripts/buildsystems/vcpkg.cmake ..
cmake --build . --target install --config Debug
cd ..
cd ..
dir td/tdlib

我展示一下我编译的过程。

首先安装cmake和vcpkg,并且添加环境变量,这里不再赘述。

然后需要安装三个组件。

vcpkg install gperf openssl zlib

cmake运行。

cmake .. -DGPERF_EXECUTABLE=D:/app/vcpkg/installed/x64-windows/tools/gperf -DOPENSSL_ROOT_DIR=D:/app/vcpkg/installed/x64-windows -DZLIB_ROOT=D:/app/vcpkg/installed/x64-windows -DCMAKE_INSTALL_PREFIX:PATH=D:\file\cpp\lib\tdlib_debug

编译。

cmake --build . --target install --config Debug

我们可能需要编译两种,一种是Debug模式,一种是Release模式。

编译完成,在安装的目录,我们可以看到如下文件结构。

├─bin
│      libcrypto-3-x64.dll
│      libssl-3-x64.dll
│      tdjson.dll
│      zlib1.dll
│
├─include
│  └─td
│      ├─telegram
│      │      Client.h
│      │      Log.h
│      │      tdjson_export.h
│      │      td_api.h
│      │      td_api.hpp
│      │      td_json_client.h
│      │      td_log.h
│      │
│      └─tl
│              TlObject.h
│
└─lib
    │  tdactor.lib
    │  tdapi.lib
    │  tdclient.lib
    │  tdcore.lib
    │  tddb.lib
    │  tde2e.lib
    │  tdjson.lib
    │  tdjson_private.lib
    │  tdjson_static.lib
    │  tdmtproto.lib
    │  tdnet.lib
    │  tdsqlite.lib
    │  tdutils.lib
    │
    ├─cmake
    │  └─Td
    │          TdConfig.cmake
    │          TdConfigVersion.cmake
    │          TdStaticTargets-release.cmake
    │          TdStaticTargets.cmake
    │          TdTargets-release.cmake
    │          TdTargets.cmake
    │
    └─pkgconfig
            tdactor.pc
            tdapi.pc
            tdclient.pc
            tdcore.pc
            tddb.pc
            tde2e.pc
            tdjson.pc
            tdjson_private.pc
            tdjson_static.pc
            tdmtproto.pc
            tdnet.pc
            tdsqlite.pc
            tdutils.pc

这个是一个简单的CMake项目。

CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
project(one)
list(APPEND CMAKE_PREFIX_PATH "D:/file/cpp/lib/tdlib_debug")
include_directories("D:/file/cpp/lib/tdlib_debug/include")
add_executable(one one.cpp)
find_package(Td)
find_package(Boost CONFIG REQUIRED COMPONENTS json)
target_link_libraries(one PRIVATE Td::TdJson Boost::json)

one.cpp

#include <iostream>
#include <td/telegram/td_json_client.h>
#include <boost/json.hpp>
int main()
{
    int client_id = td_create_client_id();
    boost::json::value v;
    v = {{"@type", "getOption"}, {"name", "version"}};
    td_send(client_id, boost::json::serialize(v).c_str());
    while (true)
    {
        const char *result = td_receive(10);
        if (!result)
            continue;
        std::cout << result << std::endl;
    }
    return 0;
}

具体如何运行。

我这个项目需要安装Boost。

vcpkg install boost

在项目文件复制CMakeLists.txt和one.cpp,执行。

mkdir build
cd build
cmake .. -DCMAKE_TOOLCHAIN_FILE=D:/app/vcpkg/scripts/buildsystems/vcpkg.cmake
cmake --build .

运行是需要使用dll,所以可以把td编译产物目录添加到环境变量。

set PATH=%PATH%;D:\file\cpp\lib\tdlib_debug\bin

然后运行

build\Debug\one.exe

可以看见如下输出。

[ 3][t 0][1766815979.062391757][Client.cpp:482] Created managed client 1
[ 3][t 0][1766815979.064108371][Client.cpp:383] Initialize client 1
[ 3][t 0][1766815979.064299821][Client.cpp:280][&td_requests]   Begin to wait for updates with timeout 10.000000
[ 3][t 4][1766815979.065277814][Td.cpp:138][#1][!MultiTd]       Create Td with layer 218, database version 14 and version 56 on 4 
threads
[ 3][t 4][1766815979.065881252][Td.cpp:1348][#1][!Td][&td_requests]     Sending update: updateOption {
  name = "version"
  value = optionValueString {
    value = "1.8.58"
  }
}
[ 3][t 4][1766815979.066354274][Td.cpp:1348][#1][!Td][&td_requests]     Sending update: updateOption {
  name = "commit_hash"
  value = optionValueString {
    value = "GITDIR-NOTFOUND"
  }
}
[ 3][t 0][1766815979.066459655][Client.cpp:293][&td_requests]   End to wait for updates, returning object 0 000001AEB1C19B80      
[ 3][t 4][1766815979.067265748][Td.cpp:1355][#1][!Td][&td_requests]     Sending update: updateAuthorizationState {
  authorization_state = authorizationStateWaitTdlibParameters {
  }
}
{"@type":"updateOption","name":"version","value":{"@type":"optionValueString","value":"1.8.58"},"@client_id":1}[ 3][t 4][1766815979.067872047][Td.cpp:282][#1][!Td][&td_requests] Receive request 1: getOption {
  name = "version"
}

[ 3][t 4][1766815979.068123817][Td.cpp:1372][#1][!Td][&td_requests]     Sending result for request 1: optionValueString {
  value = "1.8.58"
}
[ 3][t 0][1766815979.068181514][Client.cpp:280][&td_requests]   Begin to wait for updates with timeout 10.000000
[ 3][t 0][1766815979.068467140][Client.cpp:293][&td_requests]   End to wait for updates, returning object 0 000001AEB1C1A780      
{"@type":"updateOption","name":"commit_hash","value":{"@type":"optionValueString","value":"GITDIR-NOTFOUND"},"@client_id":1}      
[ 3][t 0][1766815979.068993091][Client.cpp:280][&td_requests]   Begin to wait for updates with timeout 10.000000
[ 3][t 0][1766815979.069097042][Client.cpp:293][&td_requests]   End to wait for updates, returning object 0 000001AEB1C5DB20      
{"@type":"updateAuthorizationState","authorization_state":{"@type":"authorizationStateWaitTdlibParameters"},"@client_id":1}       
[ 3][t 0][1766815979.069492816][Client.cpp:280][&td_requests]   Begin to wait for updates with timeout 10.000000
[ 3][t 0][1766815979.069586515][Client.cpp:293][&td_requests]   End to wait for updates, returning object 1 000001AEB1C1BD10      
{"@type":"optionValueString","value":"1.8.58","@client_id":1}
[ 3][t 0][1766815979.069773197][Client.cpp:280][&td_requests]   Begin to wait for updates with timeout 10.000000