最好的方法是使用update_id,这是一个特定的数字,会随着每个新请求(即更新)而增加。如何实现?
首先,让我们从以下anonymous class(使用PHP7)开始:
$lastUpdateId = new class()
{
const FILE_PATH = "last-update-id.txt";
private $value = 1;
public function __construct()
{
$this->ensureFileExists();
$this->value = filesize(self::FILE_PATH) == 0
? 0 : (int)(file_get_contents(self::FILE_PATH));
}
public function set(int $lastUpdateId)
{
$this->ensureFileExists();
file_put_contents(self::FILE_PATH, $lastUpdateId);
$this->value = $lastUpdateId;
}
public function get(): int
{
return $this->value;
}
public function isNewRequest(int $updateId): bool
{
return $updateId > $this->value;
}
private function ensureFileExists()
{
if (!file_exists(self::FILE_PATH)) {
touch(self::FILE_PATH);
}
}
};
类的作用很明确:通过纯文件处理最后一个update_id。
注意:课程尽量简短。它不提供错误检查。改用您的自定义实现(例如,使用 SplFileObject 代替 file_{get|put}_contents() 函数)。
现在,有两种获取更新的方法:Long Polling xor WebHooks(有关每种方法和所有 JSON 属性的更多详细信息,请查看 Telegram bot API)。上述代码(或类似代码)应在这两种情况下使用。
注意:目前无法同时使用这两种方法。
长轮询方法(默认)
通过这种方式,您可以向 Telegram 机器人 API 发送 HTTPS 请求,并且您会在 JSON 格式的对象中获得更新作为响应。所以,可以做以下工作来获得新的更新(API,why using offset):
$botToken = "<token>";
$updates = json_decode(file_get_contents("https://api.telegram.org/bot{$botToken}/getUpdates?offset={$lastUpdateId->get()}"), true);
// Split updates from each other in $updates
// It is considered that one sample update is stored in $update
// See the section below
parseUpdate($update);
WebHook 方法(首选)
要求您的服务器支持 HTTPS POST 方法,这是即时获取更新的最佳方式。
最初,您必须使用以下请求 (more details) 为您的机器人启用 WebHook:
https://api.telegram.org/bot<token>/setWebhook?url=<file>
将<token> 替换为您的机器人令牌,将<file> 替换为您将接受新请求的文件的地址。同样,它必须是 HTTPS。
好的,最后一步是在指定的 URL 创建文件:
// The update is sent
$update = $_POST;
// See the section below
parseUpdate($update);
从现在开始,您的机器人的所有请求和更新都将直接发送到文件中。
parseUpdate()的实现
它的实现完全取决于您。然而,为了展示如何在实现中使用上面的类,这是一个示例和简短的实现:
function parseUpdate($update)
{
// Validate $update, first
// Actually, you should have a validation class for it
// Here, we suppose that: $update["update_id"] !== null
if ($lastUpdateId->isNewRequest($update["update_id"])) {
$lastUpdateId->set($update["update_id"]);
// New request, go on
} else {
// Old request (or possible file error)
// You may throw exceptions here
}
}
享受吧!
编辑:感谢@Amir 提出的版本建议使这个答案更加完整和有用。