longman/telegram-bot


README

PHP Telegram机器人

PHP Telegram Bot logo

基于官方 Telegram机器人API 的Telegram机器人

API Version Join the bot support group on Telegram Donate

Tests Code Coverage Code Quality Latest Stable Version Dependencies Total Downloads Downloads Month Minimum PHP Version License

目录

介绍

这是一个纯PHP Telegram机器人,完全可以通过插件进行扩展。

Telegram宣布正式支持机器人API,允许各种集成商将自动化交互带到移动平台。此机器人旨在提供一个平台,用户可以轻松编写机器人并在几分钟内进行交互。

机器人可以

  • 使用WebhookgetUpdates方法检索更新。
  • 支持根据Telegram机器人API 7.1(2024年2月)的所有类型和方法。
  • 支持超级群组。
  • 处理与其他机器人的聊天中的命令。
  • 从机器人管理员界面管理频道。
  • 完全支持内联机器人
  • 内联键盘。
  • 消息、内联查询和ChosenInlineQuery存储在数据库中。
  • 会话功能。

此代码可在GitHub上找到。欢迎提交拉取请求。

说明

创建您的第一个机器人

  1. @BotFather发送消息,内容为:/newbot

    如果您不知道如何通过用户名发送消息,请点击您的Telegram应用中的搜索字段,并输入@BotFather,您应该能够开始对话。注意不要发送给错误联系人,因为一些用户的用户名与BotFather相似。

    BotFather initial conversation

  2. @BotFather回复

    Alright, a new bot. How are we going to call it? Please choose a name for your bot.
    
  3. 输入您想要的机器人名称。

  4. @BotFather回复

    Good. Now let's choose a username for your bot. It must end in `bot`. Like this, for example: TetrisBot or tetris_bot.
    
  5. 为您的机器人设置一个想要的用户名,至少5个字符,并且必须以bot结尾。例如:telesample_bot

  6. @BotFather回复

    Done! Congratulations on your new bot. You will find it at
    telegram.me/telesample_bot. You can now add a description, about
    section and profile picture for your bot, see /help for a list of
    commands.
    
    Use this token to access the HTTP API:
    123456789:AAG90e14-0f8-40183D-18491dDE
    
    For a description of the Bot API, see this page:
    https://core.telegram.org/bots/api
    
  7. 记下上面提到的'token'。

可选:设置机器人隐私

  1. @BotFather发送/setprivacy

    BotFather later conversation

  2. @BotFather回复

    Choose a bot to change group messages settings.
    
  3. 输入(或选择)@telesample_bot(将其更改为在第5步中设置的名称,但以@开头)

  4. @BotFather回复

    'Enable' - your bot will only receive messages that either start with the '/' symbol or mention the bot by username.
    'Disable' - your bot will receive all messages that people send to groups.
    Current status is: ENABLED
    
  5. 输入(或选择)禁用以让您的机器人接收发送到群组的所有消息。

  6. @BotFather回复

    Success! The new status is: DISABLED. /help
    

使用Composer安装此包

通过Composer安装此软件包。编辑项目的composer.json文件以要求longman/telegram-bot

创建composer.json文件

{
    "name": "yourproject/yourproject",
    "type": "project",
    "require": {
        "php": "^8.1",
        "longman/telegram-bot": "*"
    }
}

然后运行composer update

或者

在命令行中运行此命令

composer require longman/telegram-bot

选择如何检索Telegram更新

机器人可以通过WebhookgetUpdates方法处理更新。

使用自定义Bot API服务器

仅适用于高级用户!

从Telegram Bot API 5.0开始,用户可以运行自己的Bot API服务器来处理更新。这意味着,PHP Telegram Bot需要配置以服务该自定义URI。另外,您可以定义上传到机器人的文件可下载的URI(注意{API_KEY}占位符)。

Longman\TelegramBot\Request::setCustomBotApiUri(
    $api_base_uri          = 'https://your-bot-api-server', // Default: https://api.telegram.org
    $api_base_download_uri = '/path/to/files/{API_KEY}'     // Default: /file/bot{API_KEY}
);

注意:如果您以--local模式运行机器人,则不需要Request::downloadFile()方法,因为那时您可以直接从Request::getFile()返回的绝对路径访问文件。

Webhook安装

注意:有关更详细的说明,请访问example-bot存储库并遵循那里的说明。

为了设置Webhook,您需要一个支持HTTPS和Composer的服务器。(对于自签名证书,您需要添加一些额外的代码)

创建set.php,内容如下

<?php
// Load composer
require __DIR__ . '/vendor/autoload.php';

$bot_api_key  = 'your:bot_api_key';
$bot_username = 'username_bot';
$hook_url     = 'https://your-domain/path/to/hook.php';

try {
    // Create Telegram API object
    $telegram = new Longman\TelegramBot\Telegram($bot_api_key, $bot_username);

    // Set webhook
    $result = $telegram->setWebhook($hook_url);
    if ($result->isOk()) {
        echo $result->getDescription();
    }
} catch (Longman\TelegramBot\Exception\TelegramException $e) {
    // log telegram errors
    // echo $e->getMessage();
}

通过浏览器打开您的set.php以将Webhook注册到Telegram。您应该看到Webhook已设置

现在,创建hook.php,内容如下

<?php
// Load composer
require __DIR__ . '/vendor/autoload.php';

$bot_api_key  = 'your:bot_api_key';
$bot_username = 'username_bot';

try {
    // Create Telegram API object
    $telegram = new Longman\TelegramBot\Telegram($bot_api_key, $bot_username);

    // Handle telegram webhook request
    $telegram->handle();
} catch (Longman\TelegramBot\Exception\TelegramException $e) {
    // Silence is golden!
    // log telegram errors
    // echo $e->getMessage();
}

自签名证书

上传证书,并在set.php中将路径作为参数添加

$result = $telegram->setWebhook($hook_url, ['certificate' => '/path/to/certificate']);

取消Webhook

编辑unset.php,并使用您的机器人凭据执行它。

getUpdates安装

为了获得最佳性能,MySQL数据库应该启用getUpdates方法!

创建getUpdatesCLI.php,内容如下

#!/usr/bin/env php
<?php
require __DIR__ . '/vendor/autoload.php';

$bot_api_key  = 'your:bot_api_key';
$bot_username = 'username_bot';

$mysql_credentials = [
   'host'     => 'localhost',
   'port'     => 3306, // optional
   'user'     => 'dbuser',
   'password' => 'dbpass',
   'database' => 'dbname',
];

try {
    // Create Telegram API object
    $telegram = new Longman\TelegramBot\Telegram($bot_api_key, $bot_username);

    // Enable MySQL
    $telegram->enableMySql($mysql_credentials);

    // Handle telegram getUpdates request
    $telegram->handleGetUpdates();
} catch (Longman\TelegramBot\Exception\TelegramException $e) {
    // log telegram errors
    // echo $e->getMessage();
}

然后,为文件赋予执行权限

$ chmod +x getUpdatesCLI.php

最后,运行它!

$ ./getUpdatesCLI.php

无数据库的getUpdates

如果您选择使用或不强制使用getUpdates方法而不使用数据库,可以将上面的$telegram->enableMySql(...);行替换为

$telegram->useGetUpdatesWithoutDatabase();

更新过滤

❗ 注意,默认情况下,Telegram将发送未来可能添加的任何新更新类型。这可能导致未考虑这些类型的命令中断!

建议您具体定义机器人可以接收并正确处理的更新类型。

您可以通过设置webhook或在使用getUpdates时传递允许的类型数组来定义发送到机器人的更新类型。

use Longman\TelegramBot\Entities\Update;

// For all update types currently implemented in this library:
// $allowed_updates = Update::getUpdateTypes();

// Define the list of allowed Update types manually:
$allowed_updates = [
    Update::TYPE_MESSAGE,
    Update::TYPE_CHANNEL_POST,
    // etc.
];

// When setting the webhook.
$telegram->setWebhook($hook_url, ['allowed_updates' => $allowed_updates]);

// When handling the getUpdates method.
$telegram->handleGetUpdates(['allowed_updates' => $allowed_updates]);

或者,可以通过定义自定义更新过滤器来允许或拒绝更新处理。

假设我们只想允许ID为428的用户的消息,我们可以在处理请求之前这样做

$telegram->setUpdateFilter(function (Update $update, Telegram $telegram, &$reason = 'Update denied by update_filter') {
    $user_id = $update->getMessage()->getFrom()->getId();
    if ($user_id === 428) {
        return true;
    }

    $reason = "Invalid user with ID {$user_id}";
    return false;
});

拒绝更新的原因可以使用$reason参数定义。此文本将被写入调试日志。

支持

类型

所有类型均按照Telegram API 7.1(2024年2月)实现。

内联查询

完全支持根据Telegram API 7.1(2024年2月)的内置查询。

方法

所有方法均按照Telegram API 7.1(2024年2月)实现。

发送消息

超过4096个字符的消息将被拆分为多个消息。

$result = Request::sendMessage([
    'chat_id' => $chat_id,
    'text'    => 'Your utf8 text 😜 ...',
]);

发送照片

要发送本地照片,请使用文件路径将其正确添加到$data参数中。

$result = Request::sendPhoto([
    'chat_id' => $chat_id,
    'photo'   => Request::encodeFile('/path/to/pic.jpg'),
]);

如果您知道之前上传文件的file_id,只需直接在数据数组中使用它即可。

$result = Request::sendPhoto([
    'chat_id' => $chat_id,
    'photo'   => 'AAQCCBNtIhAoAAss4tLEZ3x6HzqVAAqC',
]);

要发送远程照片,请使用直接URL。

$result = Request::sendPhoto([
    'chat_id' => $chat_id,
    'photo'   => 'https://example.com/path/to/pic.jpg',
]);

sendAudiosendDocumentsendAnimationsendStickersendVideosendVoicesendVideoNote都以相同的方式工作,只需查阅API文档以获取确切用法。请参见ImageCommand.php以获取完整示例。

发送聊天动作

Request::sendChatAction([
    'chat_id' => $chat_id,
    'action'  => Longman\TelegramBot\ChatAction::TYPING,
]);

getUserProfilePhoto

检索用户照片。(请参阅WhoamiCommand.php以获取完整示例)

getFile和downloadFile

获取文件路径并下载它。(请参阅WhoamiCommand.php以获取完整示例)

向所有活跃聊天发送消息

为此,您必须启用MySQL连接。以下是一个示例用法(检查DB::selectChats()以获取参数用法)

$results = Request::sendToActiveChats(
    'sendMessage', // Callback function to execute (see Request.php methods)
    ['text' => 'Hey! Check out the new features!!'], // Param to evaluate the request
    [
        'groups'      => true,
        'supergroups' => true,
        'channels'    => false,
        'users'       => true,
    ]
);

您还可以从与您的机器人的私人聊天中向用户广播消息。请参阅下面的管理命令

工具

MySQL存储(推荐)

如果您想在命令中进一步使用消息/用户/聊天,请在handle()方法之前创建一个新的数据库(utf8mb4_unicode_520_ci),导入structure.sql并启用MySQL支持。

$mysql_credentials = [
   'host'     => 'localhost',
   'port'     => 3306, // optional
   'user'     => 'dbuser',
   'password' => 'dbpass',
   'database' => 'dbname',
];

$telegram->enableMySql($mysql_credentials);

在启用MySQL时,您还可以为所有表设置自定义前缀。

$telegram->enableMySql($mysql_credentials, $bot_username . '_');

您还可以将内置查询和所选内置查询数据存储在数据库中。

外部数据库连接

您可以为库提供外部MySQL PDO连接。以下是如何配置它。

$telegram->enableExternalMySql($external_pdo_connection);
//$telegram->enableExternalMySql($external_pdo_connection, $table_prefix)

频道支持

所有实现的方法都可以用于管理频道。使用管理命令,您可以直接通过您的机器人私人聊天管理您的频道。

命令

预定义命令

机器人能够在具有多个机器人的聊天中识别命令(/command@mybot)。

它还可以执行由事件触发的命令,即所谓的服务消息。

自定义命令

也许您想开发自己的命令。有一些指南可以帮助您创建自己的命令

此外,请务必查看示例命令以了解有关自定义命令及其工作方式的更多信息。

您可以通过不同的方式添加自定义命令。

// Add a folder that contains command files
$telegram->addCommandsPath('/path/to/command/files');
//$telegram->addCommandsPaths(['/path/to/command/files', '/another/path']);

// Add a command directly using the class name
$telegram->addCommandClass(MyCommand::class);
//$telegram->addCommandClasses([MyCommand::class, MyOtherCommand::class]);

命令配置

使用此方法,您可以设置一些特定于命令的参数,例如

// Google geocode/timezone API key for /date command
$telegram->setCommandConfig('date', [
    'google_api_key' => 'your_google_api_key_here',
]);

// OpenWeatherMap API key for /weather command
$telegram->setCommandConfig('weather', [
    'owm_api_key' => 'your_owm_api_key_here',
]);

管理员命令

启用此功能后,机器人管理员可以执行一些超级用户命令,例如

  • 列出所有以机器人开始的聊天/chats
  • 清理旧数据库条目/cleanup
  • 显示有关机器人的调试信息/debug
  • 向所有聊天发送消息/sendtoall
  • 将任何内容发布到您的频道/sendtochannel
  • 使用/whois检查用户或聊天

请查看存储在 src/Commands/AdminCommands/ 文件夹中的所有默认管理员命令。

设置管理员

您可以使用此选项指定一个或多个管理员。

// Single admin
$telegram->enableAdmin(your_telegram_user_id);

// Multiple admins
$telegram->enableAdmins([
    your_telegram_user_id,
    other_telegram_user_id,
]);

您可以使用 /whoami 命令检索 Telegram 用户 ID。

频道管理

要启用此功能,请按照以下步骤操作:

  • 将您的机器人添加为频道管理员,这可以通过任何 Telegram 客户端完成。
  • 如上所述管理员部分中所述,为您的用户启用管理员界面。
  • 将您的频道名称作为参数输入到 /sendtochannel 命令中。
$telegram->setCommandConfig('sendtochannel', [
    'your_channel' => [
        '@type_here_your_channel',
    ]
]);
  • 如果您想要管理更多频道:
$telegram->setCommandConfig('sendtochannel', [
    'your_channel' => [
        '@type_here_your_channel',
        '@type_here_another_channel',
        '@and_so_on',
    ]
]);
  • 祝您玩得开心!

上传和下载目录路径

要使用上传和下载功能,您需要设置路径。

$telegram->setDownloadPath('/your/path/Download');
$telegram->setUploadPath('/your/path/Upload');

文档

请查看 Wiki 了解更多信息和使用教程!请自由地改进!

资产

所有项目资产都可以在 assets 仓库中找到。

示例机器人

我们正在忙于构建一个完整的 A-Z 示例机器人,以帮助您开始使用这个库,并展示如何使用其所有功能。您可以在 example-bot 仓库 中查看进度。

使用此库的项目

这是一个使用此库的项目列表,请自由地添加您的项目!

故障排除

如果您喜欢走在前沿,请在 PHP Telegram Bot issues 页面上报告您发现的任何错误。

贡献

有关更多信息,请参阅 CONTRIBUTING

安全性

有关更多信息,请参阅 SECURITY

捐赠

我们在业余时间投入了无数个小时来编写这个机器人,旨在为您提供易于使用和扩展的 Telegram Bot 库。如果您喜欢使用这个库,并想表示感谢,捐款是一种表达您支持的好方法。

捐款将重新投入到项目中 👍

感谢您让这个项目保持活力 🙏

企业版

作为 Tidelift 订阅的一部分提供。

PHP Telegram Bot 的维护者以及成千上万的其他软件包的维护者正在与 Tidelift 合作,为构建应用程序时使用的开源依赖项提供商业支持和维护。节省时间,降低风险,并提高代码质量,同时支付使用依赖项的维护者。了解更多。

许可协议

请参阅此仓库中包含的 LICENSE 文件,以获取完整的 MIT 许可证副本,本项目受此许可证授权。

致谢

CREDITS 中列出。