klev-o / telegram-bot-api

简单易用的面向对象实现Telegram机器人API,支持php版本^7.4。你会喜欢的!

2.2.2 2024-08-21 08:24 UTC

README

TelegramBotApi

klev-o/telegram-bot-api

支持php版本^7.4的简单易用实现Telegram机器人API。你会喜欢的!

基于官方Telegram API

License Packagist Downloads GitHub release (latest by date including pre-releases) Scrutinizer code quality (GitHub/Bitbucket) GitHub last commit

📖简介

此机器人完全支持官方Telegram API。完全面向对象,代码简单。所有可用类型和方法都通过类进行描述,所有字段都有文档说明。你甚至不需要查阅官方文档——所有描述都在机器人中!但每个类仍然标明了文档的URL,你可以在这里了解细节等。

你只需放松,创建超级机器人!

注意! 目前,机器人仅支持通过Webhook接收更新。Webhook比长轮询更高效,减少服务器负载,并保证几乎即时刷新应用程序的数据。但需要考虑一些细节,更详细的内容在这里

🛠 安装

在命令行中运行此命令

composer require klev-o/telegram-bot-api

🔌用法

设置webhook

首先,你需要安装Webhook,Telegram会将更新发送到该Webhook。可以使用以下代码完成此操作

<?php

use Klev\TelegramBotApi\Telegram;
use Klev\TelegramBotApi\TelegramException;
use Klev\TelegramBotApi\Methods\SetWebhook;

require 'vendor/autoload.php';

$pageUrl = "https://".$_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"];

try {
    $bot = new Telegram('your personal token');

    if(!file_exists("webhook.trigger")){
        $webhook = new SetWebhook($pageUrl);
        $result = $bot->setWebhook($webhook);
        if($result) {
            file_put_contents("webhook.trigger", time());
            echo 'webhook was set';
        }
    }
    
    //...
} catch (TelegramException $e) {
    // log errors
}

为了防止每次请求都安装Webhook,我们添加了一个简单的检查。现在打开文件,你应该看到'webhook已设置'。如果发生任何错误,则可以在相应的块中捕获它

获取Webhook更新

要接收更新,必须使用getWebhookUpdates()方法

<?php

use Klev\TelegramBotApi\Telegram;
use Klev\TelegramBotApi\TelegramException;
use Klev\TelegramBotApi\Methods\SetWebhook;

require 'vendor/autoload.php';

$pageUrl = "https://".$_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"];

try {
    $bot = new Telegram('your personal token');

    if(!file_exists("webhook.trigger")){
        $webhook = new SetWebhook($pageUrl);
        $result = $bot->setWebhook($webhook);
        if($result) {
            file_put_contents("webhook.trigger", time());
            echo 'webhook was set';
        }
    }
    
    /**@var \Klev\TelegramBotApi\Types\Update $update*/
    $update = $bot->getWebhookUpdates();
} catch (TelegramException $e) {
    // log errors
}

$update变量将是一个Update对象

通常,通过阅读官方文档,你可以看到对象字段的类型或方法返回值——所有这些都完全与代码一致。

例如,$update->message的类型为Message,对应于Klev\TelegramBotApi\Types\Message。

只需查看文档,调用你想要的方法即可!

实际示例

假设我们想让机器人在收到任何消息时回复"Hello, your username"。

让我们写下以下代码

<?php

use Klev\TelegramBotApi\Telegram;
use Klev\TelegramBotApi\TelegramException;
use Klev\TelegramBotApi\Methods\SetWebhook;
use Klev\TelegramBotApi\Methods\SendMessage;

require 'vendor/autoload.php';

$pageUrl = "https://".$_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"];

try {
    $bot = new Telegram('your personal token');

    if(!file_exists("webhook.trigger")){
        $webhook = new SetWebhook($pageUrl);
        $result = $bot->setWebhook($webhook);
        if($result) {
            file_put_contents("webhook.trigger", time());
            echo 'webhook was set';
        }
    }
    
    /**@var \Klev\TelegramBotApi\Types\Update $update*/
    $update = $bot->getWebhookUpdates();
    
    if ($update->message) {
        $chatId = $update->message->chat->id;
        $username = $update->message->from->first_name;
        $text = "Hello, $username!";
        /**@var \Klev\TelegramBotApi\Types\Message $result*/
        $result = $bot->sendMessage(new SendMessage($chatId, $text));
    }
    
} catch (TelegramException $e) {
    // log errors
}

如你所见,一切都非常简单直接。记住,方法有很多参数,你可以根据自己的喜好进一步自定义。每个参数的描述都包含在phpdoc中的代码,或官方API文档的网站上。

$chatId = $update->message->chat->id;
$username = $update->message->from->first_name;
$messageId = $update->message->id;
$text = "Hello, $username!";

$msg = new SendMessage($chatId, $text)
$msg->disable_notification = true;
$msg->reply_to_message_id = $messageId;

$bot->sendMessage($msg);

发送文件

发送文件非常简单:您需要在字段中指定文件路径或URL(如果方法支持通过URL接受文件,请参阅说明)。然后,它将自动检查文件是否存在于本地,并添加所有必要的头信息。

如果文件不可读,您将收到错误"File -filename- is not readable."

以下示例中,如果用户将"doc"发送到机器人,机器人将发送本地文档。

<?php

use Klev\TelegramBotApi\Telegram;
use Klev\TelegramBotApi\TelegramException;
use \Klev\TelegramBotApi\Methods\SendDocument;

require 'vendor/autoload.php';

try {
    $bot = new Telegram('your personal token');
    
    /**@var \Klev\TelegramBotApi\Types\Update $update*/
    $update = $bot->getWebhookUpdates();
    
    if ($update->message && $update->message->text === 'doc') {
        $chatId = $update->message->chat->id;
        $path = 'pat/to/local/doc';
    
        $doc = new SendDocument($chatId, $path);
        $doc->disable_notification = true;
        
        /**@var \Klev\TelegramBotApi\Types\Message $result*/
        $result = $bot->sendDocument($doc);
    }
} catch (TelegramException $e) {
    // log errors
}

同样,没有阻止通过链接传递文件而不是本地文件——代码将完全相同,只是这部分将发生变化。

$path = 'https://link/to/file';

📟高级

如你所见,$bot->getWebhookUpdates() 方法将结果返回为一个 Update 对象。在最简单的情况下,我们可以检查该对象中哪个字段被填充,并在此基础上实现进一步的逻辑。但如果我们有一个中大型项目,这可能不太方便。

事件(Klev\TelegramBotApi\Events\*)来拯救我们

你可以为这些事件中的任何一个注册自己的处理器,并确保你响应的是哪个更新。默认情况下,事件是禁用的。要启用它们,你需要使用方法 $bot->setEnableEvents(true); 以下是一个例子

<?php

use Klev\TelegramBotApi\Telegram;
use Klev\TelegramBotApi\Events\EditedMessageEvent;
use Monolog\Handler\StreamHandler;
use Monolog\Logger;

require 'vendor/autoload.php';

//The logger does not have to be created, it is used only for an example
$logger = new Logger('App');
$logger->pushHandler(new StreamHandler('../var/logs/app.log'));

$bot = new Telegram('your personal token');
$bot->setEnableEvents(true);

$bot->on(EditedMessageEvent::class, static function(EditedMessageEvent $event) use ($logger)  {
    //do something with $event
    $logger->info('id from event', [$event->update_id])
    $logger->info('payload from event', [$event->payload])
});

每个事件对象将包含两个必需的字段:update_idpayload。事件中 payload 的类型可以在期望事件的类中查看

//For this example, let's assume that the incoming webhook populated the message field in the object
$updates = $bot->getWebhookUpdates();

//Then the `MessageEvent` will fire and the fields will be filled accordingly:
$event->update_id  === $updates->update_id
$event->payload === $updates->message

此外,作为一个事件处理器,你可以使用任何符合可调用类型的对象。以下是一个例子

<?php

use Klev\TelegramBotApi\Telegram;
use Klev\TelegramBotApi\Events\MessageEvent;
use Monolog\Handler\StreamHandler;
use Monolog\Logger;

require 'vendor/autoload.php';

//imagine that you are using some DI
$builder = new DI\ContainerBuilder();

$builder->addDefinitions([
    //specify the rules on how to create an object
    LoggerInterface::class => function(\DI\Container $c) {
        $log = new Logger('App');
        $log->pushHandler(new StreamHandler('../var/logs/app.log'));
        return $log;
    },
    //specify the rules on how to create an object
    MessageReceivedListener::class => function(\DI\Container $c) {
        return new MessageReceivedListener($c->get(LoggerInterface::class));
    }
]);
$container = $builder->build();

//Instead of using an anonymous function, we can now use a custom class, into which,
//if necessary, we can pull everything we need (working with the database, sending by mail, etc.)
class MessageReceivedListener
{
    private Logger $logger;
    public function __construct(Logger $logger)
    {
        $this->logger = $logger;
    }
    public function __invoke(MessageEvent $event)
    {
        $this->log->info('Using invocable class', (array)$event->payload);
    }
}

$bot = new Telegram('your personal token');
$bot->setEnableEvents(true);

$bot->on(MessageEvent::class, $container->get(MessageReceivedListener::class));

$bot->getWebhookUpdates();

🎁捐赠

如果你喜欢这个项目,请支持它。资金将用于食物。

🧨故障排除

请,如果你发现任何错误或不太准确的地方,请在此 问题页面 报告

最后...

快乐的机器人之旅 🤖