如何使用PHP结合TDLib获取Telegram频道数据?
在PHP中使用TDLib获取Telegram公开频道数据的解决方案
核心流程说明
TDLib采用异步事件驱动模式,所有操作需通过发送请求并监听响应/更新完成。针对你的需求,核心流程分为两步:搜索并订阅公开频道、获取频道历史消息。
1. 加入公开频道
公开频道无需申请权限,只需完成两步操作即可订阅:
- 调用
searchPublicChat,通过频道用户名获取对应的chat_id - 调用
joinChat,传入chat_id完成订阅(即使是公开频道,订阅后才能稳定获取历史消息)
2. 获取频道消息
订阅成功后,调用getChatHistory获取历史消息,需指定关键参数:
chat_id:目标频道的唯一IDlimit:单次获取的消息数量offset_date/offset_message_id:分页参数,用于加载更早的历史消息
完整示例代码
以下代码在你的基础上扩展,包含搜索频道、订阅、获取消息的完整逻辑:
<?php $ffi = FFI::cdef(" void *td_json_client_create(); void td_json_client_destroy(void *client); void td_json_client_send(void *client, const char *request); const char *td_json_client_receive(void *client, double timeout); ", "tdjson.dll"); $client = $ffi->td_json_client_create(); // 请求发送封装 function sendRequest($ffi, $client, array $request): void { $ffi->td_json_client_send($client, json_encode($request, JSON_UNESCAPED_UNICODE)); } // 响应监听封装,循环过滤目标类型响应 function waitForResponse($ffi, $client, string $targetType, float $timeout = 10.0) { while (true) { $responseStr = $ffi->td_json_client_receive($client, $timeout); if (!$responseStr) continue; $response = json_decode($responseStr, true); // 忽略认证状态更新(你已完成登录) if ($response['@type'] === 'updateAuthorizationState') continue; // 返回目标类型响应 if ($response['@type'] === $targetType) return $response; } } // 初始化TDLib参数(替换为你的API信息) sendRequest($ffi, $client, [ '@type' => 'setTdlibParameters', 'parameters' => [ 'api_id' => 123456, // 你的API ID 'api_hash' => 'your_api_hash_here', // 你的API Hash 'device_model' => 'Desktop', 'system_version' => 'Windows', 'application_version' => '1.0', 'database_directory' => './tdlib_data', 'use_message_database' => true, // 建议开启消息缓存 'use_secret_chats' => false, 'system_language_code' => 'en', ] ]); waitForResponse($ffi, $client, 'ok'); // 1. 搜索目标公开频道 $targetUsername = 'telegram'; // 替换为频道用户名(不带@) sendRequest($ffi, $client, [ '@type' => 'searchPublicChat', 'username' => $targetUsername ]); $chatResponse = waitForResponse($ffi, $client, 'chat'); $chatId = $chatResponse['id']; echo "找到频道:{$chatResponse['title']},ID:{$chatId}\n"; // 2. 订阅频道 sendRequest($ffi, $client, [ '@type' => 'joinChat', 'chat_id' => $chatId ]); waitForResponse($ffi, $client, 'ok'); echo "已成功订阅频道\n"; // 3. 获取最新20条历史消息 sendRequest($ffi, $client, [ '@type' => 'getChatHistory', 'chat_id' => $chatId, 'limit' => 20, 'offset_date' => 0, // 从最新消息开始 'offset_message_id' => 0, 'offset_chat_id' => 0 ]); $messagesResponse = waitForResponse($ffi, $client, 'messages'); echo "获取到{$messagesResponse['total_count']}条消息:\n"; // 遍历输出消息内容 foreach ($messagesResponse['messages'] as $msg) { if ($msg['@type'] === 'message') { $sender = $msg['sender_user_id'] ?? '频道'; $content = $msg['content']['@type'] === 'messageText' ? $msg['content']['text']['text'] : '[非文本消息]'; echo "[{$msg['date']}] 发送者ID:{$sender}:{$content}\n"; } } // 销毁客户端 $ffi->td_json_client_destroy($client);
关键注意事项
- 版本匹配:确保
tdjson.dll版本与TDLib官方文档一致,避免API不兼容 - 异步处理:TDLib会持续返回各类更新(如新消息、状态变化),需循环过滤有效响应
- 账号状态:确保你的Telegram账号无登录限制,部分公开频道需正常账号才能订阅
- 分页加载:调整
getChatHistory的offset_date/offset_message_id参数,可加载更早的历史消息
内容的提问来源于stack exchange,提问作者Gene_Nostrada
相关产品推荐
相关产品推荐

