Repository: php-telegram-bot/laravel
Branch: main
Commit: f0ba8e0018ac
Files: 44
Total size: 68.8 KB
Directory structure:
gitextract_qf0nzb7c/
├── .gitignore
├── .styleci.yml
├── changelog.md
├── composer.json
├── config/
│ └── telegram.php
├── database/
│ └── migrations/
│ ├── 2021_06_14_171118_create_telegram_bot_structure.php
│ ├── 2022_02_18_175100_update_to_0.75.0.php
│ ├── 2022_04_24_175700_update_to_0.77.0.php
│ ├── 2022_10_04_221900_update_to_0.78.0.php
│ ├── 2022_11_11_130500_update_to_0.80.0.php
│ ├── 2023_05-07_101600_update_to_0.81.0.php
│ └── sql/
│ ├── 0.74.0-0.75.0.sql
│ ├── 0.76.1-0.77.0.sql
│ ├── 0.77.1-0.78.0.sql
│ ├── 0.79.0-0.80.0.sql
│ ├── 0.80.0-0.81.0.sql
│ └── structure-0.73.0.sql
├── license.md
├── phpunit.xml
├── readme.md
├── routes/
│ └── telegram.php
└── src/
├── Console/
│ └── Commands/
│ ├── GeneratorCommand.php
│ ├── MakeTelegramCommand.php
│ ├── TelegramCloseCommand.php
│ ├── TelegramDeleteWebhookCommand.php
│ ├── TelegramFetchCommand.php
│ ├── TelegramLogoutCommand.php
│ ├── TelegramPublishCommand.php
│ ├── TelegramSetWebhookCommand.php
│ └── stubs/
│ ├── example-start-command.stub
│ └── telegram-command.stub
├── Facades/
│ ├── CallbackButton.php
│ └── Telegram.php
├── Factories/
│ └── CallbackButton.php
├── Http/
│ └── Middleware/
│ └── TrustTelegramNetwork.php
├── LaravelTelegramBot.php
├── Telegram/
│ ├── Commands/
│ │ ├── CallbackqueryCommand.php
│ │ └── GenericmessageCommand.php
│ ├── Conversation/
│ │ ├── ConversationWrapper.php
│ │ └── LeadsConversation.php
│ ├── InlineKeyboardButton/
│ │ ├── CallbackPayload.php
│ │ └── RemembersCallbackPayload.php
│ └── UsesEffectiveEntities.php
└── TelegramServiceProvider.php
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
# Created by https://www.toptal.com/developers/gitignore/api/laravel,composer
# Edit at https://www.toptal.com/developers/gitignore?templates=laravel,composer
### Composer ###
composer.phar
/vendor/
# Commit your application's lock file https://getcomposer.org/doc/01-basic-usage.md#commit-your-composer-lock-file-to-version-control
# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file
composer.lock
### Laravel ###
node_modules/
npm-debug.log
yarn-error.log
# Laravel 4 specific
bootstrap/compiled.php
app/storage/
# Laravel 5 & Lumen specific
public/storage
public/hot
# Laravel 5 & Lumen specific with changed public path
public_html/storage
public_html/hot
storage/*.key
.env
Homestead.yaml
Homestead.json
/.vagrant
.phpunit.result.cache
# Laravel IDE helper
*.meta.*
_ide_*
# End of https://www.toptal.com/developers/gitignore/api/laravel,composer
/.idea
================================================
FILE: .styleci.yml
================================================
preset: laravel
================================================
FILE: changelog.md
================================================
# Changelog
All notable changes to `LaravelTelegramBot` will be documented in this file.
## Version 2.1.0
### Added
- Support for Laravel 10
### Changed
- Bump to core version 0.81.0
## Version 2.0.0
### Added
- Everything
================================================
FILE: composer.json
================================================
{
"name": "php-telegram-bot/laravel",
"description": "Integrates PHP Telegram Bot into Laravel.",
"license": "MIT",
"authors": [
{
"name": "Avtandil Kikabidze aka LONGMAN",
"email": "akalongman@gmail.com",
"homepage": "http://longman.me",
"role": "Maintainer, Developer"
},
{
"name": "Tii",
"email": "mail@tii.one",
"role": "Developer"
}
],
"homepage": "https://github.com/php-telegram-bot/laravel",
"keywords": ["laravel", "telegram", "bot"],
"require": {
"illuminate/support": "~7|~8|~9|~10|~11|~12",
"longman/telegram-bot": "^0.81",
"ext-pcntl": "*"
},
"require-dev": {
"phpunit/phpunit": "~9.0",
"symfony/process": "^5.3"
},
"autoload": {
"psr-4": {
"PhpTelegramBot\\Laravel\\": "src/"
}
},
"extra": {
"branch-alias": {
"dev-main": "2.1.x-dev"
},
"laravel": {
"providers": [
"PhpTelegramBot\\Laravel\\TelegramServiceProvider"
],
"aliases": {
"CallbackButton": "PhpTelegramBot\\Laravel\\Facades\\CallbackButton",
"Telegram": "PhpTelegramBot\\Laravel\\Facades\\Telegram"
}
}
},
"minimum-stability": "dev",
"prefer-stable": true,
"config": {
"allow-plugins": {
"dealerdirect/phpcodesniffer-composer-installer": true
}
}
}
================================================
FILE: config/telegram.php
================================================
<?php
return [
'bot' => [
'api_token' => env('TELEGRAM_API_TOKEN'),
'username' => env('TELEGRAM_BOT_USERNAME', ''),
'api_url' => env('TELEGRAM_API_URL'),
],
'admins' => env('TELEGRAM_ADMINS', '')
];
================================================
FILE: database/migrations/2021_06_14_171118_create_telegram_bot_structure.php
================================================
<?php
use Illuminate\Database\Migrations\Migration;
return new class extends Migration {
public function up()
{
DB::unprepared(file_get_contents(__DIR__ . '/sql/structure-0.73.0.sql'));
}
public function down()
{
//
}
};
================================================
FILE: database/migrations/2022_02_18_175100_update_to_0.75.0.php
================================================
<?php
use Illuminate\Database\Migrations\Migration;
return new class extends Migration {
public function up()
{
DB::unprepared(file_get_contents(__DIR__ . '/sql/0.74.0-0.75.0.sql'));
}
public function down()
{
//
}
};
================================================
FILE: database/migrations/2022_04_24_175700_update_to_0.77.0.php
================================================
<?php
use Illuminate\Database\Migrations\Migration;
return new class extends Migration {
public function up()
{
DB::unprepared(file_get_contents(__DIR__ . '/sql/0.76.1-0.77.0.sql'));
}
public function down()
{
//
}
};
================================================
FILE: database/migrations/2022_10_04_221900_update_to_0.78.0.php
================================================
<?php
use Illuminate\Database\Migrations\Migration;
return new class extends Migration {
public function up()
{
DB::unprepared(file_get_contents(__DIR__ . '/sql/0.77.1-0.78.0.sql'));
}
public function down()
{
//
}
};
================================================
FILE: database/migrations/2022_11_11_130500_update_to_0.80.0.php
================================================
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;
return new class extends Migration {
public function up()
{
DB::unprepared(file_get_contents(__DIR__ . '/sql/0.79.0-0.80.0.sql'));
}
public function down()
{
//
}
};
================================================
FILE: database/migrations/2023_05-07_101600_update_to_0.81.0.php
================================================
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;
return new class extends Migration {
public function up()
{
DB::unprepared(file_get_contents(__DIR__ . '/sql/0.80.0-0.81.0.sql'));
}
public function down()
{
//
}
};
================================================
FILE: database/migrations/sql/0.74.0-0.75.0.sql
================================================
CREATE TABLE IF NOT EXISTS `bot_chat_join_request` (
`id` BIGINT UNSIGNED AUTO_INCREMENT COMMENT 'Unique identifier for this entry',
`chat_id` BIGINT NOT NULL COMMENT 'Chat to which the request was sent',
`user_id` BIGINT NOT NULL COMMENT 'User that sent the join request',
`date` TIMESTAMP NOT NULL COMMENT 'Date the request was sent in Unix time',
`bio` TEXT NULL COMMENT 'Optional. Bio of the user',
`invite_link` TEXT NULL COMMENT 'Optional. Chat invite link that was used by the user to send the join request',
`created_at` timestamp NULL DEFAULT NULL COMMENT 'Entry date creation',
PRIMARY KEY (`id`),
FOREIGN KEY (`chat_id`) REFERENCES `bot_chat` (`id`),
FOREIGN KEY (`user_id`) REFERENCES `bot_user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci;
ALTER TABLE `bot_telegram_update` ADD COLUMN `chat_join_request_id` BIGINT UNSIGNED NULL COMMENT 'A request to join the chat has been sent';
ALTER TABLE `bot_telegram_update` ADD FOREIGN KEY (`chat_join_request_id`) REFERENCES `bot_chat_join_request` (`id`);
ALTER TABLE `bot_message` ADD COLUMN `is_automatic_forward` tinyint(1) DEFAULT 0 COMMENT 'True, if the message is a channel post that was automatically forwarded to the connected discussion group' AFTER `forward_date`;
ALTER TABLE `bot_message` ADD COLUMN `has_protected_content` tinyint(1) DEFAULT 0 COMMENT 'True, if the message can''t be forwarded' AFTER `edit_date`;
================================================
FILE: database/migrations/sql/0.76.1-0.77.0.sql
================================================
ALTER TABLE `bot_message` ADD COLUMN `web_app_data` TEXT NULL DEFAULT NULL COMMENT 'Service message: data sent by a Web App' AFTER `voice_chat_participants_invited`;
ALTER TABLE `bot_message`
CHANGE `voice_chat_scheduled` `video_chat_scheduled` TEXT COMMENT 'Service message: video chat scheduled',
CHANGE `voice_chat_started` `video_chat_started` TEXT COMMENT 'Service message: video chat started',
CHANGE `voice_chat_ended` `video_chat_ended` TEXT COMMENT 'Service message: video chat ended',
CHANGE `voice_chat_participants_invited` `video_chat_participants_invited` TEXT COMMENT 'Service message: new participants invited to a video chat';
================================================
FILE: database/migrations/sql/0.77.1-0.78.0.sql
================================================
ALTER TABLE `bot_user` ADD COLUMN `is_premium` tinyint(1) DEFAULT 0 COMMENT 'True, if this user is a Telegram Premium user' AFTER `language_code`;
ALTER TABLE `bot_user` ADD COLUMN `added_to_attachment_menu` tinyint(1) DEFAULT 0 COMMENT 'True, if this user added the bot to the attachment menu' AFTER `is_premium`;
================================================
FILE: database/migrations/sql/0.79.0-0.80.0.sql
================================================
ALTER TABLE `bot_message`
ADD COLUMN `is_topic_message` TINYINT(1) DEFAULT 0 COMMENT 'True, if the message is sent to a forum topic' AFTER `forward_date`,
ADD COLUMN `message_thread_id` BIGINT(20) NULL DEFAULT NULL COMMENT 'Unique identifier of a message thread to which the message belongs; for supergroups only' AFTER `id`,
ADD COLUMN `forum_topic_created` TEXT NULL DEFAULT NULL COMMENT 'Service message: forum topic created' AFTER `proximity_alert_triggered`,
ADD COLUMN `forum_topic_closed` TEXT NULL DEFAULT NULL COMMENT 'Service message: forum topic closed' AFTER `forum_topic_created`,
ADD COLUMN `forum_topic_reopened` TEXT NULL DEFAULT NULL COMMENT 'Service message: forum topic reopened' AFTER `forum_topic_closed`;
ALTER TABLE `bot_chat`
ADD COLUMN `is_forum` TINYINT(1) DEFAULT 0 COMMENT 'True, if the supergroup chat is a forum (has topics enabled)' AFTER `last_name`;
================================================
FILE: database/migrations/sql/0.80.0-0.81.0.sql
================================================
ALTER TABLE `bot_message`
ADD COLUMN `has_media_spoiler` TINYINT(1) DEFAULT 0 COMMENT 'True, if the message media is covered by a spoiler animation' AFTER `caption`,
ADD COLUMN `write_access_allowed` TEXT DEFAULT NULL COMMENT 'Service message: the user allowed the bot added to the attachment menu to write messages' AFTER `connected_website`,
ADD COLUMN `forum_topic_edited` TEXT DEFAULT NULL COMMENT 'Service message: forum topic edited' AFTER `forum_topic_created`,
ADD COLUMN `general_forum_topic_hidden` TEXT DEFAULT NULL COMMENT 'Service message: the General forum topic hidden' AFTER `forum_topic_reopened`,
ADD COLUMN `general_forum_topic_unhidden` TEXT DEFAULT NULL COMMENT 'Service message: the General forum topic unhidden' AFTER `general_forum_topic_hidden`,
ADD COLUMN `user_shared` TEXT DEFAULT NULL COMMENT 'Optional. Service message: a user was shared with the bot' AFTER `successful_payment`,
ADD COLUMN `chat_shared` TEXT DEFAULT NULL COMMENT 'Optional. Service message: a chat was shared with the bot' AFTER `user_shared`;
================================================
FILE: database/migrations/sql/structure-0.73.0.sql
================================================
CREATE TABLE IF NOT EXISTS bot_user (
`id` bigint COMMENT 'Unique identifier for this user or bot',
`is_bot` tinyint(1) DEFAULT 0 COMMENT 'True, if this user is a bot',
`first_name` CHAR(255) NOT NULL DEFAULT '' COMMENT 'User''s or bot''s first name',
`last_name` CHAR(255) DEFAULT NULL COMMENT 'User''s or bot''s last name',
`username` CHAR(191) DEFAULT NULL COMMENT 'User''s or bot''s username',
`language_code` CHAR(10) DEFAULT NULL COMMENT 'IETF language tag of the user''s language',
`created_at` timestamp NULL DEFAULT NULL COMMENT 'Entry date creation',
`updated_at` timestamp NULL DEFAULT NULL COMMENT 'Entry date update',
PRIMARY KEY (`id`),
KEY `username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci;
CREATE TABLE IF NOT EXISTS bot_chat (
`id` bigint COMMENT 'Unique identifier for this chat',
`type` ENUM('private', 'group', 'supergroup', 'channel') NOT NULL COMMENT 'Type of chat, can be either private, group, supergroup or channel',
`title` CHAR(255) DEFAULT '' COMMENT 'Title, for supergroups, channels and group chats',
`username` CHAR(255) DEFAULT NULL COMMENT 'Username, for private chats, supergroups and channels if available',
`first_name` CHAR(255) DEFAULT NULL COMMENT 'First name of the other party in a private chat',
`last_name` CHAR(255) DEFAULT NULL COMMENT 'Last name of the other party in a private chat',
`all_members_are_administrators` tinyint(1) DEFAULT 0 COMMENT 'True if a all members of this group are admins',
`created_at` timestamp NULL DEFAULT NULL COMMENT 'Entry date creation',
`updated_at` timestamp NULL DEFAULT NULL COMMENT 'Entry date update',
`old_id` bigint DEFAULT NULL COMMENT 'Unique chat identifier, this is filled when a group is converted to a supergroup',
PRIMARY KEY (`id`),
KEY `old_id` (`old_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci;
CREATE TABLE IF NOT EXISTS bot_user_chat (
`user_id` bigint COMMENT 'Unique user identifier',
`chat_id` bigint COMMENT 'Unique user or chat identifier',
PRIMARY KEY (`user_id`, `chat_id`),
FOREIGN KEY (`user_id`) REFERENCES bot_user (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY (`chat_id`) REFERENCES bot_chat (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci;
CREATE TABLE IF NOT EXISTS bot_inline_query (
`id` bigint UNSIGNED COMMENT 'Unique identifier for this query',
`user_id` bigint NULL COMMENT 'Unique user identifier',
`location` CHAR(255) NULL DEFAULT NULL COMMENT 'Location of the user',
`query` TEXT NOT NULL COMMENT 'Text of the query',
`offset` CHAR(255) NULL DEFAULT NULL COMMENT 'Offset of the result',
`chat_type` CHAR(255) NULL DEFAULT NULL COMMENT 'Optional. Type of the chat, from which the inline query was sent.',
`created_at` timestamp NULL DEFAULT NULL COMMENT 'Entry date creation',
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`),
FOREIGN KEY (`user_id`) REFERENCES bot_user (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci;
CREATE TABLE IF NOT EXISTS bot_chosen_inline_result (
`id` bigint UNSIGNED AUTO_INCREMENT COMMENT 'Unique identifier for this entry',
`result_id` CHAR(255) NOT NULL DEFAULT '' COMMENT 'The unique identifier for the result that was chosen',
`user_id` bigint NULL COMMENT 'The user that chose the result',
`location` CHAR(255) NULL DEFAULT NULL COMMENT 'Sender location, only for bots that require user location',
`inline_message_id` CHAR(255) NULL DEFAULT NULL COMMENT 'Identifier of the sent inline message',
`query` TEXT NOT NULL COMMENT 'The query that was used to obtain the result',
`created_at` timestamp NULL DEFAULT NULL COMMENT 'Entry date creation',
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`),
FOREIGN KEY (`user_id`) REFERENCES bot_user (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci;
CREATE TABLE IF NOT EXISTS bot_message (
`chat_id` bigint COMMENT 'Unique chat identifier',
`sender_chat_id` bigint COMMENT 'Sender of the message, sent on behalf of a chat',
`id` bigint UNSIGNED COMMENT 'Unique message identifier',
`user_id` bigint NULL COMMENT 'Unique user identifier',
`date` timestamp NULL DEFAULT NULL COMMENT 'Date the message was sent in timestamp format',
`forward_from` bigint NULL DEFAULT NULL COMMENT 'Unique user identifier, sender of the original message',
`forward_from_chat` bigint NULL DEFAULT NULL COMMENT 'Unique chat identifier, chat the original message belongs to',
`forward_from_message_id` bigint NULL DEFAULT NULL COMMENT 'Unique chat identifier of the original message in the channel',
`forward_signature` TEXT NULL DEFAULT NULL COMMENT 'For messages forwarded from channels, signature of the post author if present',
`forward_sender_name` TEXT NULL DEFAULT NULL COMMENT 'Sender''s name for messages forwarded from users who disallow adding a link to their account in forwarded messages',
`forward_date` timestamp NULL DEFAULT NULL COMMENT 'date the original message was sent in timestamp format',
`reply_to_chat` bigint NULL DEFAULT NULL COMMENT 'Unique chat identifier',
`reply_to_message` bigint UNSIGNED DEFAULT NULL COMMENT 'Message that this message is reply to',
`via_bot` bigint NULL DEFAULT NULL COMMENT 'Optional. Bot through which the message was sent',
`edit_date` timestamp NULL DEFAULT NULL COMMENT 'Date the message was last edited in Unix time',
`media_group_id` TEXT COMMENT 'The unique identifier of a media message group this message belongs to',
`author_signature` TEXT COMMENT 'Signature of the post author for messages in channels',
`text` TEXT COMMENT 'For text messages, the actual UTF-8 text of the message max message length 4096 char utf8mb4',
`entities` TEXT COMMENT 'For text messages, special entities like usernames, URLs, bot commands, etc. that appear in the text',
`caption_entities` TEXT COMMENT 'For messages with a caption, special entities like usernames, URLs, bot commands, etc. that appear in the caption',
`audio` TEXT COMMENT 'Audio object. Message is an audio file, information about the file',
`document` TEXT COMMENT 'Document object. Message is a general file, information about the file',
`animation` TEXT COMMENT 'Message is an animation, information about the animation',
`game` TEXT COMMENT 'Game object. Message is a game, information about the game',
`photo` TEXT COMMENT 'Array of PhotoSize objects. Message is a photo, available sizes of the photo',
`sticker` TEXT COMMENT 'Sticker object. Message is a sticker, information about the sticker',
`video` TEXT COMMENT 'Video object. Message is a video, information about the video',
`voice` TEXT COMMENT 'Voice Object. Message is a Voice, information about the Voice',
`video_note` TEXT COMMENT 'VoiceNote Object. Message is a Video Note, information about the Video Note',
`caption` TEXT COMMENT 'For message with caption, the actual UTF-8 text of the caption',
`contact` TEXT COMMENT 'Contact object. Message is a shared contact, information about the contact',
`location` TEXT COMMENT 'Location object. Message is a shared location, information about the location',
`venue` TEXT COMMENT 'Venue object. Message is a Venue, information about the Venue',
`poll` TEXT COMMENT 'Poll object. Message is a native poll, information about the poll',
`dice` TEXT COMMENT 'Message is a dice with random value from 1 to 6',
`new_chat_members` TEXT COMMENT 'List of unique user identifiers, new member(s) were added to the group, information about them (one of these members may be the bot itself)',
`left_chat_member` bigint NULL DEFAULT NULL COMMENT 'Unique user identifier, a member was removed from the group, information about them (this member may be the bot itself)',
`new_chat_title` CHAR(255) DEFAULT NULL COMMENT 'A chat title was changed to this value',
`new_chat_photo` TEXT COMMENT 'Array of PhotoSize objects. A chat photo was change to this value',
`delete_chat_photo` tinyint(1) DEFAULT 0 COMMENT 'Informs that the chat photo was deleted',
`group_chat_created` tinyint(1) DEFAULT 0 COMMENT 'Informs that the group has been created',
`supergroup_chat_created` tinyint(1) DEFAULT 0 COMMENT 'Informs that the supergroup has been created',
`channel_chat_created` tinyint(1) DEFAULT 0 COMMENT 'Informs that the channel chat has been created',
`message_auto_delete_timer_changed` TEXT COMMENT 'MessageAutoDeleteTimerChanged object. Message is a service message: auto-delete timer settings changed in the chat',
`migrate_to_chat_id` bigint NULL DEFAULT NULL COMMENT 'Migrate to chat identifier. The group has been migrated to a supergroup with the specified identifier',
`migrate_from_chat_id` bigint NULL DEFAULT NULL COMMENT 'Migrate from chat identifier. The supergroup has been migrated from a group with the specified identifier',
`pinned_message` TEXT NULL COMMENT 'Message object. Specified message was pinned',
`invoice` TEXT NULL COMMENT 'Message is an invoice for a payment, information about the invoice',
`successful_payment` TEXT NULL COMMENT 'Message is a service message about a successful payment, information about the payment',
`connected_website` TEXT NULL COMMENT 'The domain name of the website on which the user has logged in.',
`passport_data` TEXT NULL COMMENT 'Telegram Passport data',
`proximity_alert_triggered` TEXT NULL COMMENT 'Service message. A user in the chat triggered another user''s proximity alert while sharing Live Location.',
`voice_chat_scheduled` TEXT COMMENT 'VoiceChatScheduled object. Message is a service message: voice chat scheduled',
`voice_chat_started` TEXT COMMENT 'VoiceChatStarted object. Message is a service message: voice chat started',
`voice_chat_ended` TEXT COMMENT 'VoiceChatEnded object. Message is a service message: voice chat ended',
`voice_chat_participants_invited` TEXT COMMENT 'VoiceChatParticipantsInvited object. Message is a service message: new participants invited to a voice chat',
`reply_markup` TEXT NULL COMMENT 'Inline keyboard attached to the message',
PRIMARY KEY (`chat_id`, `id`),
KEY `user_id` (`user_id`),
KEY `forward_from` (`forward_from`),
KEY `forward_from_chat` (`forward_from_chat`),
KEY `reply_to_chat` (`reply_to_chat`),
KEY `reply_to_message` (`reply_to_message`),
KEY `via_bot` (`via_bot`),
KEY `left_chat_member` (`left_chat_member`),
KEY `migrate_from_chat_id` (`migrate_from_chat_id`),
KEY `migrate_to_chat_id` (`migrate_to_chat_id`),
FOREIGN KEY (`user_id`) REFERENCES bot_user (`id`),
FOREIGN KEY (`chat_id`) REFERENCES bot_chat (`id`),
FOREIGN KEY (`forward_from`) REFERENCES bot_user (`id`),
FOREIGN KEY (`forward_from_chat`) REFERENCES bot_chat (`id`),
FOREIGN KEY (`reply_to_chat`, `reply_to_message`) REFERENCES bot_message (`chat_id`, `id`),
FOREIGN KEY (`via_bot`) REFERENCES bot_user (`id`),
FOREIGN KEY (`left_chat_member`) REFERENCES bot_user (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci;
CREATE TABLE IF NOT EXISTS bot_edited_message (
`id` bigint UNSIGNED AUTO_INCREMENT COMMENT 'Unique identifier for this entry',
`chat_id` bigint COMMENT 'Unique chat identifier',
`message_id` bigint UNSIGNED COMMENT 'Unique message identifier',
`user_id` bigint NULL COMMENT 'Unique user identifier',
`edit_date` timestamp NULL DEFAULT NULL COMMENT 'Date the message was edited in timestamp format',
`text` TEXT COMMENT 'For text messages, the actual UTF-8 text of the message max message length 4096 char utf8',
`entities` TEXT COMMENT 'For text messages, special entities like usernames, URLs, bot commands, etc. that appear in the text',
`caption` TEXT COMMENT 'For message with caption, the actual UTF-8 text of the caption',
PRIMARY KEY (`id`),
KEY `chat_id` (`chat_id`),
KEY `message_id` (`message_id`),
KEY `user_id` (`user_id`),
FOREIGN KEY (`chat_id`) REFERENCES bot_chat (`id`),
FOREIGN KEY (`chat_id`, `message_id`) REFERENCES bot_message (`chat_id`, `id`),
FOREIGN KEY (`user_id`) REFERENCES bot_user (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci;
CREATE TABLE IF NOT EXISTS bot_callback_query (
`id` bigint UNSIGNED COMMENT 'Unique identifier for this query',
`user_id` bigint NULL COMMENT 'Unique user identifier',
`chat_id` bigint NULL COMMENT 'Unique chat identifier',
`message_id` bigint UNSIGNED COMMENT 'Unique message identifier',
`inline_message_id` CHAR(255) NULL DEFAULT NULL COMMENT 'Identifier of the message sent via the bot in inline mode, that originated the query',
`chat_instance` CHAR(255) NOT NULL DEFAULT '' COMMENT 'Global identifier, uniquely corresponding to the chat to which the message with the callback button was sent',
`data` CHAR(255) NOT NULL DEFAULT '' COMMENT 'Data associated with the callback button',
`game_short_name` CHAR(255) NOT NULL DEFAULT '' COMMENT 'Short name of a Game to be returned, serves as the unique identifier for the game',
`created_at` timestamp NULL DEFAULT NULL COMMENT 'Entry date creation',
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`),
KEY `chat_id` (`chat_id`),
KEY `message_id` (`message_id`),
FOREIGN KEY (`user_id`) REFERENCES bot_user (`id`),
FOREIGN KEY (`chat_id`, `message_id`) REFERENCES bot_message (`chat_id`, `id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci;
CREATE TABLE IF NOT EXISTS bot_shipping_query (
`id` bigint UNSIGNED COMMENT 'Unique query identifier',
`user_id` bigint COMMENT 'User who sent the query',
`invoice_payload` CHAR(255) NOT NULL DEFAULT '' COMMENT 'Bot specified invoice payload',
`shipping_address` CHAR(255) NOT NULL DEFAULT '' COMMENT 'User specified shipping address',
`created_at` timestamp NULL DEFAULT NULL COMMENT 'Entry date creation',
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`),
FOREIGN KEY (`user_id`) REFERENCES bot_user (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci;
CREATE TABLE IF NOT EXISTS bot_pre_checkout_query (
`id` bigint UNSIGNED COMMENT 'Unique query identifier',
`user_id` bigint COMMENT 'User who sent the query',
`currency` CHAR(3) COMMENT 'Three-letter ISO 4217 currency code',
`total_amount` bigint COMMENT 'Total price in the smallest units of the currency',
`invoice_payload` CHAR(255) NOT NULL DEFAULT '' COMMENT 'Bot specified invoice payload',
`shipping_option_id` CHAR(255) NULL COMMENT 'Identifier of the shipping option chosen by the user',
`order_info` TEXT NULL COMMENT 'Order info provided by the user',
`created_at` timestamp NULL DEFAULT NULL COMMENT 'Entry date creation',
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`),
FOREIGN KEY (`user_id`) REFERENCES bot_user (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci;
CREATE TABLE IF NOT EXISTS bot_poll (
`id` bigint UNSIGNED COMMENT 'Unique poll identifier',
`question` text NOT NULL COMMENT 'Poll question',
`options` text NOT NULL COMMENT 'List of poll options',
`total_voter_count` int UNSIGNED COMMENT 'Total number of users that voted in the poll',
`is_closed` tinyint(1) DEFAULT 0 COMMENT 'True, if the poll is closed',
`is_anonymous` tinyint(1) DEFAULT 1 COMMENT 'True, if the poll is anonymous',
`type` char(255) COMMENT 'Poll type, currently can be “regular” or “quiz”',
`allows_multiple_answers` tinyint(1) DEFAULT 0 COMMENT 'True, if the poll allows multiple answers',
`correct_option_id` int UNSIGNED COMMENT '0-based identifier of the correct answer option. Available only for polls in the quiz mode, which are closed, or was sent (not forwarded) by the bot or to the private chat with the bot.',
`explanation` varchar(255) DEFAULT NULL COMMENT 'Text that is shown when a user chooses an incorrect answer or taps on the lamp icon in a quiz-style poll, 0-200 characters',
`explanation_entities` text DEFAULT NULL COMMENT 'Special entities like usernames, URLs, bot commands, etc. that appear in the explanation',
`open_period` int UNSIGNED DEFAULT NULL COMMENT 'Amount of time in seconds the poll will be active after creation',
`close_date` timestamp NULL DEFAULT NULL COMMENT 'Point in time (Unix timestamp) when the poll will be automatically closed',
`created_at` timestamp NULL DEFAULT NULL COMMENT 'Entry date creation',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci;
CREATE TABLE IF NOT EXISTS bot_poll_answer (
`poll_id` bigint UNSIGNED COMMENT 'Unique poll identifier',
`user_id` bigint NOT NULL COMMENT 'The user, who changed the answer to the poll',
`option_ids` text NOT NULL COMMENT '0-based identifiers of answer options, chosen by the user. May be empty if the user retracted their vote.',
`created_at` timestamp NULL DEFAULT NULL COMMENT 'Entry date creation',
PRIMARY KEY (`poll_id`, `user_id`),
FOREIGN KEY (`poll_id`) REFERENCES bot_poll (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci;
CREATE TABLE IF NOT EXISTS bot_chat_member_updated (
`id` BIGINT UNSIGNED AUTO_INCREMENT COMMENT 'Unique identifier for this entry',
`chat_id` BIGINT NOT NULL COMMENT 'Chat the user belongs to',
`user_id` BIGINT NOT NULL COMMENT 'Performer of the action, which resulted in the change',
`date` TIMESTAMP NOT NULL COMMENT 'Date the change was done in Unix time',
`old_chat_member` TEXT NOT NULL COMMENT 'Previous information about the chat member',
`new_chat_member` TEXT NOT NULL COMMENT 'New information about the chat member',
`invite_link` TEXT NULL COMMENT 'Chat invite link, which was used by the user to join the chat; for joining by invite link events only',
`created_at` timestamp NULL DEFAULT NULL COMMENT 'Entry date creation',
PRIMARY KEY (`id`),
FOREIGN KEY (`chat_id`) REFERENCES bot_chat (`id`),
FOREIGN KEY (`user_id`) REFERENCES bot_user (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci;
CREATE TABLE IF NOT EXISTS bot_telegram_update (
`id` bigint UNSIGNED COMMENT 'Update''s unique identifier',
`chat_id` bigint NULL DEFAULT NULL COMMENT 'Unique chat identifier',
`message_id` bigint UNSIGNED DEFAULT NULL COMMENT 'New incoming message of any kind - text, photo, sticker, etc.',
`edited_message_id` bigint UNSIGNED DEFAULT NULL COMMENT 'New version of a message that is known to the bot and was edited',
`channel_post_id` bigint UNSIGNED DEFAULT NULL COMMENT 'New incoming channel post of any kind - text, photo, sticker, etc.',
`edited_channel_post_id` bigint UNSIGNED DEFAULT NULL COMMENT 'New version of a channel post that is known to the bot and was edited',
`inline_query_id` bigint UNSIGNED DEFAULT NULL COMMENT 'New incoming inline query',
`chosen_inline_result_id` bigint UNSIGNED DEFAULT NULL COMMENT 'The result of an inline query that was chosen by a user and sent to their chat partner',
`callback_query_id` bigint UNSIGNED DEFAULT NULL COMMENT 'New incoming callback query',
`shipping_query_id` bigint UNSIGNED DEFAULT NULL COMMENT 'New incoming shipping query. Only for invoices with flexible price',
`pre_checkout_query_id` bigint UNSIGNED DEFAULT NULL COMMENT 'New incoming pre-checkout query. Contains full information about checkout',
`poll_id` bigint UNSIGNED DEFAULT NULL COMMENT 'New poll state. Bots receive only updates about polls, which are sent or stopped by the bot',
`poll_answer_poll_id` bigint UNSIGNED DEFAULT NULL COMMENT 'A user changed their answer in a non-anonymous poll. Bots receive new votes only in polls that were sent by the bot itself.',
`my_chat_member_updated_id` BIGINT UNSIGNED NULL COMMENT 'The bot''s chat member status was updated in a chat. For private chats, this update is received only when the bot is blocked or unblocked by the user.',
`chat_member_updated_id` BIGINT UNSIGNED NULL COMMENT 'A chat member''s status was updated in a chat. The bot must be an administrator in the chat and must explicitly specify “chat_member” in the list of allowed_updates to receive these updates.',
PRIMARY KEY (`id`),
KEY `message_id` (`message_id`),
KEY `chat_message_id` (`chat_id`, `message_id`),
KEY `edited_message_id` (`edited_message_id`),
KEY `channel_post_id` (`channel_post_id`),
KEY `edited_channel_post_id` (`edited_channel_post_id`),
KEY `inline_query_id` (`inline_query_id`),
KEY `chosen_inline_result_id` (`chosen_inline_result_id`),
KEY `callback_query_id` (`callback_query_id`),
KEY `shipping_query_id` (`shipping_query_id`),
KEY `pre_checkout_query_id` (`pre_checkout_query_id`),
KEY `poll_id` (`poll_id`),
KEY `poll_answer_poll_id` (`poll_answer_poll_id`),
KEY `my_chat_member_updated_id` (`my_chat_member_updated_id`),
KEY `chat_member_updated_id` (`chat_member_updated_id`),
FOREIGN KEY (`chat_id`, `message_id`) REFERENCES bot_message (`chat_id`, `id`),
FOREIGN KEY (`edited_message_id`) REFERENCES bot_edited_message (`id`),
FOREIGN KEY (`chat_id`, `channel_post_id`) REFERENCES bot_message (`chat_id`, `id`),
FOREIGN KEY (`edited_channel_post_id`) REFERENCES bot_edited_message (`id`),
FOREIGN KEY (`inline_query_id`) REFERENCES bot_inline_query (`id`),
FOREIGN KEY (`chosen_inline_result_id`) REFERENCES bot_chosen_inline_result (`id`),
FOREIGN KEY (`callback_query_id`) REFERENCES bot_callback_query (`id`),
FOREIGN KEY (`shipping_query_id`) REFERENCES bot_shipping_query (`id`),
FOREIGN KEY (`pre_checkout_query_id`) REFERENCES bot_pre_checkout_query (`id`),
FOREIGN KEY (`poll_id`) REFERENCES bot_poll (`id`),
FOREIGN KEY (`poll_answer_poll_id`) REFERENCES bot_poll_answer (`poll_id`),
FOREIGN KEY (`my_chat_member_updated_id`) REFERENCES bot_chat_member_updated (`id`),
FOREIGN KEY (`chat_member_updated_id`) REFERENCES bot_chat_member_updated (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci;
CREATE TABLE IF NOT EXISTS bot_conversation (
`id` bigint(20) unsigned AUTO_INCREMENT COMMENT 'Unique identifier for this entry',
`user_id` bigint NULL DEFAULT NULL COMMENT 'Unique user identifier',
`chat_id` bigint NULL DEFAULT NULL COMMENT 'Unique user or chat identifier',
`status` ENUM('active', 'cancelled', 'stopped') NOT NULL DEFAULT 'active' COMMENT 'Conversation state',
`command` varchar(160) DEFAULT '' COMMENT 'Default command to execute',
`notes` text DEFAULT NULL COMMENT 'Data stored from command',
`created_at` timestamp NULL DEFAULT NULL COMMENT 'Entry date creation',
`updated_at` timestamp NULL DEFAULT NULL COMMENT 'Entry date update',
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`),
KEY `chat_id` (`chat_id`),
KEY `status` (`status`),
FOREIGN KEY (`user_id`) REFERENCES bot_user (`id`),
FOREIGN KEY (`chat_id`) REFERENCES bot_chat (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci;
CREATE TABLE IF NOT EXISTS bot_request_limiter (
`id` bigint UNSIGNED AUTO_INCREMENT COMMENT 'Unique identifier for this entry',
`chat_id` char(255) NULL DEFAULT NULL COMMENT 'Unique chat identifier',
`inline_message_id` char(255) NULL DEFAULT NULL COMMENT 'Identifier of the sent inline message',
`method` char(255) DEFAULT NULL COMMENT 'Request method',
`created_at` timestamp NULL DEFAULT NULL COMMENT 'Entry date creation',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci;
================================================
FILE: license.md
================================================
# The license
MIT License
Copyright (c) 2022 [PHP Telegram Bot](https://github.com/php-telegram-bot)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
================================================
FILE: phpunit.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="vendor/autoload.php"
backupGlobals="false"
backupStaticAttributes="false"
colors="true"
verbose="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false">
<testsuites>
<testsuite name="Package">
<directory suffix=".php">./tests/</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory>src/</directory>
</whitelist>
</filter>
</phpunit>
================================================
FILE: readme.md
================================================
# LaravelTelegramBot
[![Latest Version on Packagist][ico-version]][link-packagist]
[![Total Downloads][ico-downloads]][link-downloads]
## Installation
Install this package through Composer. Run this command in your project's terminal:
``` bash
composer require php-telegram-bot/laravel
```
Execute the following command to publish the folder structure to your Laravel application:
```bash
php artisan telegram:publish
```
This also includes a dummy `/start` command to give you a quick start.
Since we're using the database part of php-telegram-bot you should run the migrations so the database schema gets installed:
```bash
php artisan migrate
```
And add the following lines to your .env file:
```dotenv
TELEGRAM_API_TOKEN=
TELEGRAM_BOT_USERNAME=
TELEGRAM_API_URL=
TELEGRAM_ADMINS=
```
`TELEGRAM_API_TOKEN` and `TELEGRAM_BOT_USERNAME` should be filled with the corresponding data from [@BotFather](https://t.me/BotFather)
`TELEGRAM_API_URL` is optional and can be filled with the URL to your [custom Bot API Server](https://core.telegram.org/bots/api#using-a-local-bot-api-server) if you want to use one.
`TELEGRAM_ADMINS` is optional and a comma-separated list of Telegram User IDs that gets passed to the `enableAdmins` command of php-telegram-bot to enable admin commands for those users.
After that you can run `php artisan telegram:set-webhook` if your development server is reachable from the outside or you're using a custom bot api server.
Or `php artisan telegram:fetch` to start fetching your updates via polling.
⚠️ Be aware that you have to cancel and restart the `telegram:fetch` command, if you change your code.
## Usage
For further basic configuration of this Laravel package you do not need to create any configuration files.
Artisan terminal commands for the Webhook usage (remember, that you need an HTTPS server for it):
``` bash
# Use this method to specify a url and receive incoming updates via an outgoing webhook
php artisan telegram:set-webhook
# List of available options:
# --d|drop-pending-updates : Drop all pending updates
# --a|all-update-types : Explicitly allow all updates (including "chat_member")
# --allowed-updates= : Define allowed updates (comma-seperated)
# Use this method to remove webhook integration if you decide to switch back to getUpdates
php artisan telegram:delete-webhook
# List of available options:
# --d|drop-pending-updates : Pass to drop all pending updates
```
Artisan terminal commands for the Telegram getUpdates method:
``` bash
# Fetches Telegram updates periodically
php artisan telegram:fetch
# List of available options:
# --a|all-update-types : Explicitly allow all updates (including "chat_member")
# --allowed-updates= : Define allowed updates (comma-seperated)
```
Artisan terminal command for Telegram Server logging out:
``` bash
# Sends a logout to the currently registered Telegram Server
php artisan telegram:logout
```
Artisan terminal command for closing Telegram Server:
``` bash
# Sends a close to the currently registered Telegram Server
php artisan telegram:close
```
Artisan terminal command for publishing Telegram command folder structure in your project:
``` bash
# Publishes folder structure for Telegram Commands
# Default StartCommand class will be created
php artisan telegram:publish
```
Artisan terminal command for creating new Telegram command class in your project:
``` bash
# Create a new Telegram Bot Command class
# e.g. php artisan make:telegram-command Menu --> will make User command class MenuCommand
# e.g. php artisan make:telegram-command Genericmessage --system --> will make System command class GenericmessageCommand
php artisan make:telegram-command
# List of available options:
# name : Name of the Telegram Command
# --a|admin : Generate a AdminCommand
# --s|system : Generate a SystemCommand
# Without admin or system option default User command will be created
```
## Credits
- [Avtandil Kikabidze aka LONGMAN](https://github.com/akalongman)
- [TiiFuchs](https://github.com/TiiFuchs)
- [All Contributors][link-contributors]
## License
Please see the [license file](license.md) for more information.
[ico-version]: https://img.shields.io/packagist/v/php-telegram-bot/laravel.svg?style=flat-square
[ico-downloads]: https://img.shields.io/packagist/dt/php-telegram-bot/laravel.svg?style=flat-square
[link-packagist]: https://packagist.org/packages/php-telegram-bot/laravel
[link-downloads]: https://packagist.org/packages/php-telegram-bot/laravel
[link-contributors]: https://github.com/php-telegram-bot/laravel/contributors
================================================
FILE: routes/telegram.php
================================================
<?php
Route::post('/api/telegram/webhook/{token}', static function (\Longman\TelegramBot\Telegram $bot, $token) {
if ($token != config('telegram.bot.api_token')) {
abort(400);
}
$bot->handle();
})->middleware('telegram.network')->name('telegram.webhook');
================================================
FILE: src/Console/Commands/GeneratorCommand.php
================================================
<?php
namespace PhpTelegramBot\Laravel\Console\Commands;
use Illuminate\Console\Command;
abstract class GeneratorCommand extends Command
{
protected function publish(string $source, string $destination, array $replacements = [], bool $overwrite = false) : bool
{
if (file_exists($destination) && ! $overwrite) {
$basename = basename($destination);
$this->error("{$basename} already exists!");
return false;
}
$content = file_get_contents($source);
$content = $this->replacePlaceholder($content, $replacements);
file_put_contents($destination, $content);
return true;
}
protected function replacePlaceholder(string $content, array $replacements): string
{
foreach ($replacements as $from => $to) {
$content = str_replace($from, $to, $content);
}
return $content;
}
protected function getRootNamespace(): string
{
return rtrim($this->laravel->getNamespace(), '\\');
}
}
================================================
FILE: src/Console/Commands/MakeTelegramCommand.php
================================================
<?php
namespace PhpTelegramBot\Laravel\Console\Commands;
use Illuminate\Support\Str;
class MakeTelegramCommand extends GeneratorCommand
{
protected $signature = 'make:telegram-command
{name : Name of the Telegram Command}
{--a|admin : Generate a AdminCommand}
{--s|system : Generate a SystemCommand}';
protected $description = 'Create a new Telegram Bot Command class';
/*
* DummyNamespace
* DummyParent
* DummyClass
* {{name}}
*/
public function handle()
{
$name = $this->argument('name'); // start
if (Str::endsWith($name, ['Command', 'command'])) {
$name = (string) Str::of($name)->substr(0, -7)->lower();
} else {
$name = Str::lower($name);
}
$class = Str::studly($name) . 'Command';
$success = $this->publish(
__DIR__ . '/stubs/telegram-command.stub',
app_path("Telegram/Commands/{$class}.php"),
[
'DummyNamespace' => $this->getRootNamespace(),
'DummyParent' => $this->getParentClassName(),
'DummyClass' => $class,
'{{name}}' => $name
]
);
if ($success) {
$this->info('Telegram Command created successfully');
}
}
protected function getParentClassName()
{
if ($this->option('admin')) {
return 'AdminCommand';
}
if ($this->option('system')) {
return 'SystemCommand';
}
return 'UserCommand';
}
}
================================================
FILE: src/Console/Commands/TelegramCloseCommand.php
================================================
<?php
namespace PhpTelegramBot\Laravel\Console\Commands;
use Illuminate\Console\Command;
use Longman\TelegramBot\Request;
use Longman\TelegramBot\Telegram;
class TelegramCloseCommand extends Command
{
protected $signature = 'telegram:close';
protected $description = 'Sends a close to the currently registered Telegram Server';
public function handle(Telegram $bot)
{
$response = Request::close();
if (! $response->isOk()) {
$this->error($response->getDescription());
}
$this->info($response->getDescription());
}
}
================================================
FILE: src/Console/Commands/TelegramDeleteWebhookCommand.php
================================================
<?php
namespace PhpTelegramBot\Laravel\Console\Commands;
use Illuminate\Console\Command;
use Longman\TelegramBot\Request;
use Longman\TelegramBot\Telegram;
class TelegramDeleteWebhookCommand extends Command
{
protected $signature = 'telegram:delete-webhook
{--d|drop-pending-updates : Pass to drop all pending updates}';
protected $description = 'Use this method to remove webhook integration if you decide to switch back to getUpdates';
public function handle(Telegram $bot)
{
$options = [];
if ($this->option('drop-pending-updates')) {
$options['drop_pending_updates'] = true;
}
$response = Request::deleteWebhook($options);
if (! $response->isOk()) {
$this->error($response->getDescription());
}
$this->info($response->getDescription());
}
}
================================================
FILE: src/Console/Commands/TelegramFetchCommand.php
================================================
<?php
namespace PhpTelegramBot\Laravel\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Str;
use Longman\TelegramBot\Entities\Update;
use Longman\TelegramBot\Exception\TelegramException;
use Longman\TelegramBot\Telegram;
use Symfony\Component\Console\Command\SignalableCommandInterface;
class TelegramFetchCommand extends Command implements SignalableCommandInterface
{
protected $signature = 'telegram:fetch
{--a|all-update-types : Explicitly allow all updates (including "chat_member")}
{--allowed-updates= : Define allowed updates (comma-seperated)}';
protected $description = 'Fetches Telegram updates periodically';
protected bool $shallExit = false;
protected ?int $childPid = null;
public function handle(Telegram $bot)
{
$this->callSilent('telegram:delete-webhook');
$options = [
'timeout' => 30
];
// allowed_updates
if ($this->option('all-update-types')) {
$options['allowed_updates'] = Update::getUpdateTypes();
} elseif ($allowedUpdates = $this->option('allowed-updates')) {
$options['allowed_updates'] = Str::of($allowedUpdates)->explode(',');
}
$this->info("Start fetching updates...\n<comment>(Exit with Ctrl + C)</comment>");
if ($this->childPid = pcntl_fork()) {
// Parent process
while (true) {
if ($this->shallExit) {
exec('kill -9 ' . $this->childPid);
break;
}
}
} else {
// Child process
while (true) {
$response = rescue(fn() => $bot->handleGetUpdates($options));
if ($response !== null && ! $response->isOk()) {
$this->error($response->getDescription());
}
}
}
}
public function getSubscribedSignals(): array
{
return [SIGINT];
}
public function handleSignal(int $signal, int|false $previousExitCode = 0): int|false
{
$this->shallExit = true;
}
}
================================================
FILE: src/Console/Commands/TelegramLogoutCommand.php
================================================
<?php
namespace PhpTelegramBot\Laravel\Console\Commands;
use Illuminate\Console\Command;
use Longman\TelegramBot\Request;
use Longman\TelegramBot\Telegram;
class TelegramLogoutCommand extends Command
{
protected $signature = 'telegram:logout';
protected $description = 'Sends a logout to the currently registered Telegram Server';
public function handle(Telegram $bot)
{
$response = Request::logOut();
if (! $response->isOk()) {
$this->error($response->getDescription());
}
$this->info($response->getDescription());
}
}
================================================
FILE: src/Console/Commands/TelegramPublishCommand.php
================================================
<?php
namespace PhpTelegramBot\Laravel\Console\Commands;
use Illuminate\Filesystem\Filesystem;
class TelegramPublishCommand extends GeneratorCommand
{
protected $signature = 'telegram:publish';
protected $description = 'Publishes folder structure for Telegram Commands';
public function handle()
{
(new Filesystem())->ensureDirectoryExists(app_path('Telegram/Commands'));
$success = $this->publish(
__DIR__ . '/stubs/example-start-command.stub',
app_path('Telegram/Commands/StartCommand.php'),
[
'DummyRootNamespace' => $this->getRootNamespace(),
]
);
if ($success) {
$this->info('Publishing complete.');
}
}
}
================================================
FILE: src/Console/Commands/TelegramSetWebhookCommand.php
================================================
<?php
namespace PhpTelegramBot\Laravel\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Str;
use Longman\TelegramBot\Entities\Update;
use Longman\TelegramBot\Telegram;
class TelegramSetWebhookCommand extends Command
{
protected $signature = 'telegram:set-webhook
{hostname? : Hostname to set}
{--d|drop-pending-updates : Drop all pending updates}
{--a|all-update-types : Explicitly allow all updates (including "chat_member")}
{--allowed-updates= : Define allowed updates (comma-seperated)}';
protected $description = 'Use this method to specify a url and receive incoming updates via an outgoing webhook';
public function handle(Telegram $bot)
{
$hostname = $this->argument('hostname');
if (! $hostname) {
$hostname = $this->ask('Which hostname do you like to set?', config('app.url'));
}
if (! Str::of($hostname)->startsWith('http')) {
$schema = match (app()->environment()) {
'local' => 'http',
default => 'https'
};
$hostname = "{$schema}://{$hostname}";
}
$url = $hostname . route('telegram.webhook', [
'token' => config('telegram.bot.api_token')
], false);
$options = [];
if ($this->option('drop-pending-updates')) {
$options['drop_pending_updates'] = true;
}
if ($this->option('all-update-types')) {
$options['allowed_updates'] = Update::getUpdateTypes();
} elseif ($allowedUpdates = $this->option('allowed-updates')) {
$options['allowed_updates'] = Str::of($allowedUpdates)->explode(',');
}
$response = $bot->setWebhook($url, $options);
if (! $response->isOk()) {
$this->error($response->getDescription());
}
$this->info("Telegram Webhook set to <comment>{$url}</comment>");
}
}
================================================
FILE: src/Console/Commands/stubs/example-start-command.stub
================================================
<?php
namespace DummyRootNamespace\Telegram\Commands;
use Longman\TelegramBot\Commands\UserCommand;
use Longman\TelegramBot\Entities\ServerResponse;
use Longman\TelegramBot\Exception\TelegramException;
class StartCommand extends UserCommand
{
/** @var string Command name */
protected $name = 'start';
/** @var string Command description */
protected $description = 'Start';
/** @var string Usage description */
protected $usage = '/start';
/** @var string Version */
protected $version = '1.0.0';
public function execute(): ServerResponse
{
return $this->replyToChat('Hello world! 👋');
}
}
================================================
FILE: src/Console/Commands/stubs/telegram-command.stub
================================================
<?php
namespace DummyNamespace\Telegram\Commands;
use Longman\TelegramBot\Commands\DummyParent;
use Longman\TelegramBot\Entities\ServerResponse;
use Longman\TelegramBot\Exception\TelegramException;
class DummyClass extends DummyParent
{
/** @var string Command name */
protected $name = '{{name}}';
/** @var string Command description */
protected $description = '';
/** @var string Usage description */
protected $usage = '/{{name}}';
/** @var string Version */
protected $version = '1.0.0';
public function execute(): ServerResponse
{
}
}
================================================
FILE: src/Facades/CallbackButton.php
================================================
<?php
namespace PhpTelegramBot\Laravel\Facades;
use Illuminate\Support\Facades\Facade;
class CallbackButton extends Facade
{
protected static function getFacadeAccessor()
{
return \PhpTelegramBot\Laravel\Factories\CallbackButton::class;
}
}
================================================
FILE: src/Facades/Telegram.php
================================================
<?php
namespace PhpTelegramBot\Laravel\Facades;
use Illuminate\Support\Facades\Facade;
use PhpTelegramBot\Laravel\LaravelTelegramBot;
class Telegram extends Facade
{
protected static function getFacadeAccessor()
{
return LaravelTelegramBot::class;
}
}
================================================
FILE: src/Factories/CallbackButton.php
================================================
<?php
namespace PhpTelegramBot\Laravel\Factories;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Str;
use Longman\TelegramBot\Entities\InlineKeyboardButton;
class CallbackButton
{
protected string $className;
protected array $data;
public function __call(string $name, array $arguments): self
{
// ->withXxxxx($value)
if (Str::startsWith($name, 'with')) {
$key = (string) Str::of($name)->after('with')->snake();
$value = head($arguments);
return $this->with($key, $value);
}
throw new \BadMethodCallException("Call to undefined method CallbackButton::{$name}()");
}
public function with(string $key, mixed $value): self
{
$this->data[$key] = $value;
return $this;
}
public function new(): self
{
return clone $this;
}
public function returnTo(string $className): self
{
$this->className = $className;
return $this;
}
public function make(string $text, array $payload = []): InlineKeyboardButton
{
// Find valid hash
do {
$hash = Str::random(32);
$cacheKey = 'CallbackQuery:'.$hash;
} while (Cache::has($cacheKey));
// Save payload
$payload = $payload + $this->data;
if (isset($this->className)) {
$payload['__class'] = $this->className;
}
Cache::put($cacheKey, $payload);
// Assemble button
return new InlineKeyboardButton([
'text' => $text,
'callback_data' => $hash
]);
}
}
================================================
FILE: src/Http/Middleware/TrustTelegramNetwork.php
================================================
<?php
namespace PhpTelegramBot\Laravel\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\App;
use Symfony\Component\HttpFoundation\IpUtils;
class TrustTelegramNetwork
{
/**
* Trusted Telegram IP addresses
* @see https://core.telegram.org/bots/webhooks#the-short-version
* @var array
*/
protected array $trustedIpNets = [
'149.154.160.0/20',
'91.108.4.0/22'
];
/**
* Local networks for debugging
* @var array|string[]
*/
protected array $localIpNets = [
'127.0.0.1/32',
'10.0.0.0/8',
'172.16.0.0/12',
'192.168.0.0/16'
];
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if (App::environment('local') && IpUtils::checkIp($request->ip(), $this->localIpNets)) {
return $next($request);
}
if (IpUtils::checkIp($request->ip(), $this->trustedIpNets)) {
return $next($request);
}
abort(403);
}
}
================================================
FILE: src/LaravelTelegramBot.php
================================================
<?php
namespace PhpTelegramBot\Laravel;
use Longman\TelegramBot\Entities\ServerResponse;
use Longman\TelegramBot\Entities\Update;
use Longman\TelegramBot\Request;
class LaravelTelegramBot
{
protected array $callbacks = [];
public function register(callable $callback)
{
$this->callbacks[] = $callback;
}
public function call(Update $update): ?ServerResponse
{
foreach ($this->callbacks as $callback) {
$return = $callback($update);
if ($return instanceof ServerResponse) {
return $return;
} elseif ($return === true) {
return Request::emptyResponse();
}
}
return null;
}
}
================================================
FILE: src/Telegram/Commands/CallbackqueryCommand.php
================================================
<?php
namespace PhpTelegramBot\Laravel\Telegram\Commands;
use Illuminate\Support\Facades\App;
use Longman\TelegramBot\Commands\Command;
use Longman\TelegramBot\Commands\SystemCommand;
use Longman\TelegramBot\Conversation;
use Longman\TelegramBot\Entities\ServerResponse;
use Longman\TelegramBot\Request;
use PhpTelegramBot\Laravel\Facades\Telegram;
use PhpTelegramBot\Laravel\Telegram\Conversation\ConversationWrapper;
use PhpTelegramBot\Laravel\Telegram\InlineKeyboardButton\RemembersCallbackPayload;
use PhpTelegramBot\Laravel\Telegram\UsesEffectiveEntities;
class CallbackqueryCommand extends SystemCommand
{
use RemembersCallbackPayload, UsesEffectiveEntities;
protected $name = 'callbackquery';
protected $description = 'Handles CallbackQueries';
protected $version = '1.0';
public function execute(): ServerResponse
{
$return = Telegram::call($this->getUpdate());
if ($return instanceof ServerResponse) {
return $return;
}
// Check if we have data for that hash in the Cache
if ($class = $this->payload()?->get('__class')) {
if (class_exists($class) && is_subclass_of($class, Command::class)) {
/** @var Command $command */
$command = new $class($this->telegram, $this->update);
return $command->preExecute();
}
}
// Check if conversation is active
$user = $this->getEffectiveUser($this->getUpdate());
$chat = $this->getEffectiveChat($this->getUpdate());
$conversation = new Conversation(
user_id: $user->getId(),
chat_id: $chat->getId()
);
if ($conversation->exists() && ($command = $conversation->getCommand())) {
return $this->getTelegram()->executeCommand($command);
}
// Check if own CallbackqueryCommand class is available
$class = App::getNamespace() . 'Telegram\\Commands\\CallbackqueryCommand';
if (class_exists($class) && is_subclass_of($class, SystemCommand::class)) {
/** @var SystemCommand $command */
$command = new $class($this->telegram, $this->update);
return $command->preExecute();
}
return Request::emptyResponse();
}
}
================================================
FILE: src/Telegram/Commands/GenericmessageCommand.php
================================================
<?php
namespace PhpTelegramBot\Laravel\Telegram\Commands;
use Illuminate\Support\Facades\App;
use Longman\TelegramBot\Commands\SystemCommand;
use Longman\TelegramBot\Conversation;
use Longman\TelegramBot\Entities\ServerResponse;
use Longman\TelegramBot\Request;
use PhpTelegramBot\Laravel\Facades\Telegram;
use PhpTelegramBot\Laravel\Telegram\Conversation\ConversationWrapper;
use PhpTelegramBot\Laravel\Telegram\UsesEffectiveEntities;
class GenericmessageCommand extends SystemCommand
{
use UsesEffectiveEntities;
protected $name = 'genericmessage';
protected $description = 'Handles Genericmessages';
protected $version = '1.0';
public function execute(): ServerResponse
{
$return = Telegram::call($this->getUpdate());
if ($return instanceof ServerResponse) {
return $return;
}
$user = $this->getEffectiveUser($this->getUpdate());
$chat = $this->getEffectiveChat($this->getUpdate());
// Check Conversation
$conversation = new Conversation(
user_id: $user->getId(),
chat_id: $chat->getId()
);
if ($conversation->exists() && ($command = $conversation->getCommand())) {
return $this->getTelegram()->executeCommand($command);
}
// Check if own GenericmessageCommand class is available
$class = App::getNamespace() . 'Telegram\\Commands\\GenericmessageCommand';
if (class_exists($class) && is_subclass_of($class, SystemCommand::class)) {
/** @var SystemCommand $command */
$command = new $class($this->telegram, $this->update);
return $command->preExecute();
}
return Request::emptyResponse();
}
}
================================================
FILE: src/Telegram/Conversation/ConversationWrapper.php
================================================
<?php
namespace PhpTelegramBot\Laravel\Telegram\Conversation;
use Longman\TelegramBot\Conversation;
use Longman\TelegramBot\Entities\Update;
class ConversationWrapper
{
protected Conversation $conversation;
protected array $temporary = [];
public function __construct(Update $update, $command = '')
{
if ($message = $update->getMessage() ?? $update->getEditedMessage()) {
$user = $message->getFrom();
$chat = $message->getChat();
} elseif ($callbackQuery = $update->getCallbackQuery()) {
$user = $callbackQuery->getFrom();
$chat = $callbackQuery->getMessage()?->getChat();
}
// TODO: Use getEffective*() Methods that should be created in \Bot Facade
if (! isset($user) || ! isset($chat)) {
throw new \InvalidArgumentException('Could not determine user or chat for ConversationWrapper');
}
$this->conversation = new Conversation(
user_id: $user->getId(),
chat_id: $chat->getId(),
command: $command
);
$notes = &$this->conversation->notes;
$notes['vars'] ??= [];
$notes['persist'] ??= [];
if ($this->conversation->exists()) {
// Remove temporary variables
foreach ($notes['vars'] as $key => $value) {
if (array_search($key, $notes['persist']) === false) {
// Is temporary
$this->temporary[$key] = $value;
unset($notes['vars'][$key]);
}
}
$this->conversation->update();
}
}
public function all(): array
{
return $this->conversation->notes['vars'] + $this->temporary;
}
public function get(string $key, string $default = null): mixed
{
return data_get($this->conversation->notes['vars'], $key)
?? data_get($this->temporary, $key, $default);
}
public function has(string $key): bool
{
return $this->get($key) !== null;
}
public function getConversation(): Conversation
{
return $this->conversation;
}
public function persist(array $data): self
{
$notes = &$this->conversation->notes;
foreach ($data as $key => $value) {
$notes['vars'][$key] = $value;
$notes['persist'][] = $key;
}
$this->conversation->update();
return $this;
}
public function remember(array $data = [], bool $keepPreviousData = false): self
{
$notes = &$this->conversation->notes;
if ($keepPreviousData) {
foreach ($this->temporary as $key => $value) {
$notes['vars'][$key] = $value;
}
}
foreach ($data as $key => $value) {
$notes['vars'][$key] = $value;
$index = array_search($key, $notes['persist']);
if ($index !== false) {
unset($notes['persist'][$index]);
}
}
$notes['persist'] = array_values($notes['persist']);
$this->conversation->update();
return $this;
}
public function exists(): bool
{
return $this->conversation->exists();
}
public function end(): void
{
$this->conversation->stop();
}
public function cancel(): void
{
$this->conversation->cancel();
}
}
================================================
FILE: src/Telegram/Conversation/LeadsConversation.php
================================================
<?php
namespace PhpTelegramBot\Laravel\Telegram\Conversation;
use Longman\TelegramBot\Entities\Update;
/**
* Trait LeadsConversation
* @package PhpTelegramBot\Laravel
* @method Update getUpdate()
* @method string getName()
*/
trait LeadsConversation
{
/**
* @internal
*/
protected ?ConversationWrapper $conversation;
/**
* @param string|null $key
* @param string|null $default
* @return ?ConversationWrapper|mixed
*/
protected function conversation(string $key = null, string $default = null)
{
if (! isset($this->conversation)) {
$this->conversation = new ConversationWrapper($this->getUpdate(), $this->getName());
}
if (isset($key)) {
return $this->conversation->get($key, $default);
}
return $this->conversation;
}
}
================================================
FILE: src/Telegram/InlineKeyboardButton/CallbackPayload.php
================================================
<?php
namespace PhpTelegramBot\Laravel\Telegram\InlineKeyboardButton;
class CallbackPayload
{
public function __construct(protected array $payload)
{
}
public function all(): array
{
return $this->payload;
}
public function get(string $key, string $default = null): mixed
{
return data_get($this->payload, $key, $default);
}
public function has(string $key): bool
{
return $this->get($key) !== null;
}
}
================================================
FILE: src/Telegram/InlineKeyboardButton/RemembersCallbackPayload.php
================================================
<?php
namespace PhpTelegramBot\Laravel\Telegram\InlineKeyboardButton;
use Illuminate\Support\Facades\Cache;
use Longman\TelegramBot\Commands\Command;
use Longman\TelegramBot\Entities\Update;
/**
* Trait CallbackQueryCache
* @package PhpTelegramBot\Laravel\Services
* @method Update getUpdate()
*/
trait RemembersCallbackPayload
{
/**
* @var CallbackPayload
* @internal
*/
protected ?CallbackPayload $payload;
/**
* @param string|null $key
* @param string|null $default
* @return CallbackPayload|null|mixed
*/
protected function payload(string $key = null, string $default = null)
{
if (! isset($this->payload)) {
$update = $this->getUpdate();
$data = $update?->getCallbackQuery()?->getData();
if ($data === null) {
return null;
}
// TODO: Move CacheKey and initialization in CallbackPayload::__construct()
$cacheKey = 'CallbackQuery:'.$data;
if (! Cache::has($cacheKey)) {
return null;
}
$payload = Cache::get($cacheKey);
$this->payload = new CallbackPayload($payload);
}
if (isset($key)) {
return $this->payload->get($key, $default);
}
return $this->payload;
}
}
================================================
FILE: src/Telegram/UsesEffectiveEntities.php
================================================
<?php
namespace PhpTelegramBot\Laravel\Telegram;
use Longman\TelegramBot\Entities\Chat;
use Longman\TelegramBot\Entities\Message;
use Longman\TelegramBot\Entities\Update;
use Longman\TelegramBot\Entities\User;
trait UsesEffectiveEntities
{
protected function getEffectiveUser(Update $update): ?User
{
$type = $update->getUpdateType();
$user = $update->$type['from']
?? $update->poll_answer['user']
?? null;
return $user ? new User($user) : null;
}
protected function getEffectiveChat(Update $update): ?Chat
{
$type = $update->getUpdateType();
$chat = $update->$type['chat']
?? $update->callback_query['message']['chat']
?? null;
return $chat ? new Chat($chat) : null;
}
protected function getEffectiveMessage(Update $update): ?Message
{
$message = $update->edited_channel_post
?? $update->channel_post
?? $update->callback_query['message']
?? $update->edited_message
?? $update->message
?? null;
return $message ? new Message($message) : null;
}
}
================================================
FILE: src/TelegramServiceProvider.php
================================================
<?php
namespace PhpTelegramBot\Laravel;
use Illuminate\Routing\Router;
use Illuminate\Support\Facades\File;
use Illuminate\Support\ServiceProvider;
use Longman\TelegramBot\Commands\Command;
use Longman\TelegramBot\Request;
use Longman\TelegramBot\Telegram;
use Symfony\Component\Finder\Finder;
use PhpTelegramBot\Laravel\Console\Commands\TelegramCloseCommand;
use PhpTelegramBot\Laravel\Console\Commands\TelegramDeleteWebhookCommand;
use PhpTelegramBot\Laravel\Console\Commands\TelegramFetchCommand;
use PhpTelegramBot\Laravel\Console\Commands\TelegramLogoutCommand;
use PhpTelegramBot\Laravel\Console\Commands\TelegramPublishCommand;
use PhpTelegramBot\Laravel\Console\Commands\TelegramSetWebhookCommand;
use PhpTelegramBot\Laravel\Console\Commands\MakeTelegramCommand;
use PhpTelegramBot\Laravel\Factories\CallbackButton;
use PhpTelegramBot\Laravel\Http\Middleware\TrustTelegramNetwork;
use PhpTelegramBot\Laravel\Telegram\Commands\CallbackqueryCommand;
use PhpTelegramBot\Laravel\Telegram\Commands\GenericmessageCommand;
class TelegramServiceProvider extends ServiceProvider
{
/**
* Perform post-registration booting of services.
*
* @return void
*/
public function boot(): void
{
$this->loadMigrationsFrom(__DIR__ . '/../database/migrations');
if (file_exists(base_path('routes/telegram.php'))) {
$this->loadRoutesFrom(base_path('routes/telegram.php'));
} else {
$this->loadRoutesFrom(__DIR__ . '/../routes/telegram.php');
}
$router = $this->app->make(Router::class);
$router->aliasMiddleware('telegram.network', TrustTelegramNetwork::class);
// Publishing is only necessary when using the CLI.
if ($this->app->runningInConsole()) {
$this->bootForConsole();
}
}
/**
* Register any package services.
*
* @return void
*/
public function register(): void
{
$this->mergeConfigFrom(__DIR__ . '/../config/telegram.php', 'telegram');
$this->configureTelegramBot();
}
protected function configureTelegramBot()
{
$token = config('telegram.bot.api_token');
if (! $token) {
return;
}
$username = config('telegram.bot.username');
$apiUrl = config('telegram.bot.api_url', '');
if (! empty($apiUrl)) {
Request::setCustomBotApiUri($apiUrl);
}
$bot = new Telegram($token, $username);
// Commands Discovery
$this->discoverTelegramCommands($bot);
$bot->addCommandClass(CallbackqueryCommand::class);
$bot->addCommandClass(GenericmessageCommand::class);
// Set MySQL Connection
$connection = app('db')->connection('mysql');
$bot->enableExternalMySql($connection->getPdo(), 'bot_');
// Register admins
$this->registerTelegramAdmins($bot);
$this->app->instance(Telegram::class, $bot);
}
/**
* Console-specific booting.
*
* @return void
*/
protected function bootForConsole(): void
{
// Publishing the configuration file.
$this->publishes([
__DIR__ . '/../config/telegram.php' => config_path('telegram.php'),
], 'telegram-config');
$this->publishes([
__DIR__ . '/../routes/telegram.php' => base_path('routes/telegram.php')
], 'telegram-routes');
// Registering package commands.
$this->commands([
MakeTelegramCommand::class,
TelegramCloseCommand::class,
TelegramDeleteWebhookCommand::class,
TelegramFetchCommand::class,
TelegramLogoutCommand::class,
TelegramPublishCommand::class,
TelegramSetWebhookCommand::class,
]);
}
/**
* @param Telegram $bot
* @throws \ReflectionException
*/
protected function discoverTelegramCommands(Telegram $bot): void
{
$namespace = $this->app->getNamespace();
$commandsPath = app_path('Telegram/Commands');
File::ensureDirectoryExists($commandsPath);
foreach ((new Finder)->in($commandsPath)->files() as $command) {
$command = $namespace . str_replace(
['/', '.php'],
['\\', ''],
\Str::after($command->getRealPath(), realpath(app_path()) . DIRECTORY_SEPARATOR)
);
if (is_subclass_of($command, Command::class) &&
! (new \ReflectionClass($command))->isAbstract()) {
$bot->addCommandClass($command);
}
}
}
/**
* @param Telegram $bot
*/
protected function registerTelegramAdmins(Telegram $bot): void
{
$admins = config('telegram.admins', '');
if (! empty($admins)) {
$admins = explode(',', $admins);
$bot->enableAdmins($admins);
}
}
}
gitextract_qf0nzb7c/
├── .gitignore
├── .styleci.yml
├── changelog.md
├── composer.json
├── config/
│ └── telegram.php
├── database/
│ └── migrations/
│ ├── 2021_06_14_171118_create_telegram_bot_structure.php
│ ├── 2022_02_18_175100_update_to_0.75.0.php
│ ├── 2022_04_24_175700_update_to_0.77.0.php
│ ├── 2022_10_04_221900_update_to_0.78.0.php
│ ├── 2022_11_11_130500_update_to_0.80.0.php
│ ├── 2023_05-07_101600_update_to_0.81.0.php
│ └── sql/
│ ├── 0.74.0-0.75.0.sql
│ ├── 0.76.1-0.77.0.sql
│ ├── 0.77.1-0.78.0.sql
│ ├── 0.79.0-0.80.0.sql
│ ├── 0.80.0-0.81.0.sql
│ └── structure-0.73.0.sql
├── license.md
├── phpunit.xml
├── readme.md
├── routes/
│ └── telegram.php
└── src/
├── Console/
│ └── Commands/
│ ├── GeneratorCommand.php
│ ├── MakeTelegramCommand.php
│ ├── TelegramCloseCommand.php
│ ├── TelegramDeleteWebhookCommand.php
│ ├── TelegramFetchCommand.php
│ ├── TelegramLogoutCommand.php
│ ├── TelegramPublishCommand.php
│ ├── TelegramSetWebhookCommand.php
│ └── stubs/
│ ├── example-start-command.stub
│ └── telegram-command.stub
├── Facades/
│ ├── CallbackButton.php
│ └── Telegram.php
├── Factories/
│ └── CallbackButton.php
├── Http/
│ └── Middleware/
│ └── TrustTelegramNetwork.php
├── LaravelTelegramBot.php
├── Telegram/
│ ├── Commands/
│ │ ├── CallbackqueryCommand.php
│ │ └── GenericmessageCommand.php
│ ├── Conversation/
│ │ ├── ConversationWrapper.php
│ │ └── LeadsConversation.php
│ ├── InlineKeyboardButton/
│ │ ├── CallbackPayload.php
│ │ └── RemembersCallbackPayload.php
│ └── UsesEffectiveEntities.php
└── TelegramServiceProvider.php
SYMBOL INDEX (100 symbols across 29 files)
FILE: database/migrations/2021_06_14_171118_create_telegram_bot_structure.php
method up (line 6) | public function up()
method down (line 11) | public function down()
FILE: database/migrations/2022_02_18_175100_update_to_0.75.0.php
method up (line 6) | public function up()
method down (line 11) | public function down()
FILE: database/migrations/2022_04_24_175700_update_to_0.77.0.php
method up (line 6) | public function up()
method down (line 11) | public function down()
FILE: database/migrations/2022_10_04_221900_update_to_0.78.0.php
method up (line 6) | public function up()
method down (line 11) | public function down()
FILE: database/migrations/2022_11_11_130500_update_to_0.80.0.php
method up (line 7) | public function up()
method down (line 12) | public function down()
FILE: database/migrations/2023_05-07_101600_update_to_0.81.0.php
method up (line 7) | public function up()
method down (line 12) | public function down()
FILE: database/migrations/sql/0.74.0-0.75.0.sql
type `bot_chat_join_request` (line 1) | CREATE TABLE IF NOT EXISTS `bot_chat_join_request` (
FILE: database/migrations/sql/structure-0.73.0.sql
type bot_user (line 1) | CREATE TABLE IF NOT EXISTS bot_user (
type bot_chat (line 15) | CREATE TABLE IF NOT EXISTS bot_chat (
type bot_user_chat (line 31) | CREATE TABLE IF NOT EXISTS bot_user_chat (
type bot_inline_query (line 41) | CREATE TABLE IF NOT EXISTS bot_inline_query (
type bot_chosen_inline_result (line 56) | CREATE TABLE IF NOT EXISTS bot_chosen_inline_result (
type bot_message (line 71) | CREATE TABLE IF NOT EXISTS bot_message (
type bot_edited_message (line 150) | CREATE TABLE IF NOT EXISTS bot_edited_message (
type bot_callback_query (line 170) | CREATE TABLE IF NOT EXISTS bot_callback_query (
type bot_shipping_query (line 190) | CREATE TABLE IF NOT EXISTS bot_shipping_query (
type bot_pre_checkout_query (line 203) | CREATE TABLE IF NOT EXISTS bot_pre_checkout_query (
type bot_poll (line 219) | CREATE TABLE IF NOT EXISTS bot_poll (
type bot_poll_answer (line 238) | CREATE TABLE IF NOT EXISTS bot_poll_answer (
type bot_chat_member_updated (line 248) | CREATE TABLE IF NOT EXISTS bot_chat_member_updated (
type bot_telegram_update (line 263) | CREATE TABLE IF NOT EXISTS bot_telegram_update (
type bot_conversation (line 311) | CREATE TABLE IF NOT EXISTS bot_conversation (
type bot_request_limiter (line 330) | CREATE TABLE IF NOT EXISTS bot_request_limiter (
FILE: src/Console/Commands/GeneratorCommand.php
class GeneratorCommand (line 9) | abstract class GeneratorCommand extends Command
method publish (line 12) | protected function publish(string $source, string $destination, array ...
method replacePlaceholder (line 27) | protected function replacePlaceholder(string $content, array $replacem...
method getRootNamespace (line 36) | protected function getRootNamespace(): string
FILE: src/Console/Commands/MakeTelegramCommand.php
class MakeTelegramCommand (line 7) | class MakeTelegramCommand extends GeneratorCommand
method handle (line 23) | public function handle()
method getParentClassName (line 51) | protected function getParentClassName()
FILE: src/Console/Commands/TelegramCloseCommand.php
class TelegramCloseCommand (line 9) | class TelegramCloseCommand extends Command
method handle (line 15) | public function handle(Telegram $bot)
FILE: src/Console/Commands/TelegramDeleteWebhookCommand.php
class TelegramDeleteWebhookCommand (line 9) | class TelegramDeleteWebhookCommand extends Command
method handle (line 16) | public function handle(Telegram $bot)
FILE: src/Console/Commands/TelegramFetchCommand.php
class TelegramFetchCommand (line 14) | class TelegramFetchCommand extends Command implements SignalableCommandI...
method handle (line 27) | public function handle(Telegram $bot)
method getSubscribedSignals (line 72) | public function getSubscribedSignals(): array
method handleSignal (line 77) | public function handleSignal(int $signal, int|false $previousExitCode ...
FILE: src/Console/Commands/TelegramLogoutCommand.php
class TelegramLogoutCommand (line 9) | class TelegramLogoutCommand extends Command
method handle (line 15) | public function handle(Telegram $bot)
FILE: src/Console/Commands/TelegramPublishCommand.php
class TelegramPublishCommand (line 7) | class TelegramPublishCommand extends GeneratorCommand
method handle (line 13) | public function handle()
FILE: src/Console/Commands/TelegramSetWebhookCommand.php
class TelegramSetWebhookCommand (line 10) | class TelegramSetWebhookCommand extends Command
method handle (line 20) | public function handle(Telegram $bot)
FILE: src/Facades/CallbackButton.php
class CallbackButton (line 9) | class CallbackButton extends Facade
method getFacadeAccessor (line 11) | protected static function getFacadeAccessor()
FILE: src/Facades/Telegram.php
class Telegram (line 8) | class Telegram extends Facade
method getFacadeAccessor (line 10) | protected static function getFacadeAccessor()
FILE: src/Factories/CallbackButton.php
class CallbackButton (line 11) | class CallbackButton
method __call (line 17) | public function __call(string $name, array $arguments): self
method with (line 30) | public function with(string $key, mixed $value): self
method new (line 36) | public function new(): self
method returnTo (line 41) | public function returnTo(string $className): self
method make (line 47) | public function make(string $text, array $payload = []): InlineKeyboar...
FILE: src/Http/Middleware/TrustTelegramNetwork.php
class TrustTelegramNetwork (line 9) | class TrustTelegramNetwork
method handle (line 40) | public function handle($request, Closure $next)
FILE: src/LaravelTelegramBot.php
class LaravelTelegramBot (line 9) | class LaravelTelegramBot
method register (line 14) | public function register(callable $callback)
method call (line 19) | public function call(Update $update): ?ServerResponse
FILE: src/Telegram/Commands/CallbackqueryCommand.php
class CallbackqueryCommand (line 18) | class CallbackqueryCommand extends SystemCommand
method execute (line 26) | public function execute(): ServerResponse
FILE: src/Telegram/Commands/GenericmessageCommand.php
class GenericmessageCommand (line 14) | class GenericmessageCommand extends SystemCommand
method execute (line 22) | public function execute(): ServerResponse
FILE: src/Telegram/Conversation/ConversationWrapper.php
class ConversationWrapper (line 8) | class ConversationWrapper
method __construct (line 14) | public function __construct(Update $update, $command = '')
method all (line 53) | public function all(): array
method get (line 58) | public function get(string $key, string $default = null): mixed
method has (line 64) | public function has(string $key): bool
method getConversation (line 69) | public function getConversation(): Conversation
method persist (line 74) | public function persist(array $data): self
method remember (line 86) | public function remember(array $data = [], bool $keepPreviousData = fa...
method exists (line 109) | public function exists(): bool
method end (line 114) | public function end(): void
method cancel (line 119) | public function cancel(): void
FILE: src/Telegram/Conversation/LeadsConversation.php
type LeadsConversation (line 14) | trait LeadsConversation
method conversation (line 27) | protected function conversation(string $key = null, string $default = ...
FILE: src/Telegram/InlineKeyboardButton/CallbackPayload.php
class CallbackPayload (line 7) | class CallbackPayload
method __construct (line 10) | public function __construct(protected array $payload)
method all (line 14) | public function all(): array
method get (line 19) | public function get(string $key, string $default = null): mixed
method has (line 24) | public function has(string $key): bool
FILE: src/Telegram/InlineKeyboardButton/RemembersCallbackPayload.php
type RemembersCallbackPayload (line 15) | trait RemembersCallbackPayload
method payload (line 28) | protected function payload(string $key = null, string $default = null)
FILE: src/Telegram/UsesEffectiveEntities.php
type UsesEffectiveEntities (line 10) | trait UsesEffectiveEntities
method getEffectiveUser (line 13) | protected function getEffectiveUser(Update $update): ?User
method getEffectiveChat (line 24) | protected function getEffectiveChat(Update $update): ?Chat
method getEffectiveMessage (line 35) | protected function getEffectiveMessage(Update $update): ?Message
FILE: src/TelegramServiceProvider.php
class TelegramServiceProvider (line 24) | class TelegramServiceProvider extends ServiceProvider
method boot (line 31) | public function boot(): void
method register (line 55) | public function register(): void
method configureTelegramBot (line 62) | protected function configureTelegramBot()
method bootForConsole (line 99) | protected function bootForConsole(): void
method discoverTelegramCommands (line 126) | protected function discoverTelegramCommands(Telegram $bot): void
method registerTelegramAdmins (line 149) | protected function registerTelegramAdmins(Telegram $bot): void
Condensed preview — 44 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (76K chars).
[
{
"path": ".gitignore",
"chars": 918,
"preview": "\n# Created by https://www.toptal.com/developers/gitignore/api/laravel,composer\n# Edit at https://www.toptal.com/develope"
},
{
"path": ".styleci.yml",
"chars": 15,
"preview": "preset: laravel"
},
{
"path": "changelog.md",
"chars": 229,
"preview": "# Changelog\n\nAll notable changes to `LaravelTelegramBot` will be documented in this file.\n\n## Version 2.1.0\n\n### Added\n-"
},
{
"path": "composer.json",
"chars": 1549,
"preview": "{\n \"name\": \"php-telegram-bot/laravel\",\n \"description\": \"Integrates PHP Telegram Bot into Laravel.\",\n \"license\":"
},
{
"path": "config/telegram.php",
"chars": 240,
"preview": "<?php\n\nreturn [\n 'bot' => [\n 'api_token' => env('TELEGRAM_API_TOKEN'),\n\n 'username' => env('TELEGRAM_BO"
},
{
"path": "database/migrations/2021_06_14_171118_create_telegram_bot_structure.php",
"chars": 264,
"preview": "<?php\n\nuse Illuminate\\Database\\Migrations\\Migration;\n\nreturn new class extends Migration {\n public function up()\n "
},
{
"path": "database/migrations/2022_02_18_175100_update_to_0.75.0.php",
"chars": 261,
"preview": "<?php\n\nuse Illuminate\\Database\\Migrations\\Migration;\n\nreturn new class extends Migration {\n public function up()\n "
},
{
"path": "database/migrations/2022_04_24_175700_update_to_0.77.0.php",
"chars": 261,
"preview": "<?php\n\nuse Illuminate\\Database\\Migrations\\Migration;\n\nreturn new class extends Migration {\n public function up()\n "
},
{
"path": "database/migrations/2022_10_04_221900_update_to_0.78.0.php",
"chars": 261,
"preview": "<?php\n\nuse Illuminate\\Database\\Migrations\\Migration;\n\nreturn new class extends Migration {\n public function up()\n "
},
{
"path": "database/migrations/2022_11_11_130500_update_to_0.80.0.php",
"chars": 296,
"preview": "<?php\n\nuse Illuminate\\Database\\Migrations\\Migration;\nuse Illuminate\\Support\\Facades\\DB;\n\nreturn new class extends Migrat"
},
{
"path": "database/migrations/2023_05-07_101600_update_to_0.81.0.php",
"chars": 296,
"preview": "<?php\n\nuse Illuminate\\Database\\Migrations\\Migration;\nuse Illuminate\\Support\\Facades\\DB;\n\nreturn new class extends Migrat"
},
{
"path": "database/migrations/sql/0.74.0-0.75.0.sql",
"chars": 1461,
"preview": "CREATE TABLE IF NOT EXISTS `bot_chat_join_request` (\n `id` BIGINT UNSIGNED AUTO_INCREMENT COMMENT 'Unique identifier "
},
{
"path": "database/migrations/sql/0.76.1-0.77.0.sql",
"chars": 661,
"preview": "ALTER TABLE `bot_message` ADD COLUMN `web_app_data` TEXT NULL DEFAULT NULL COMMENT 'Service message: data sent by a Web "
},
{
"path": "database/migrations/sql/0.77.1-0.78.0.sql",
"chars": 315,
"preview": "ALTER TABLE `bot_user` ADD COLUMN `is_premium` tinyint(1) DEFAULT 0 COMMENT 'True, if this user is a Telegram Premium us"
},
{
"path": "database/migrations/sql/0.79.0-0.80.0.sql",
"chars": 908,
"preview": "ALTER TABLE `bot_message`\n ADD COLUMN `is_topic_message` TINYINT(1) DEFAULT 0 COMMENT 'True, if the message is sent t"
},
{
"path": "database/migrations/sql/0.80.0-0.81.0.sql",
"chars": 1170,
"preview": "ALTER TABLE `bot_message`\n ADD COLUMN `has_media_spoiler` TINYINT(1) DEFAULT 0 COMMENT 'True, if the messa"
},
{
"path": "database/migrations/sql/structure-0.73.0.sql",
"chars": 23404,
"preview": "CREATE TABLE IF NOT EXISTS bot_user (\n `id` bigint COMMENT 'Unique identifier for this user or bot',\n `is_bot` tinyint"
},
{
"path": "license.md",
"chars": 1158,
"preview": "# The license\n\nMIT License\n\nCopyright (c) 2022 [PHP Telegram Bot](https://github.com/php-telegram-bot)\n\nPermission is he"
},
{
"path": "phpunit.xml",
"chars": 661,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<phpunit bootstrap=\"vendor/autoload.php\"\n backupGlobals=\"false\"\n "
},
{
"path": "readme.md",
"chars": 4566,
"preview": "# LaravelTelegramBot\n\n[![Latest Version on Packagist][ico-version]][link-packagist]\n[![Total Downloads][ico-downloads]]["
},
{
"path": "routes/telegram.php",
"chars": 278,
"preview": "<?php\n\nRoute::post('/api/telegram/webhook/{token}', static function (\\Longman\\TelegramBot\\Telegram $bot, $token) {\n i"
},
{
"path": "src/Console/Commands/GeneratorCommand.php",
"chars": 1044,
"preview": "<?php\n\n\nnamespace PhpTelegramBot\\Laravel\\Console\\Commands;\n\n\nuse Illuminate\\Console\\Command;\n\nabstract class GeneratorCo"
},
{
"path": "src/Console/Commands/MakeTelegramCommand.php",
"chars": 1654,
"preview": "<?php\n\nnamespace PhpTelegramBot\\Laravel\\Console\\Commands;\n\nuse Illuminate\\Support\\Str;\n\nclass MakeTelegramCommand extend"
},
{
"path": "src/Console/Commands/TelegramCloseCommand.php",
"chars": 587,
"preview": "<?php\n\nnamespace PhpTelegramBot\\Laravel\\Console\\Commands;\n\nuse Illuminate\\Console\\Command;\nuse Longman\\TelegramBot\\Reque"
},
{
"path": "src/Console/Commands/TelegramDeleteWebhookCommand.php",
"chars": 881,
"preview": "<?php\n\nnamespace PhpTelegramBot\\Laravel\\Console\\Commands;\n\nuse Illuminate\\Console\\Command;\nuse Longman\\TelegramBot\\Reque"
},
{
"path": "src/Console/Commands/TelegramFetchCommand.php",
"chars": 2180,
"preview": "<?php\n\n\nnamespace PhpTelegramBot\\Laravel\\Console\\Commands;\n\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Support\\Str;"
},
{
"path": "src/Console/Commands/TelegramLogoutCommand.php",
"chars": 591,
"preview": "<?php\n\nnamespace PhpTelegramBot\\Laravel\\Console\\Commands;\n\nuse Illuminate\\Console\\Command;\nuse Longman\\TelegramBot\\Reque"
},
{
"path": "src/Console/Commands/TelegramPublishCommand.php",
"chars": 754,
"preview": "<?php\n\nnamespace PhpTelegramBot\\Laravel\\Console\\Commands;\n\nuse Illuminate\\Filesystem\\Filesystem;\n\nclass TelegramPublishC"
},
{
"path": "src/Console/Commands/TelegramSetWebhookCommand.php",
"chars": 2039,
"preview": "<?php\n\nnamespace PhpTelegramBot\\Laravel\\Console\\Commands;\n\nuse Illuminate\\Console\\Command;\nuse Illuminate\\Support\\Str;\nu"
},
{
"path": "src/Console/Commands/stubs/example-start-command.stub",
"chars": 651,
"preview": "<?php\n\n\nnamespace DummyRootNamespace\\Telegram\\Commands;\n\n\nuse Longman\\TelegramBot\\Commands\\UserCommand;\nuse Longman\\Tele"
},
{
"path": "src/Console/Commands/stubs/telegram-command.stub",
"chars": 594,
"preview": "<?php\n\n\nnamespace DummyNamespace\\Telegram\\Commands;\n\n\nuse Longman\\TelegramBot\\Commands\\DummyParent;\nuse Longman\\Telegram"
},
{
"path": "src/Facades/CallbackButton.php",
"chars": 266,
"preview": "<?php\n\n\nnamespace PhpTelegramBot\\Laravel\\Facades;\n\n\nuse Illuminate\\Support\\Facades\\Facade;\n\nclass CallbackButton extends"
},
{
"path": "src/Facades/Telegram.php",
"chars": 274,
"preview": "<?php\n\nnamespace PhpTelegramBot\\Laravel\\Facades;\n\nuse Illuminate\\Support\\Facades\\Facade;\nuse PhpTelegramBot\\Laravel\\Lara"
},
{
"path": "src/Factories/CallbackButton.php",
"chars": 1638,
"preview": "<?php\n\n\nnamespace PhpTelegramBot\\Laravel\\Factories;\n\n\nuse Illuminate\\Support\\Facades\\Cache;\nuse Illuminate\\Support\\Str;\n"
},
{
"path": "src/Http/Middleware/TrustTelegramNetwork.php",
"chars": 1151,
"preview": "<?php\n\nnamespace PhpTelegramBot\\Laravel\\Http\\Middleware;\n\nuse Closure;\nuse Illuminate\\Support\\Facades\\App;\nuse Symfony\\C"
},
{
"path": "src/LaravelTelegramBot.php",
"chars": 722,
"preview": "<?php\n\nnamespace PhpTelegramBot\\Laravel;\n\nuse Longman\\TelegramBot\\Entities\\ServerResponse;\nuse Longman\\TelegramBot\\Entit"
},
{
"path": "src/Telegram/Commands/CallbackqueryCommand.php",
"chars": 2287,
"preview": "<?php\n\n\nnamespace PhpTelegramBot\\Laravel\\Telegram\\Commands;\n\n\nuse Illuminate\\Support\\Facades\\App;\nuse Longman\\TelegramBo"
},
{
"path": "src/Telegram/Commands/GenericmessageCommand.php",
"chars": 1737,
"preview": "<?php\n\nnamespace PhpTelegramBot\\Laravel\\Telegram\\Commands;\n\nuse Illuminate\\Support\\Facades\\App;\nuse Longman\\TelegramBot\\"
},
{
"path": "src/Telegram/Conversation/ConversationWrapper.php",
"chars": 3422,
"preview": "<?php\n\nnamespace PhpTelegramBot\\Laravel\\Telegram\\Conversation;\n\nuse Longman\\TelegramBot\\Conversation;\nuse Longman\\Telegr"
},
{
"path": "src/Telegram/Conversation/LeadsConversation.php",
"chars": 856,
"preview": "<?php\n\n\nnamespace PhpTelegramBot\\Laravel\\Telegram\\Conversation;\n\nuse Longman\\TelegramBot\\Entities\\Update;\n\n/**\n * Trait "
},
{
"path": "src/Telegram/InlineKeyboardButton/CallbackPayload.php",
"chars": 485,
"preview": "<?php\n\n\nnamespace PhpTelegramBot\\Laravel\\Telegram\\InlineKeyboardButton;\n\n\nclass CallbackPayload\n{\n\n public function _"
},
{
"path": "src/Telegram/InlineKeyboardButton/RemembersCallbackPayload.php",
"chars": 1343,
"preview": "<?php\n\nnamespace PhpTelegramBot\\Laravel\\Telegram\\InlineKeyboardButton;\n\n\nuse Illuminate\\Support\\Facades\\Cache;\nuse Longm"
},
{
"path": "src/Telegram/UsesEffectiveEntities.php",
"chars": 1167,
"preview": "<?php\n\nnamespace PhpTelegramBot\\Laravel\\Telegram;\n\nuse Longman\\TelegramBot\\Entities\\Chat;\nuse Longman\\TelegramBot\\Entiti"
},
{
"path": "src/TelegramServiceProvider.php",
"chars": 4943,
"preview": "<?php\n\nnamespace PhpTelegramBot\\Laravel;\n\nuse Illuminate\\Routing\\Router;\nuse Illuminate\\Support\\Facades\\File;\nuse Illumi"
}
]
About this extraction
This page contains the full source code of the php-telegram-bot/laravel GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 44 files (68.8 KB), approximately 17.8k tokens, and a symbol index with 100 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.