diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..660dccf
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,20 @@
+root = true
+
+[*]
+end_of_line = lf
+insert_final_newline = true
+charset = utf-8
+indent_style = space
+indent_size = 4
+trim_trailing_whitespace = true
+
+[*.md]
+trim_trailing_whitespace = false
+
+[*.yml]
+indent_style = space
+indent_size = 2
+
+# Tab indentation (no size specified)
+[Makefile]
+indent_style = tab
diff --git a/.gitignore b/.gitignore
index 9949256..ab0ce12 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,43 +1,33 @@
-
-# Created by https://www.toptal.com/developers/gitignore/api/laravel,composer
-# Edit at https://www.toptal.com/developers/gitignore?templates=laravel,composer
-
-### Composer ###
+# IDE & System Related Files #
+.buildpath
+.project
+.settings
+.DS_Store
+.idea
+.phpintel
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
+# Local System Files (i.e. cache, logs, etc.) #
+/cache
+/build/logs
+/build/coverage
+/tmp
-# Laravel 5 & Lumen specific with changed public path
-public_html/storage
-public_html/hot
+# Test Related Files #
+/phpunit.xml
+/.phpunit.result.cache
-storage/*.key
-.env
-Homestead.yaml
-Homestead.json
-/.vagrant
-.phpunit.result.cache
+# Composer
+vendor/
-# Laravel IDE helper
-*.meta.*
-_ide_*
+.fuse_hidden*
-# End of https://www.toptal.com/developers/gitignore/api/laravel,composer
+# phpDocumentor Logs #
+phpdoc-*
-/.idea
+# OSX #
+._*
+.Spotlight-V100
+.Trashes
+_ide_helper.php
diff --git a/.scrutinizer.yml b/.scrutinizer.yml
new file mode 100644
index 0000000..b7067bf
--- /dev/null
+++ b/.scrutinizer.yml
@@ -0,0 +1,21 @@
+build:
+ environment:
+ php: 7.3.0
+ nodes:
+ analysis:
+ tests:
+ override:
+ - php-scrutinizer-run
+
+filter:
+ paths:
+ - src/
+
+checks:
+ php:
+ code_rating: true
+ duplication: true
+
+tools:
+ external_code_coverage:
+ timeout: 300
diff --git a/.styleci.yml b/.styleci.yml
deleted file mode 100644
index c3bb259..0000000
--- a/.styleci.yml
+++ /dev/null
@@ -1 +0,0 @@
-preset: laravel
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..ece28aa
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,28 @@
+language: php
+sudo: false
+
+php:
+ - 7.3
+ - 7.4
+ - 8.0
+
+before_install:
+ - composer self-update
+
+install:
+ - travis_retry composer update --no-interaction --prefer-source
+
+script:
+ - ./vendor/bin/phpcs --standard=phpcs.xml -spn --encoding=utf-8 src/ --report-width=150
+ - ./vendor/bin/phpunit --coverage-clover build/logs/clover.xml
+
+after_script:
+ - wget https://scrutinizer-ci.com/ocular.phar
+ - then php ocular.phar code-coverage:upload --format=php-clover build/logs/clover.xml
+
+matrix:
+ fast_finish: true
+
+notifications:
+ on_success: never
+ on_failure: always
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..0609226
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,27 @@
+Contributing
+-------------
+
+Before you contribute code to this project, please make sure it conforms to the PSR-2 coding standard
+and that the project unit tests still pass. The easiest way to contribute is to work on a checkout of the repository,
+or your own fork. If you do this, you can run the following commands to check if everything is ready to submit:
+
+ cd project
+ composer update
+ ./vendor/bin/phpcs --standard=phpcs.xml -spn --encoding=utf-8 src/ --report-width=150
+
+Which should give you no output, indicating that there are no coding standard errors. And then:
+
+ ./vendor/bin/phpunit
+
+Which should give you no failures or errors. You can ignore any skipped tests as these are for external tools.
+
+Pushing
+-------
+
+Development is based on the git flow branching model (see http://nvie.com/posts/a-successful-git-branching-model/ )
+If you fix a bug please push in hotfix branch.
+If you develop a new feature please create a new branch.
+
+Version
+-------
+Version number: 0.#version.#hotfix
diff --git a/CREDITS b/CREDITS
new file mode 100644
index 0000000..7df11fc
--- /dev/null
+++ b/CREDITS
@@ -0,0 +1,19 @@
+ This is at least a partial credits-file of people that have
+ contributed to the current project. It is sorted by name and
+ formatted to allow easy grepping and beautification by
+ scripts. The fields are: name (N), email (E), web-address
+ (W) and description (D).
+ Thanks,
+
+ Avtandil Kikabidze
+----------
+
+N: Avtandil Kikabidze aka LONGMAN
+E: akalongman@gmail.com
+W: http://longman.me
+D: Project owner, Maintainer
+
+N: MohammadR. Fekri
+E: fekri.m@icloud.com
+W: https://fekri.me
+D: Contributor
diff --git a/EXAMPLE.md b/EXAMPLE.md
new file mode 100644
index 0000000..1f79bc0
--- /dev/null
+++ b/EXAMPLE.md
@@ -0,0 +1,82 @@
+## Example ##
+
+
+1- After adding the package and setting everything up, create a controller, for example `TelegramController.php` in your `app/Http/Controllers` directory and put this in it:
+
+```
+setWebhook(url(config('phptelegrambot.bot.api_key') . '/hook'));
+ }
+
+ public function hook(PhpTelegramBotContract $telegram_bot) {
+ $telegram_bot->handle();
+ }
+}
+```
+
+2- Now you need to write routes for these actions. so open your `web.php` and write:
+```
+$router->group(['prefix' => config('phptelegrambot.bot.api_key')], function() use ($router) {
+ $router->get('set', 'TelegramController@set');
+ $router->post('hook', 'TelegramController@hook');
+});
+```
+We prefix all routes with the long API key that BotFather has given us to make the `hook` url secure and to ensure the incoming requests are from no one but Telegram.
+
+3- Go to `https://yoursite.com/[YOUR BOT API KEY]/set`
+You should see the success message.
+
+4- Create a directory for your commands. It can be anywhere, for example `app/Telegram/Commands/[CommandNameCommand].php` would be nice.
+
+This is an example `StartCommand.php`:
+```
+getMessage();
+
+ $chat_id = $message->getChat()->getId();
+ $text = 'Hi! Welcome to my bot!';
+
+ $data = [
+ 'chat_id' => $chat_id,
+ 'text' => $text,
+ ];
+
+ return Request::sendMessage($data);
+ }
+}
+```
+5- The last thing you need to do is to add your custom commands directory to the bot's config. so open `config/phptelegrambot.php` and add the commands directory to the array:
+
+```
+...
+'commands' => [
+ 'before' => true,
+ 'paths' => [
+ base_path('/app/Telegram/Commands')
+ ],
+ 'configs' => [
+ // Custom commands configs
+ ],
+],
+...
+```
+
+
+That's it.
diff --git a/LICENSE.md b/LICENSE.md
new file mode 100644
index 0000000..334f39f
--- /dev/null
+++ b/LICENSE.md
@@ -0,0 +1,22 @@
+The [MIT License](http://opensource.org/licenses/mit-license.php)
+
+Copyright (c) 2016 [Avtandil Kikabidze aka LONGMAN](https://github.com/akalongman)
+
+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 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.
+
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..5e9f205
--- /dev/null
+++ b/README.md
@@ -0,0 +1,110 @@
+# Telegram Bot Package for Laravel 6.x, 7.x, and 8.x
+
+[](https://travis-ci.org/php-telegram-bot/laravel)
+[](https://scrutinizer-ci.com/g/php-telegram-bot/laravel/?b=master)
+[](https://scrutinizer-ci.com/g/php-telegram-bot/laravel/?b=master)
+[](https://packagist.org/packages/php-telegram-bot/laravel)
+[](https://packagist.org/packages/php-telegram-bot/laravel)
+[](https://packagist.org/packages/php-telegram-bot/laravel)
+[](https://php.net/)
+[](https://github.com/php-telegram-bot/laravel/LICENSE.md)
+
+This package helps easily integrate [PHP Telegram Bot](https://github.com/php-telegram-bot/core) library in Laravel application.
+
+## Table of Contents
+- [Installation](#installation)
+- [Usage](#usage)
+- [TODO](#todo)
+- [Troubleshooting](#troubleshooting)
+- [Contributing](#contributing)
+- [License](#license)
+- [Credits](#credits)
+
+## Installation
+
+Install this package through [Composer](https://getcomposer.org/).
+
+Edit your project's `composer.json` file to require `php-telegram-bot/laravel`
+
+Create *composer.json* file:
+```json
+{
+ "name": "yourproject/yourproject",
+ "type": "project",
+ "require": {
+ "php-telegram-bot/laravel": "^1.0"
+ }
+}
+```
+And run composer update
+
+**Or** run a command in your command line:
+
+ composer require php-telegram-bot/laravel
+
+Copy the package config and migrations to your project with the publish command:
+
+ php artisan vendor:publish --provider="PhpTelegramBot\Laravel\ServiceProvider"
+
+After run migration command
+
+ php artisan migrate
+
+In the config you have to specify Telegram API KEY
+
+## Usage
+
+You can inject `PhpTelegramBot\Laravel\PhpTelegramBotContract` in anywhere and use bot instance
+
+For example:
+
+```php
+handle();
+
+ // Or set webhook
+ $hookUrl = 'https://hook.url';
+ $telegramBot->setWebhook($hookUrl);
+
+ // Or handle telegram getUpdates request
+ $telegramBot->handleGetUpdates();
+ }
+}
+
+```
+
+More details about usage you can see on the PHP Telegram Bot docs: https://github.com/php-telegram-bot/core#instructions
+
+## TODO
+
+write more tests
+
+## Troubleshooting
+
+If you like living on the edge, please report any bugs you find on the
+[php-telegram-bot/laravel issues](https://github.com/php-telegram-bot/laravel/issues) page.
+
+## Contributing
+
+Pull requests are welcome.
+See [CONTRIBUTING.md](CONTRIBUTING.md) for information.
+
+## License
+
+Please see the [LICENSE](LICENSE.md) included in this repository for a full copy of the MIT license,
+which this project is licensed under.
+
+## Credits
+
+- [Avtandil Kikabidze aka LONGMAN](https://github.com/akalongman)
+
+Full credit list in [CREDITS](CREDITS)
diff --git a/changelog.md b/changelog.md
deleted file mode 100644
index dfa1e3e..0000000
--- a/changelog.md
+++ /dev/null
@@ -1,16 +0,0 @@
-# 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
diff --git a/composer.json b/composer.json
index 646cffc..b8a9324 100644
--- a/composer.json
+++ b/composer.json
@@ -1,55 +1,73 @@
{
"name": "php-telegram-bot/laravel",
- "description": "Integrates PHP Telegram Bot into Laravel.",
+ "type": "library",
+ "description": "Package to integrate PHP Telegram Bot library in Laravel 6.x, 7.x, and 8.x",
+ "keywords": [
+ "laravel",
+ "telegram",
+ "bot"
+ ],
"license": "MIT",
+ "homepage": "https://github.com/php-telegram-bot/laravel",
+ "support": {
+ "issues": "https://github.com/php-telegram-bot/laravel/issues",
+ "source": "https://github.com/php-telegram-bot/laravel"
+ },
"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": "*"
+ "php": "^7.3|^8.0",
+ "ext-json": "*",
+ "illuminate/database": "^6.0|^7.0|^8.0",
+ "illuminate/support": "^6.0|^7.0|^8.0",
+ "longman/telegram-bot": "^0.74"
},
"require-dev": {
- "phpunit/phpunit": "~9.0",
- "symfony/process": "^5.3"
+ "phpunit/phpunit": "^9.3",
+ "longman/php-code-style": "^7.0",
+ "graham-campbell/testbench": "^5.6"
},
"autoload": {
"psr-4": {
- "PhpTelegramBot\\Laravel\\": "src/"
+ "PhpTelegramBot\\Laravel\\": "src/Laravel"
}
},
- "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"
- }
+ "autoload-dev": {
+ "psr-4": {
+ "Tests\\": "tests/"
}
},
- "minimum-stability": "dev",
- "prefer-stable": true,
"config": {
- "allow-plugins": {
- "dealerdirect/phpcodesniffer-composer-installer": true
+ "sort-packages": true
+ },
+ "scripts": {
+ "test": [
+ "vendor/bin/phpunit"
+ ],
+ "coverage-text": [
+ "vendor/bin/phpunit --coverage-text --colors=never"
+ ],
+ "coverage-html": [
+ "vendor/bin/phpunit --coverage-html public/coverage"
+ ],
+ "phpcs": [
+ "vendor/bin/phpcs --standard=phpcs.xml -spn --encoding=utf-8 src/ tests/ --report-width=150"
+ ],
+ "phpcbf": [
+ "vendor/bin/phpcbf --standard=phpcs.xml -spn --encoding=utf-8 src/ tests/ --report-width=150"
+ ]
+ },
+ "extra": {
+ "laravel": {
+ "providers": [
+ "PhpTelegramBot\\Laravel\\ServiceProvider"
+ ]
}
}
}
diff --git a/config/telegram.php b/config/telegram.php
deleted file mode 100644
index 6f043ed..0000000
--- a/config/telegram.php
+++ /dev/null
@@ -1,14 +0,0 @@
- [
- 'api_token' => env('TELEGRAM_API_TOKEN'),
-
- 'username' => env('TELEGRAM_BOT_USERNAME', ''),
-
- 'api_url' => env('TELEGRAM_API_URL'),
- ],
-
- 'admins' => env('TELEGRAM_ADMINS', '')
-
-];
diff --git a/database/migrations/2021_06_14_171118_create_telegram_bot_structure.php b/database/migrations/2021_06_14_171118_create_telegram_bot_structure.php
deleted file mode 100644
index 28ef465..0000000
--- a/database/migrations/2021_06_14_171118_create_telegram_bot_structure.php
+++ /dev/null
@@ -1,15 +0,0 @@
-
+
+
+
+
+
+ src/database/*
+
+
+ tests/*
+
+
+
+
+
+
+
+
diff --git a/phpunit.xml b/phpunit.xml
deleted file mode 100644
index ce34605..0000000
--- a/phpunit.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
- ./tests/
-
-
-
-
- src/
-
-
-
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
new file mode 100644
index 0000000..a57873b
--- /dev/null
+++ b/phpunit.xml.dist
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ./tests/
+
+
+
+
+ ./src
+
+ ./src/config
+ ./src/database
+
+
+
+
diff --git a/readme.md b/readme.md
deleted file mode 100644
index 8f96d7a..0000000
--- a/readme.md
+++ /dev/null
@@ -1,116 +0,0 @@
-# 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
diff --git a/routes/telegram.php b/routes/telegram.php
deleted file mode 100644
index 7bb44eb..0000000
--- a/routes/telegram.php
+++ /dev/null
@@ -1,9 +0,0 @@
-handle();
-})->middleware('telegram.network')->name('telegram.webhook');
diff --git a/src/Console/Commands/GeneratorCommand.php b/src/Console/Commands/GeneratorCommand.php
deleted file mode 100644
index 10507c4..0000000
--- a/src/Console/Commands/GeneratorCommand.php
+++ /dev/null
@@ -1,41 +0,0 @@
-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(), '\\');
- }
-
-}
diff --git a/src/Console/Commands/MakeTelegramCommand.php b/src/Console/Commands/MakeTelegramCommand.php
deleted file mode 100644
index 8b7a3f4..0000000
--- a/src/Console/Commands/MakeTelegramCommand.php
+++ /dev/null
@@ -1,63 +0,0 @@
-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';
- }
-}
diff --git a/src/Console/Commands/TelegramCloseCommand.php b/src/Console/Commands/TelegramCloseCommand.php
deleted file mode 100644
index 39e012c..0000000
--- a/src/Console/Commands/TelegramCloseCommand.php
+++ /dev/null
@@ -1,25 +0,0 @@
-isOk()) {
- $this->error($response->getDescription());
- }
-
- $this->info($response->getDescription());
- }
-}
diff --git a/src/Console/Commands/TelegramDeleteWebhookCommand.php b/src/Console/Commands/TelegramDeleteWebhookCommand.php
deleted file mode 100644
index c448f86..0000000
--- a/src/Console/Commands/TelegramDeleteWebhookCommand.php
+++ /dev/null
@@ -1,31 +0,0 @@
-option('drop-pending-updates')) {
- $options['drop_pending_updates'] = true;
- }
-
- $response = Request::deleteWebhook($options);
-
- if (! $response->isOk()) {
- $this->error($response->getDescription());
- }
-
- $this->info($response->getDescription());
- }
-}
diff --git a/src/Console/Commands/TelegramFetchCommand.php b/src/Console/Commands/TelegramFetchCommand.php
deleted file mode 100644
index e9d1d3a..0000000
--- a/src/Console/Commands/TelegramFetchCommand.php
+++ /dev/null
@@ -1,81 +0,0 @@
-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(Exit with Ctrl + C)");
-
- 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;
- }
-}
diff --git a/src/Console/Commands/TelegramLogoutCommand.php b/src/Console/Commands/TelegramLogoutCommand.php
deleted file mode 100644
index f36ea31..0000000
--- a/src/Console/Commands/TelegramLogoutCommand.php
+++ /dev/null
@@ -1,25 +0,0 @@
-isOk()) {
- $this->error($response->getDescription());
- }
-
- $this->info($response->getDescription());
- }
-}
diff --git a/src/Console/Commands/TelegramPublishCommand.php b/src/Console/Commands/TelegramPublishCommand.php
deleted file mode 100644
index 7f733bd..0000000
--- a/src/Console/Commands/TelegramPublishCommand.php
+++ /dev/null
@@ -1,29 +0,0 @@
-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.');
- }
- }
-
-}
diff --git a/src/Console/Commands/TelegramSetWebhookCommand.php b/src/Console/Commands/TelegramSetWebhookCommand.php
deleted file mode 100644
index 1f6d27b..0000000
--- a/src/Console/Commands/TelegramSetWebhookCommand.php
+++ /dev/null
@@ -1,58 +0,0 @@
-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 {$url}");
- }
-}
diff --git a/src/Console/Commands/stubs/example-start-command.stub b/src/Console/Commands/stubs/example-start-command.stub
deleted file mode 100644
index cf890ea..0000000
--- a/src/Console/Commands/stubs/example-start-command.stub
+++ /dev/null
@@ -1,28 +0,0 @@
-replyToChat('Hello world! 👋');
- }
-
-}
diff --git a/src/Console/Commands/stubs/telegram-command.stub b/src/Console/Commands/stubs/telegram-command.stub
deleted file mode 100644
index 67ae0b9..0000000
--- a/src/Console/Commands/stubs/telegram-command.stub
+++ /dev/null
@@ -1,28 +0,0 @@
-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
- ]);
- }
-
-}
diff --git a/src/Http/Middleware/TrustTelegramNetwork.php b/src/Http/Middleware/TrustTelegramNetwork.php
deleted file mode 100644
index cd557cc..0000000
--- a/src/Http/Middleware/TrustTelegramNetwork.php
+++ /dev/null
@@ -1,52 +0,0 @@
-ip(), $this->localIpNets)) {
- return $next($request);
- }
-
- if (IpUtils::checkIp($request->ip(), $this->trustedIpNets)) {
- return $next($request);
- }
-
- abort(403);
- }
-}
diff --git a/src/Laravel/Commands/WebhookCommand.php b/src/Laravel/Commands/WebhookCommand.php
new file mode 100644
index 0000000..8f19706
--- /dev/null
+++ b/src/Laravel/Commands/WebhookCommand.php
@@ -0,0 +1,115 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+declare(strict_types=1);
+
+namespace PhpTelegramBot\Laravel\Commands;
+
+use Illuminate\Console\Command;
+use Longman\TelegramBot\Exception\TelegramException;
+use Longman\TelegramBot\Request;
+use PhpTelegramBot\Laravel\PhpTelegramBotContract;
+
+use function json_encode;
+
+use const JSON_PRETTY_PRINT;
+
+class WebhookCommand extends Command
+{
+ protected $signature = 'telegram:webhook {webhook?}
+ {--delete : Delete webhook}
+ {--info : Get webhook info}';
+
+ protected $description = 'Set, delete, or get webhook info for Telegram Bot';
+
+ /** @var \PhpTelegramBot\Laravel\PhpTelegramBotContract */
+ protected $telegramBot;
+
+ public function __construct(PhpTelegramBotContract $telegramBot)
+ {
+ parent::__construct();
+
+ $this->telegramBot = $telegramBot;
+ }
+
+ public function handle(): void
+ {
+ $webhook = $this->argument('webhook');
+ $delete = $this->option('delete');
+ $info = $this->option('info');
+
+ if (! ($webhook || $delete || $info)) {
+ $this->error('Not enough arguments!');
+ $this->error('php artisan telegram:webhook {webhook?} {--delete} {--info}');
+ return;
+ }
+
+ if ($delete && ! $this->deleteWebhook()) {
+ return;
+ }
+
+ if ($webhook && ! $this->setWebhook($webhook)) {
+ return;
+ }
+
+ if ($info && ! $this->showWebhookInfo()) {
+ return;
+ }
+
+ $this->info('All done!');
+ }
+
+ private function setWebhook(string $webhook): bool
+ {
+ try {
+ $this->telegramBot->setWebhook($webhook);
+ $this->info('Webhook set successfully!');
+ } catch (TelegramException $e) {
+ $this->error("Couldn't set webhook");
+ $this->error($e->getMessage());
+ return false;
+ }
+
+ return true;
+ }
+
+ private function deleteWebhook(): bool
+ {
+ try {
+ $this->telegramBot->deleteWebhook();
+ $this->info('Webhook deleted successfully!');
+ } catch (TelegramException $e) {
+ $this->error("Couldn't delete webhook");
+ $this->error($e->getMessage());
+ return false;
+ }
+
+ return true;
+ }
+
+ private function showWebhookInfo(): bool
+ {
+ try {
+ $request = Request::getWebhookInfo();
+ if (! $request->isOk()) {
+ throw new TelegramException($request->getDescription());
+ }
+ $this->info('Current webhook info:');
+ $this->info(json_encode($request->getResult(), JSON_PRETTY_PRINT));
+ } catch (TelegramException $e) {
+ $this->error("Couldn't get webhook info");
+ $this->error($e->getMessage());
+ return false;
+ }
+
+ return true;
+ }
+}
diff --git a/src/Laravel/Migration.php b/src/Laravel/Migration.php
new file mode 100644
index 0000000..71ec48c
--- /dev/null
+++ b/src/Laravel/Migration.php
@@ -0,0 +1,58 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+declare(strict_types=1);
+
+namespace PhpTelegramBot\Laravel;
+
+use Illuminate\Database\Migrations\Migration as LaravelMigration;
+use Illuminate\Support\Facades\DB;
+
+class Migration extends LaravelMigration
+{
+ /** @var string */
+ protected $prefix = '';
+
+ public function __construct()
+ {
+ $this->prefix = (string) config('phptelegrambot.database.prefix', '');
+ }
+
+ /**
+ * Change column type for passed table field(s).
+ *
+ * @param array $tableColumns
+ * @param string $newType
+ */
+ public function changeColumnTypes(array $tableColumns, string $newType): void
+ {
+ $database = DB::connection()->getDatabaseName();
+ $prefix = DB::connection()->getTablePrefix() . $this->prefix;
+
+ foreach ($tableColumns as $table => $columns) {
+ foreach ($columns as $column) {
+ // Preserve column comment and nullable state.
+ $props = DB::selectOne('
+ SELECT `COLUMN_COMMENT`, `IS_NULLABLE`
+ FROM `information_schema`.`COLUMNS`
+ WHERE `TABLE_SCHEMA` = ?
+ AND `TABLE_NAME` = ?
+ AND `COLUMN_NAME` = ?
+ LIMIT 1
+ ', [$database, $prefix . $table, $column]);
+
+ $comment = $props->COLUMN_COMMENT;
+ $nullable = $props->IS_NULLABLE === 'YES' ? 'NULL' : 'NOT NULL';
+ DB::statement("ALTER TABLE `{$prefix}{$table}` CHANGE `{$column}` `{$column}` {$newType} {$nullable} COMMENT '{$comment}'");
+ }
+ }
+ }
+}
diff --git a/src/Laravel/PhpTelegramBot.php b/src/Laravel/PhpTelegramBot.php
new file mode 100644
index 0000000..1ba08a4
--- /dev/null
+++ b/src/Laravel/PhpTelegramBot.php
@@ -0,0 +1,21 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+declare(strict_types=1);
+
+namespace PhpTelegramBot\Laravel;
+
+use Longman\TelegramBot\Telegram;
+
+class PhpTelegramBot extends Telegram implements PhpTelegramBotContract
+{
+ //
+}
diff --git a/src/Laravel/PhpTelegramBotContract.php b/src/Laravel/PhpTelegramBotContract.php
new file mode 100644
index 0000000..9cad294
--- /dev/null
+++ b/src/Laravel/PhpTelegramBotContract.php
@@ -0,0 +1,22 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+declare(strict_types=1);
+
+namespace PhpTelegramBot\Laravel;
+
+/**
+ * @mixin \Longman\TelegramBot\Telegram
+ */
+interface PhpTelegramBotContract
+{
+ //
+}
diff --git a/src/Laravel/ServiceProvider.php b/src/Laravel/ServiceProvider.php
new file mode 100644
index 0000000..1d41506
--- /dev/null
+++ b/src/Laravel/ServiceProvider.php
@@ -0,0 +1,116 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+declare(strict_types=1);
+
+namespace PhpTelegramBot\Laravel;
+
+use Illuminate\Support\ServiceProvider as LaravelServiceProvider;
+use PhpTelegramBot\Laravel\Commands\WebhookCommand;
+
+class ServiceProvider extends LaravelServiceProvider
+{
+ /**
+ * Indicates if loading of the provider is deferred.
+ *
+ * @var bool
+ */
+ protected $defer = true;
+
+ /**
+ * Bootstrap any application services.
+ *
+ * @return void
+ */
+ public function boot(): void
+ {
+ // Publish config files
+ $this->publishes([
+ __DIR__ . '/../config/config.php' => config_path('phptelegrambot.php'),
+ ], 'config');
+
+ // Append the default settings
+ $this->mergeConfigFrom(
+ __DIR__ . '/../config/config.php',
+ 'phptelegrambot',
+ );
+
+ $this->publishes([
+ __DIR__ . '/../database/migrations/' => database_path('migrations'),
+ ], 'migrations');
+ }
+
+ /**
+ * Register any application services.
+ *
+ * @return void
+ */
+ public function register(): void
+ {
+ $this->app->bind(PhpTelegramBotContract::class, static function ($app) {
+ $config = $app['config']->get('phptelegrambot');
+
+ $bot = new PhpTelegramBot($config['bot']['api_key'], ! empty($config['bot']['name']) ? $config['bot']['name'] : '');
+
+ // Add commands if paths are given
+ if (! empty($config['commands']['paths'])) {
+ $bot->addCommandsPaths($config['commands']['paths']);
+ }
+
+ // Set command related configs
+ if (! empty($config['commands']['configs'])) {
+ foreach ($config['commands']['configs'] as $commandName => $commandConfig) {
+ $bot->setCommandConfig($commandName, $commandConfig);
+ }
+ }
+
+ // Set database connection
+ if ($config['database']['enabled'] === true) {
+ /** @var \Illuminate\Database\Connection $connection */
+ $connection = $app['db']->connection($config['database']['connection']);
+ // Ability to use custom table prefix
+ $tablePrefix = $config['database']['prefix'] ?? '';
+ $bot->enableExternalMySql($connection->getPdo(), $tablePrefix);
+ }
+
+ // Enable admins if provided
+ if (! empty($config['admins'])) {
+ $bot->enableAdmins($config['admins']);
+ }
+
+ // Set paths
+ if (! empty($config['download_path'])) {
+ $bot->setDownloadPath($config['download_path']);
+ }
+ if (! empty($config['upload_path'])) {
+ $bot->setUploadPath($config['upload_path']);
+ }
+
+ return $bot;
+ });
+
+ if ($this->app->runningInConsole()) {
+ $this->commands([
+ WebhookCommand::class,
+ ]);
+ }
+ }
+
+ /**
+ * Get the services provided by the provider.
+ *
+ * @return array
+ */
+ public function provides(): array
+ {
+ return [PhpTelegramBotContract::class];
+ }
+}
diff --git a/src/LaravelTelegramBot.php b/src/LaravelTelegramBot.php
deleted file mode 100644
index 34bae35..0000000
--- a/src/LaravelTelegramBot.php
+++ /dev/null
@@ -1,34 +0,0 @@
-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;
- }
-
-}
diff --git a/src/Telegram/Commands/CallbackqueryCommand.php b/src/Telegram/Commands/CallbackqueryCommand.php
deleted file mode 100644
index d1d7323..0000000
--- a/src/Telegram/Commands/CallbackqueryCommand.php
+++ /dev/null
@@ -1,65 +0,0 @@
-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();
- }
-}
diff --git a/src/Telegram/Commands/GenericmessageCommand.php b/src/Telegram/Commands/GenericmessageCommand.php
deleted file mode 100644
index ebacdb8..0000000
--- a/src/Telegram/Commands/GenericmessageCommand.php
+++ /dev/null
@@ -1,53 +0,0 @@
-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();
- }
-
-}
\ No newline at end of file
diff --git a/src/Telegram/Conversation/ConversationWrapper.php b/src/Telegram/Conversation/ConversationWrapper.php
deleted file mode 100644
index 5721b95..0000000
--- a/src/Telegram/Conversation/ConversationWrapper.php
+++ /dev/null
@@ -1,124 +0,0 @@
-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();
- }
-
-}
diff --git a/src/Telegram/Conversation/LeadsConversation.php b/src/Telegram/Conversation/LeadsConversation.php
deleted file mode 100644
index 1677ee6..0000000
--- a/src/Telegram/Conversation/LeadsConversation.php
+++ /dev/null
@@ -1,40 +0,0 @@
-conversation)) {
- $this->conversation = new ConversationWrapper($this->getUpdate(), $this->getName());
- }
-
- if (isset($key)) {
- return $this->conversation->get($key, $default);
- }
-
- return $this->conversation;
- }
-
-}
diff --git a/src/Telegram/InlineKeyboardButton/CallbackPayload.php b/src/Telegram/InlineKeyboardButton/CallbackPayload.php
deleted file mode 100644
index 91170e7..0000000
--- a/src/Telegram/InlineKeyboardButton/CallbackPayload.php
+++ /dev/null
@@ -1,29 +0,0 @@
-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;
- }
-
-}
diff --git a/src/Telegram/InlineKeyboardButton/RemembersCallbackPayload.php b/src/Telegram/InlineKeyboardButton/RemembersCallbackPayload.php
deleted file mode 100644
index 36f1a6f..0000000
--- a/src/Telegram/InlineKeyboardButton/RemembersCallbackPayload.php
+++ /dev/null
@@ -1,56 +0,0 @@
-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;
- }
-
-}
diff --git a/src/Telegram/UsesEffectiveEntities.php b/src/Telegram/UsesEffectiveEntities.php
deleted file mode 100644
index 379dc04..0000000
--- a/src/Telegram/UsesEffectiveEntities.php
+++ /dev/null
@@ -1,47 +0,0 @@
-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;
- }
-
-}
\ No newline at end of file
diff --git a/src/TelegramServiceProvider.php b/src/TelegramServiceProvider.php
deleted file mode 100644
index 1b1ec29..0000000
--- a/src/TelegramServiceProvider.php
+++ /dev/null
@@ -1,157 +0,0 @@
-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);
- }
- }
-}
diff --git a/src/config/config.php b/src/config/config.php
new file mode 100644
index 0000000..aba301c
--- /dev/null
+++ b/src/config/config.php
@@ -0,0 +1,47 @@
+ [
+ 'name' => env('PHP_TELEGRAM_BOT_NAME', ''),
+ 'api_key' => env('PHP_TELEGRAM_BOT_API_KEY', ''),
+ ],
+
+ /**
+ * Database integration
+ */
+ 'database' => [
+ 'enabled' => false,
+ 'connection' => env('DB_CONNECTION', 'mysql'),
+ 'prefix' => env('PHP_TELEGRAM_BOT_TABLE_PREFIX', ''),
+ ],
+
+ 'commands' => [
+ 'before' => true,
+ 'paths' => [
+ // Custom command paths
+ ],
+ 'configs' => [
+ // Custom commands configs
+ ],
+ ],
+
+ 'admins' => [
+ // Admin ids
+ ],
+
+ /**
+ * Request limiter
+ */
+ 'limiter' => [
+ 'enabled' => false,
+ 'interval' => 1,
+ ],
+
+ 'upload_path' => env('PHP_TELEGRAM_BOT_UPLOAD_PATH', ''),
+ 'download_path' => env('PHP_TELEGRAM_BOT_DOWNLOAD_PATH', ''),
+];
diff --git a/src/database/migrations/2018_04_18_193554_create_botan_shortener_table.php b/src/database/migrations/2018_04_18_193554_create_botan_shortener_table.php
new file mode 100644
index 0000000..a397212
--- /dev/null
+++ b/src/database/migrations/2018_04_18_193554_create_botan_shortener_table.php
@@ -0,0 +1,26 @@
+bigInteger('id', true)->unsigned()->comment('Unique identifier for this entry');
+ $table->bigInteger('user_id')->nullable()->index('user_id')->comment('Unique user identifier');
+ $table->text('url')->comment('Original URL');
+ $table->char('short_url')->default('')->comment('Shortened URL');
+ $table->dateTime('created_at')->nullable()->comment('Entry date creation');
+ });
+ }
+
+ public function down(): void
+ {
+ Schema::dropIfExists('botan_shortener');
+ }
+}
diff --git a/src/database/migrations/2018_04_18_193554_create_callback_query_table.php b/src/database/migrations/2018_04_18_193554_create_callback_query_table.php
new file mode 100644
index 0000000..09ef7a8
--- /dev/null
+++ b/src/database/migrations/2018_04_18_193554_create_callback_query_table.php
@@ -0,0 +1,29 @@
+bigInteger('id')->unsigned()->primary()->comment('Unique identifier for this query');
+ $table->bigInteger('user_id')->nullable()->index('user_id')->comment('Unique user identifier');
+ $table->bigInteger('chat_id')->nullable()->index('chat_id')->comment('Unique chat identifier');
+ $table->bigInteger('message_id')->unsigned()->nullable()->index('message_id')->comment('Unique message identifier');
+ $table->char('inline_message_id')->nullable()->comment('Identifier of the message sent via the bot in inline mode, that originated the query');
+ $table->char('data')->default('')->comment('Data associated with the callback button');
+ $table->dateTime('created_at')->nullable()->comment('Entry date creation');
+ $table->index(['chat_id', 'message_id'], 'chat_id_2');
+ });
+ }
+
+ public function down(): void
+ {
+ Schema::dropIfExists('callback_query');
+ }
+}
diff --git a/src/database/migrations/2018_04_18_193554_create_chat_table.php b/src/database/migrations/2018_04_18_193554_create_chat_table.php
new file mode 100644
index 0000000..cba9bf2
--- /dev/null
+++ b/src/database/migrations/2018_04_18_193554_create_chat_table.php
@@ -0,0 +1,28 @@
+bigInteger('id')->primary()->comment('Unique user or chat identifier');
+ $table->enum('type', ['private', 'group', 'supergroup', 'channel'])->comment('Chat type, either private, group, supergroup or channel');
+ $table->char('title')->nullable()->default('')->comment('Chat (group) title, is null if chat type is private');
+ $table->char('username')->nullable()->comment('Username, for private chats, supergroups and channels if available');
+ $table->boolean('all_members_are_administrators')->nullable()->default(0)->comment('True if a all members of this group are admins');
+ $table->timestamps();
+ $table->bigInteger('old_id')->nullable()->index('old_id')->comment('Unique chat identifier, this is filled when a group is converted to a supergroup');
+ });
+ }
+
+ public function down(): void
+ {
+ Schema::dropIfExists('chat');
+ }
+}
diff --git a/src/database/migrations/2018_04_18_193554_create_chosen_inline_result_table.php b/src/database/migrations/2018_04_18_193554_create_chosen_inline_result_table.php
new file mode 100644
index 0000000..194b33b
--- /dev/null
+++ b/src/database/migrations/2018_04_18_193554_create_chosen_inline_result_table.php
@@ -0,0 +1,28 @@
+bigInteger('id', true)->unsigned()->comment('Unique identifier for this entry');
+ $table->char('result_id')->default('')->comment('Identifier for this result');
+ $table->bigInteger('user_id')->nullable()->index('user_id')->comment('Unique user identifier');
+ $table->char('location')->nullable()->comment('Location object, user\'s location');
+ $table->char('inline_message_id')->nullable()->comment('Identifier of the sent inline message');
+ $table->text('query')->comment('The query that was used to obtain the result');
+ $table->dateTime('created_at')->nullable()->comment('Entry date creation');
+ });
+ }
+
+ public function down(): void
+ {
+ Schema::dropIfExists('chosen_inline_result');
+ }
+}
diff --git a/src/database/migrations/2018_04_18_193554_create_conversation_table.php b/src/database/migrations/2018_04_18_193554_create_conversation_table.php
new file mode 100644
index 0000000..c5b5373
--- /dev/null
+++ b/src/database/migrations/2018_04_18_193554_create_conversation_table.php
@@ -0,0 +1,28 @@
+bigInteger('id', true)->unsigned()->comment('Unique identifier for this entry');
+ $table->bigInteger('user_id')->nullable()->index('user_id')->comment('Unique user identifier');
+ $table->bigInteger('chat_id')->nullable()->index('chat_id')->comment('Unique user or chat identifier');
+ $table->enum('status', ['active', 'cancelled', 'stopped'])->default('active')->index('status')->comment('Conversation state');
+ $table->string('command', 160)->nullable()->default('')->comment('Default command to execute');
+ $table->text('notes')->nullable()->comment('Data stored from command');
+ $table->timestamps();
+ });
+ }
+
+ public function down(): void
+ {
+ Schema::dropIfExists('conversation');
+ }
+}
diff --git a/src/database/migrations/2018_04_18_193554_create_edited_message_table.php b/src/database/migrations/2018_04_18_193554_create_edited_message_table.php
new file mode 100644
index 0000000..05ff7f1
--- /dev/null
+++ b/src/database/migrations/2018_04_18_193554_create_edited_message_table.php
@@ -0,0 +1,30 @@
+bigInteger('id', true)->unsigned()->comment('Unique identifier for this entry');
+ $table->bigInteger('chat_id')->nullable()->index('chat_id')->comment('Unique chat identifier');
+ $table->bigInteger('message_id')->unsigned()->nullable()->index('message_id')->comment('Unique message identifier');
+ $table->bigInteger('user_id')->nullable()->index('user_id')->comment('Unique user identifier');
+ $table->dateTime('edit_date')->nullable()->comment('Date the message was edited in timestamp format');
+ $table->text('text')->nullable()->comment('For text messages, the actual UTF-8 text of the message max message length 4096 char utf8');
+ $table->text('entities')->nullable()->comment('For text messages, special entities like usernames, URLs, bot commands, etc. that appear in the text');
+ $table->text('caption')->nullable()->comment('For message with caption, the actual UTF-8 text of the caption');
+ $table->index(['chat_id', 'message_id'], 'chat_id_2');
+ });
+ }
+
+ public function down(): void
+ {
+ Schema::dropIfExists('edited_message');
+ }
+}
diff --git a/src/database/migrations/2018_04_18_193554_create_inline_query_table.php b/src/database/migrations/2018_04_18_193554_create_inline_query_table.php
new file mode 100644
index 0000000..efc00c2
--- /dev/null
+++ b/src/database/migrations/2018_04_18_193554_create_inline_query_table.php
@@ -0,0 +1,27 @@
+bigInteger('id')->unsigned()->primary()->comment('Unique identifier for this query');
+ $table->bigInteger('user_id')->nullable()->index('user_id')->comment('Unique user identifier');
+ $table->char('location')->nullable()->comment('Location of the user');
+ $table->text('query')->comment('Text of the query');
+ $table->char('offset')->nullable()->comment('Offset of the result');
+ $table->dateTime('created_at')->nullable()->comment('Entry date creation');
+ });
+ }
+
+ public function down(): void
+ {
+ Schema::dropIfExists('inline_query');
+ }
+}
diff --git a/src/database/migrations/2018_04_18_193554_create_message_table.php b/src/database/migrations/2018_04_18_193554_create_message_table.php
new file mode 100644
index 0000000..22d8b82
--- /dev/null
+++ b/src/database/migrations/2018_04_18_193554_create_message_table.php
@@ -0,0 +1,59 @@
+bigInteger('chat_id')->comment('Unique chat identifier');
+ $table->bigInteger('id')->unsigned()->comment('Unique message identifier');
+ $table->bigInteger('user_id')->nullable()->index('user_id')->comment('Unique user identifier');
+ $table->dateTime('date')->nullable()->comment('Date the message was sent in timestamp format');
+ $table->bigInteger('forward_from')->nullable()->index('forward_from')->comment('Unique user identifier, sender of the original message');
+ $table->bigInteger('forward_from_chat')->nullable()->index('forward_from_chat')->comment('Unique chat identifier, chat the original message belongs to');
+ $table->bigInteger('forward_from_message_id')->nullable()->comment('Unique chat identifier of the original message in the channel');
+ $table->dateTime('forward_date')->nullable()->comment('date the original message was sent in timestamp format');
+ $table->bigInteger('reply_to_chat')->nullable()->index('reply_to_chat')->comment('Unique chat identifier');
+ $table->bigInteger('reply_to_message')->unsigned()->nullable()->index('reply_to_message')->comment('Message that this message is reply to');
+ $table->text('media_group_id')->nullable()->comment('The unique identifier of a media message group this message belongs to');
+ $table->text('text')->nullable()->comment('For text messages, the actual UTF-8 text of the message max message length 4096 char utf8mb4');
+ $table->text('entities')->nullable()->comment('For text messages, special entities like usernames, URLs, bot commands, etc. that appear in the text');
+ $table->text('audio')->nullable()->comment('Audio object. Message is an audio file, information about the file');
+ $table->text('document')->nullable()->comment('Document object. Message is a general file, information about the file');
+ $table->text('photo')->nullable()->comment('Array of PhotoSize objects. Message is a photo, available sizes of the photo');
+ $table->text('sticker')->nullable()->comment('Sticker object. Message is a sticker, information about the sticker');
+ $table->text('video')->nullable()->comment('Video object. Message is a video, information about the video');
+ $table->text('voice')->nullable()->comment('Voice Object. Message is a Voice, information about the Voice');
+ $table->text('video_note')->nullable()->comment('VoiceNote Object. Message is a Video Note, information about the Video Note');
+ $table->text('contact')->nullable()->comment('Contact object. Message is a shared contact, information about the contact');
+ $table->text('location')->nullable()->comment('Location object. Message is a shared location, information about the location');
+ $table->text('venue')->nullable()->comment('Venue object. Message is a Venue, information about the Venue');
+ $table->text('caption')->nullable()->comment('For message with caption, the actual UTF-8 text of the caption');
+ $table->text('new_chat_members')->nullable()->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)');
+ $table->bigInteger('left_chat_member')->nullable()->index('left_chat_member')->comment('Unique user identifier, a member was removed from the group, information about them (this member may be the bot itself)');
+ $table->char('new_chat_title')->nullable()->comment('A chat title was changed to this value');
+ $table->text('new_chat_photo')->nullable()->comment('Array of PhotoSize objects. A chat photo was change to this value');
+ $table->boolean('delete_chat_photo')->nullable()->default(0)->comment('Informs that the chat photo was deleted');
+ $table->boolean('group_chat_created')->nullable()->default(0)->comment('Informs that the group has been created');
+ $table->boolean('supergroup_chat_created')->nullable()->default(0)->comment('Informs that the supergroup has been created');
+ $table->boolean('channel_chat_created')->nullable()->default(0)->comment('Informs that the channel chat has been created');
+ $table->bigInteger('migrate_to_chat_id')->nullable()->index('migrate_to_chat_id')->comment('Migrate to chat identifier. The group has been migrated to a supergroup with the specified identifier');
+ $table->bigInteger('migrate_from_chat_id')->nullable()->index('migrate_from_chat_id')->comment('Migrate from chat identifier. The supergroup has been migrated from a group with the specified identifier');
+ $table->text('pinned_message')->nullable()->comment('Message object. Specified message was pinned');
+ $table->text('connected_website')->nullable()->comment('The domain name of the website on which the user has logged in.');
+ $table->primary(['chat_id', 'id']);
+ $table->index(['reply_to_chat', 'reply_to_message'], 'reply_to_chat_2');
+ });
+ }
+
+ public function down(): void
+ {
+ Schema::dropIfExists('message');
+ }
+}
diff --git a/src/database/migrations/2018_04_18_193554_create_request_limiter_table.php b/src/database/migrations/2018_04_18_193554_create_request_limiter_table.php
new file mode 100644
index 0000000..f048b52
--- /dev/null
+++ b/src/database/migrations/2018_04_18_193554_create_request_limiter_table.php
@@ -0,0 +1,26 @@
+bigInteger('id', true)->unsigned()->comment('Unique identifier for this entry');
+ $table->char('chat_id')->nullable()->comment('Unique chat identifier');
+ $table->char('inline_message_id')->nullable()->comment('Identifier of the sent inline message');
+ $table->char('method')->nullable()->comment('Request method');
+ $table->dateTime('created_at')->nullable()->comment('Entry date creation');
+ });
+ }
+
+ public function down(): void
+ {
+ Schema::dropIfExists('request_limiter');
+ }
+}
diff --git a/src/database/migrations/2018_04_18_193554_create_telegram_update_table.php b/src/database/migrations/2018_04_18_193554_create_telegram_update_table.php
new file mode 100644
index 0000000..59b8e05
--- /dev/null
+++ b/src/database/migrations/2018_04_18_193554_create_telegram_update_table.php
@@ -0,0 +1,29 @@
+bigInteger('id')->unsigned()->primary()->comment('Update\'s unique identifier');
+ $table->bigInteger('chat_id')->nullable()->comment('Unique chat identifier');
+ $table->bigInteger('message_id')->unsigned()->nullable()->comment('Unique message identifier');
+ $table->bigInteger('inline_query_id')->unsigned()->nullable()->index('inline_query_id')->comment('Unique inline query identifier');
+ $table->bigInteger('chosen_inline_result_id')->unsigned()->nullable()->index('chosen_inline_result_id')->comment('Local chosen inline result identifier');
+ $table->bigInteger('callback_query_id')->unsigned()->nullable()->index('callback_query_id')->comment('Unique callback query identifier');
+ $table->bigInteger('edited_message_id')->unsigned()->nullable()->index('edited_message_id')->comment('Local edited message identifier');
+ $table->index(['chat_id', 'message_id'], 'message_id');
+ });
+ }
+
+ public function down(): void
+ {
+ Schema::dropIfExists('telegram_update');
+ }
+}
diff --git a/src/database/migrations/2018_04_18_193554_create_user_chat_table.php b/src/database/migrations/2018_04_18_193554_create_user_chat_table.php
new file mode 100644
index 0000000..a604e60
--- /dev/null
+++ b/src/database/migrations/2018_04_18_193554_create_user_chat_table.php
@@ -0,0 +1,24 @@
+bigInteger('user_id')->comment('Unique user identifier');
+ $table->bigInteger('chat_id')->index('chat_id')->comment('Unique user or chat identifier');
+ $table->primary(['user_id', 'chat_id']);
+ });
+ }
+
+ public function down(): void
+ {
+ Schema::dropIfExists('user_chat');
+ }
+}
diff --git a/src/database/migrations/2018_04_18_193554_create_user_table.php b/src/database/migrations/2018_04_18_193554_create_user_table.php
new file mode 100644
index 0000000..a2d4d9e
--- /dev/null
+++ b/src/database/migrations/2018_04_18_193554_create_user_table.php
@@ -0,0 +1,28 @@
+bigInteger('id')->primary()->comment('Unique user identifier');
+ $table->boolean('is_bot')->nullable()->default(0)->comment('True if this user is a bot');
+ $table->char('first_name')->default('')->comment('User\'s first name');
+ $table->char('last_name')->nullable()->comment('User\'s last name');
+ $table->char('username', 191)->nullable()->index('username')->comment('User\'s username');
+ $table->char('language_code', 10)->nullable()->comment('User\'s system language');
+ $table->timestamps();
+ });
+ }
+
+ public function down(): void
+ {
+ Schema::dropIfExists('user');
+ }
+}
diff --git a/src/database/migrations/2018_04_18_193555_add_foreign_keys_to_botan_shortener_table.php b/src/database/migrations/2018_04_18_193555_add_foreign_keys_to_botan_shortener_table.php
new file mode 100644
index 0000000..1dc1d61
--- /dev/null
+++ b/src/database/migrations/2018_04_18_193555_add_foreign_keys_to_botan_shortener_table.php
@@ -0,0 +1,24 @@
+foreign('user_id', 'botan_shortener_ibfk_1')->references('id')->on('user')->onUpdate('RESTRICT')->onDelete('RESTRICT');
+ });
+ }
+
+ public function down(): void
+ {
+ Schema::table('botan_shortener', static function (Blueprint $table) {
+ $table->dropForeign('botan_shortener_ibfk_1');
+ });
+ }
+}
diff --git a/src/database/migrations/2018_04_18_193555_add_foreign_keys_to_callback_query_table.php b/src/database/migrations/2018_04_18_193555_add_foreign_keys_to_callback_query_table.php
new file mode 100644
index 0000000..0e8aee4
--- /dev/null
+++ b/src/database/migrations/2018_04_18_193555_add_foreign_keys_to_callback_query_table.php
@@ -0,0 +1,26 @@
+foreign('user_id', 'callback_query_ibfk_1')->references('id')->on('user')->onUpdate('RESTRICT')->onDelete('RESTRICT');
+ $table->foreign('chat_id', 'callback_query_ibfk_2')->references('chat_id')->on('message')->onUpdate('RESTRICT')->onDelete('RESTRICT');
+ });
+ }
+
+ public function down(): void
+ {
+ Schema::table('callback_query', static function (Blueprint $table) {
+ $table->dropForeign('callback_query_ibfk_1');
+ $table->dropForeign('callback_query_ibfk_2');
+ });
+ }
+}
diff --git a/src/database/migrations/2018_04_18_193555_add_foreign_keys_to_chosen_inline_result_table.php b/src/database/migrations/2018_04_18_193555_add_foreign_keys_to_chosen_inline_result_table.php
new file mode 100644
index 0000000..bfe0690
--- /dev/null
+++ b/src/database/migrations/2018_04_18_193555_add_foreign_keys_to_chosen_inline_result_table.php
@@ -0,0 +1,24 @@
+foreign('user_id', 'chosen_inline_result_ibfk_1')->references('id')->on('user')->onUpdate('RESTRICT')->onDelete('RESTRICT');
+ });
+ }
+
+ public function down(): void
+ {
+ Schema::table('chosen_inline_result', static function (Blueprint $table) {
+ $table->dropForeign('chosen_inline_result_ibfk_1');
+ });
+ }
+}
diff --git a/src/database/migrations/2018_04_18_193555_add_foreign_keys_to_conversation_table.php b/src/database/migrations/2018_04_18_193555_add_foreign_keys_to_conversation_table.php
new file mode 100644
index 0000000..521a5fa
--- /dev/null
+++ b/src/database/migrations/2018_04_18_193555_add_foreign_keys_to_conversation_table.php
@@ -0,0 +1,26 @@
+foreign('user_id', 'conversation_ibfk_1')->references('id')->on('user')->onUpdate('RESTRICT')->onDelete('RESTRICT');
+ $table->foreign('chat_id', 'conversation_ibfk_2')->references('id')->on('chat')->onUpdate('RESTRICT')->onDelete('RESTRICT');
+ });
+ }
+
+ public function down(): void
+ {
+ Schema::table('conversation', static function (Blueprint $table) {
+ $table->dropForeign('conversation_ibfk_1');
+ $table->dropForeign('conversation_ibfk_2');
+ });
+ }
+}
diff --git a/src/database/migrations/2018_04_18_193555_add_foreign_keys_to_edited_message_table.php b/src/database/migrations/2018_04_18_193555_add_foreign_keys_to_edited_message_table.php
new file mode 100644
index 0000000..625dcb7
--- /dev/null
+++ b/src/database/migrations/2018_04_18_193555_add_foreign_keys_to_edited_message_table.php
@@ -0,0 +1,28 @@
+foreign('chat_id', 'edited_message_ibfk_1')->references('id')->on('chat')->onUpdate('RESTRICT')->onDelete('RESTRICT');
+ $table->foreign('chat_id', 'edited_message_ibfk_2')->references('chat_id')->on('message')->onUpdate('RESTRICT')->onDelete('RESTRICT');
+ $table->foreign('user_id', 'edited_message_ibfk_3')->references('id')->on('user')->onUpdate('RESTRICT')->onDelete('RESTRICT');
+ });
+ }
+
+ public function down(): void
+ {
+ Schema::table('edited_message', static function (Blueprint $table) {
+ $table->dropForeign('edited_message_ibfk_1');
+ $table->dropForeign('edited_message_ibfk_2');
+ $table->dropForeign('edited_message_ibfk_3');
+ });
+ }
+}
diff --git a/src/database/migrations/2018_04_18_193555_add_foreign_keys_to_inline_query_table.php b/src/database/migrations/2018_04_18_193555_add_foreign_keys_to_inline_query_table.php
new file mode 100644
index 0000000..25a712e
--- /dev/null
+++ b/src/database/migrations/2018_04_18_193555_add_foreign_keys_to_inline_query_table.php
@@ -0,0 +1,24 @@
+foreign('user_id', 'inline_query_ibfk_1')->references('id')->on('user')->onUpdate('RESTRICT')->onDelete('RESTRICT');
+ });
+ }
+
+ public function down(): void
+ {
+ Schema::table('inline_query', static function (Blueprint $table) {
+ $table->dropForeign('inline_query_ibfk_1');
+ });
+ }
+}
diff --git a/src/database/migrations/2018_04_18_193555_add_foreign_keys_to_message_table.php b/src/database/migrations/2018_04_18_193555_add_foreign_keys_to_message_table.php
new file mode 100644
index 0000000..eb66df2
--- /dev/null
+++ b/src/database/migrations/2018_04_18_193555_add_foreign_keys_to_message_table.php
@@ -0,0 +1,36 @@
+foreign('user_id', 'message_ibfk_1')->references('id')->on('user')->onUpdate('RESTRICT')->onDelete('RESTRICT');
+ $table->foreign('chat_id', 'message_ibfk_2')->references('id')->on('chat')->onUpdate('RESTRICT')->onDelete('RESTRICT');
+ $table->foreign('forward_from', 'message_ibfk_3')->references('id')->on('user')->onUpdate('RESTRICT')->onDelete('RESTRICT');
+ $table->foreign('forward_from_chat', 'message_ibfk_4')->references('id')->on('chat')->onUpdate('RESTRICT')->onDelete('RESTRICT');
+ $table->foreign('reply_to_chat', 'message_ibfk_5')->references('chat_id')->on('message')->onUpdate('RESTRICT')->onDelete('RESTRICT');
+ $table->foreign('forward_from', 'message_ibfk_6')->references('id')->on('user')->onUpdate('RESTRICT')->onDelete('RESTRICT');
+ $table->foreign('left_chat_member', 'message_ibfk_7')->references('id')->on('user')->onUpdate('RESTRICT')->onDelete('RESTRICT');
+ });
+ }
+
+ public function down(): void
+ {
+ Schema::table('message', static function (Blueprint $table) {
+ $table->dropForeign('message_ibfk_1');
+ $table->dropForeign('message_ibfk_2');
+ $table->dropForeign('message_ibfk_3');
+ $table->dropForeign('message_ibfk_4');
+ $table->dropForeign('message_ibfk_5');
+ $table->dropForeign('message_ibfk_6');
+ $table->dropForeign('message_ibfk_7');
+ });
+ }
+}
diff --git a/src/database/migrations/2018_04_18_193555_add_foreign_keys_to_telegram_update_table.php b/src/database/migrations/2018_04_18_193555_add_foreign_keys_to_telegram_update_table.php
new file mode 100644
index 0000000..503e108
--- /dev/null
+++ b/src/database/migrations/2018_04_18_193555_add_foreign_keys_to_telegram_update_table.php
@@ -0,0 +1,32 @@
+foreign('chat_id', 'telegram_update_ibfk_1')->references('chat_id')->on('message')->onUpdate('RESTRICT')->onDelete('RESTRICT');
+ $table->foreign('inline_query_id', 'telegram_update_ibfk_2')->references('id')->on('inline_query')->onUpdate('RESTRICT')->onDelete('RESTRICT');
+ $table->foreign('chosen_inline_result_id', 'telegram_update_ibfk_3')->references('id')->on('chosen_inline_result')->onUpdate('RESTRICT')->onDelete('RESTRICT');
+ $table->foreign('callback_query_id', 'telegram_update_ibfk_4')->references('id')->on('callback_query')->onUpdate('RESTRICT')->onDelete('RESTRICT');
+ $table->foreign('edited_message_id', 'telegram_update_ibfk_5')->references('id')->on('edited_message')->onUpdate('RESTRICT')->onDelete('RESTRICT');
+ });
+ }
+
+ public function down(): void
+ {
+ Schema::table('telegram_update', static function (Blueprint $table) {
+ $table->dropForeign('telegram_update_ibfk_1');
+ $table->dropForeign('telegram_update_ibfk_2');
+ $table->dropForeign('telegram_update_ibfk_3');
+ $table->dropForeign('telegram_update_ibfk_4');
+ $table->dropForeign('telegram_update_ibfk_5');
+ });
+ }
+}
diff --git a/src/database/migrations/2018_04_18_193555_add_foreign_keys_to_user_chat_table.php b/src/database/migrations/2018_04_18_193555_add_foreign_keys_to_user_chat_table.php
new file mode 100644
index 0000000..dea8f62
--- /dev/null
+++ b/src/database/migrations/2018_04_18_193555_add_foreign_keys_to_user_chat_table.php
@@ -0,0 +1,26 @@
+foreign('user_id', 'user_chat_ibfk_1')->references('id')->on('user')->onUpdate('CASCADE')->onDelete('CASCADE');
+ $table->foreign('chat_id', 'user_chat_ibfk_2')->references('id')->on('chat')->onUpdate('CASCADE')->onDelete('CASCADE');
+ });
+ }
+
+ public function down(): void
+ {
+ Schema::table('user_chat', static function (Blueprint $table) {
+ $table->dropForeign('user_chat_ibfk_1');
+ $table->dropForeign('user_chat_ibfk_2');
+ });
+ }
+}
diff --git a/src/database/migrations/2020_05_18_000000_add_prefix_to_tables.php b/src/database/migrations/2020_05_18_000000_add_prefix_to_tables.php
new file mode 100644
index 0000000..a620bfa
--- /dev/null
+++ b/src/database/migrations/2020_05_18_000000_add_prefix_to_tables.php
@@ -0,0 +1,58 @@
+tables as $table) {
+ try {
+ if (Schema::hasTable($this->prefix . $table)) {
+ Log::warning("Prefixed table '{$this->prefix}{$table}' already exists. Verify your migration status.");
+ continue; // Migration may be partly done already...
+ }
+
+ Schema::rename($table, $this->prefix . $table);
+ } catch (Throwable $e) {
+ Log::error($e->getMessage());
+ }
+ }
+ }
+
+ public function down(): void
+ {
+ foreach ($this->tables as $table) {
+ try {
+ if (Schema::hasTable($table)) {
+ Log::warning("Un-prefixed table '{$table}' already exists. Verify your migration status.");
+ continue; // Migration may be partly done already...
+ }
+
+ Schema::rename($this->prefix . $table, $table);
+ } catch (Throwable $e) {
+ Log::error($e->getMessage());
+ }
+ }
+ }
+}
diff --git a/src/database/migrations/2020_05_18_000000_update_schema_0_53_0_to_0_54_0.php b/src/database/migrations/2020_05_18_000000_update_schema_0_53_0_to_0_54_0.php
new file mode 100644
index 0000000..f7a7c90
--- /dev/null
+++ b/src/database/migrations/2020_05_18_000000_update_schema_0_53_0_to_0_54_0.php
@@ -0,0 +1,35 @@
+prefix . 'message', static function (Blueprint $table) {
+ $table->text('game')->nullable()->comment('Message is a game, information about the game.')->after('document');
+ });
+ } catch (Throwable $e) {
+ Log::error($e->getMessage());
+ return; // Migration may be partly done already...
+ }
+ }
+
+ public function down(): void
+ {
+ try {
+ Schema::table($this->prefix . 'message', static function (Blueprint $table) {
+ $table->dropColumn('game');
+ });
+ } catch (Throwable $e) {
+ Log::error($e->getMessage());
+ return; // Migration may be partly done already...
+ }
+ }
+}
diff --git a/src/database/migrations/2020_05_18_000000_update_schema_0_54_1_to_0_55_0.php b/src/database/migrations/2020_05_18_000000_update_schema_0_54_1_to_0_55_0.php
new file mode 100644
index 0000000..b5e736e
--- /dev/null
+++ b/src/database/migrations/2020_05_18_000000_update_schema_0_54_1_to_0_55_0.php
@@ -0,0 +1,37 @@
+prefix . 'message', static function (Blueprint $table) {
+ $table->text('animation')->nullable()->comment('Message is an animation, information about the animation')->after('document');
+ $table->text('passport_data')->nullable()->comment('Telegram Passport data')->after('connected_website');
+ });
+ } catch (Throwable $e) {
+ Log::error($e->getMessage());
+ return; // Migration may be partly done already...
+ }
+ }
+
+ public function down(): void
+ {
+ try {
+ Schema::table($this->prefix . 'message', static function (Blueprint $table) {
+ $table->dropColumn('passport_data');
+ $table->dropColumn('animation');
+ });
+ } catch (Throwable $e) {
+ Log::error($e->getMessage());
+ return; // Migration may be partly done already...
+ }
+ }
+}
diff --git a/src/database/migrations/2020_05_18_000000_update_schema_0_56_0_to_0_57_0.php b/src/database/migrations/2020_05_18_000000_update_schema_0_56_0_to_0_57_0.php
new file mode 100644
index 0000000..90a1eca
--- /dev/null
+++ b/src/database/migrations/2020_05_18_000000_update_schema_0_56_0_to_0_57_0.php
@@ -0,0 +1,142 @@
+prefix . 'shipping_query', function (Blueprint $table) {
+ $table->bigInteger('id')->unsigned()->primary()->comment('Unique query identifier');
+ $table->bigInteger('user_id')->index('user_id')->comment('User who sent the query');
+ $table->char('invoice_payload', 255)->default('')->comment('Bot specified invoice payload');
+ $table->char('shipping_address', 255)->default('')->comment('User specified shipping address');
+ $table->timestamp('created_at')->nullable()->comment('Entry date creation');
+ $table->foreign('user_id', 'shipping_query_ibfk_1')->references('id')->on($this->prefix . 'user')->onUpdate('RESTRICT')->onDelete('RESTRICT');
+ });
+
+ Schema::create($this->prefix . 'pre_checkout_query', function (Blueprint $table) {
+ $table->bigInteger('id')->unsigned()->primary()->comment('Unique query identifier');
+ $table->bigInteger('user_id')->index('user_id')->comment('User who sent the query');
+ $table->char('currency', 3)->comment('Three-letter ISO 4217 currency code');
+ $table->bigInteger('total_amount')->comment('Total price in the smallest units of the currency');
+ $table->char('invoice_payload', 255)->default('')->comment('Bot specified invoice payload');
+ $table->char('shipping_option_id', 255)->nullable()->comment('Identifier of the shipping option chosen by the user');
+ $table->text('order_info')->nullable()->comment('Order info provided by the user');
+ $table->timestamp('created_at')->nullable()->comment('Entry date creation');
+ $table->foreign('user_id', 'pre_checkout_query_ibfk_1')->references('id')->on($this->prefix . 'user')->onUpdate('RESTRICT')->onDelete('RESTRICT');
+ });
+
+ Schema::create($this->prefix . 'poll', static function (Blueprint $table) {
+ $table->bigInteger('id')->unsigned()->primary()->comment('Unique poll identifier');
+ $table->char('question', 255)->comment('Poll question');
+ $table->text('options')->comment('List of poll options');
+ $table->boolean('is_closed')->default(0)->comment('True, if the poll is closed');
+ $table->timestamp('created_at')->nullable()->comment('Entry date creation');
+ });
+
+ Schema::table($this->prefix . 'callback_query', static function (Blueprint $table) {
+ $table->char('chat_instance', 255)->default('')->comment('Global identifier, uniquely corresponding to the chat to which the message with the callback button was sent')->after('inline_message_id');
+ $table->char('game_short_name', 255)->default('')->comment('Short name of a Game to be returned, serves as the unique identifier for the game')->after('data');
+ });
+
+ Schema::table($this->prefix . 'chat', static function (Blueprint $table) {
+ $table->char('first_name', 255)->nullable()->comment('First name of the other party in a private chat')->after('username');
+ $table->char('last_name', 255)->nullable()->comment('Last name of the other party in a private chat')->after('first_name');
+ });
+
+ Schema::table($this->prefix . 'message', static function (Blueprint $table) {
+ $table->text('forward_signature')->nullable()->default(null)->comment('For messages forwarded from channels, signature of the post author if present')->after('forward_from_message_id');
+ $table->text('forward_sender_name')->nullable()->default(null)->comment('Sender\'s name for messages forwarded from users who disallow adding a link to their account in forwarded messages')->after('forward_signature');
+ $table->unsignedBigInteger('edit_date')->nullable()->comment('Date the message was last edited in Unix time')->after('reply_to_message');
+ $table->text('author_signature')->nullable()->comment('Signature of the post author for messages in channels')->after('media_group_id');
+ $table->text('caption_entities')->nullable()->comment('For messages with a caption, special entities like usernames, URLs, bot commands, etc. that appear in the caption')->after('entities');
+ $table->text('poll')->nullable()->comment('Poll object. Message is a native poll, information about the poll')->after('venue');
+ $table->text('invoice')->nullable()->comment('Message is an invoice for a payment, information about the invoice')->after('pinned_message');
+ $table->text('successful_payment')->nullable()->comment('Message is a service message about a successful payment, information about the payment')->after('invoice');
+ });
+
+ Schema::table($this->prefix . 'telegram_update', function (Blueprint $table) {
+ $table->bigInteger('channel_post_id')->unsigned()->nullable()->comment('New incoming channel post of any kind - text, photo, sticker, etc.');
+ $table->bigInteger('edited_channel_post_id')->unsigned()->nullable()->comment('New version of a channel post that is known to the bot and was edited');
+ $table->bigInteger('shipping_query_id')->unsigned()->nullable()->comment('New incoming shipping query. Only for invoices with flexible price');
+ $table->bigInteger('pre_checkout_query_id')->unsigned()->nullable()->comment('New incoming pre-checkout query. Contains full information about checkout');
+ $table->bigInteger('poll_id')->unsigned()->nullable()->comment('New poll state. Bots receive only updates about polls, which are sent or stopped by the bot');
+
+ $table->index('channel_post_id', 'channel_post_id');
+ $table->index('edited_channel_post_id', 'edited_channel_post_id');
+ $table->index('shipping_query_id', 'shipping_query_id');
+ $table->index('pre_checkout_query_id', 'pre_checkout_query_id');
+ $table->index('poll_id', 'poll_id');
+
+ $table->foreign(['chat_id', 'channel_post_id'], 'telegram_update_ibfk_6')->references(['chat_id', 'id'])->on($this->prefix . 'message');
+ $table->foreign('edited_channel_post_id', 'telegram_update_ibfk_7')->references('id')->on($this->prefix . 'edited_message');
+ $table->foreign('shipping_query_id', 'telegram_update_ibfk_8')->references('id')->on($this->prefix . 'shipping_query');
+ $table->foreign('pre_checkout_query_id', 'telegram_update_ibfk_9')->references('id')->on($this->prefix . 'pre_checkout_query');
+ $table->foreign('poll_id', 'telegram_update_ibfk_10')->references('id')->on($this->prefix . 'poll');
+ });
+ } catch (Throwable $e) {
+ Log::error($e->getMessage());
+ return; // Migration may be partly done already...
+ }
+ }
+
+ public function down(): void
+ {
+ try {
+ Schema::table($this->prefix . 'telegram_update', static function (Blueprint $table) {
+ $table->dropForeign('telegram_update_ibfk_10');
+ $table->dropForeign('telegram_update_ibfk_9');
+ $table->dropForeign('telegram_update_ibfk_8');
+ $table->dropForeign('telegram_update_ibfk_7');
+ $table->dropForeign('telegram_update_ibfk_6');
+
+ $table->dropIndex('poll_id');
+ $table->dropIndex('pre_checkout_query_id');
+ $table->dropIndex('shipping_query_id');
+ $table->dropIndex('edited_channel_post_id');
+ $table->dropIndex('channel_post_id');
+
+ $table->dropColumn('poll_id');
+ $table->dropColumn('pre_checkout_query_id');
+ $table->dropColumn('shipping_query_id');
+ $table->dropColumn('edited_channel_post_id');
+ $table->dropColumn('channel_post_id');
+ });
+
+ Schema::table($this->prefix . 'message', static function (Blueprint $table) {
+ $table->dropColumn('successful_payment');
+ $table->dropColumn('invoice');
+ $table->dropColumn('poll');
+ $table->dropColumn('caption_entities');
+ $table->dropColumn('author_signature');
+ $table->dropColumn('edit_date');
+ $table->dropColumn('forward_sender_name');
+ $table->dropColumn('forward_signature');
+ });
+
+ Schema::table($this->prefix . 'chat', static function (Blueprint $table) {
+ $table->dropColumn('last_name');
+ $table->dropColumn('first_name');
+ });
+
+ Schema::table($this->prefix . 'callback_query', static function (Blueprint $table) {
+ $table->dropColumn('game_short_name');
+ $table->dropColumn('chat_instance');
+ });
+
+ Schema::dropIfExists($this->prefix . 'poll');
+ Schema::dropIfExists($this->prefix . 'pre_checkout_query');
+ Schema::dropIfExists($this->prefix . 'shipping_query');
+ } catch (Throwable $e) {
+ Log::error($e->getMessage());
+ return; // Migration may be partly done already...
+ }
+ }
+}
diff --git a/src/database/migrations/2020_05_18_000000_update_schema_0_57_0_to_0_58_0.php b/src/database/migrations/2020_05_18_000000_update_schema_0_57_0_to_0_58_0.php
new file mode 100644
index 0000000..57c23ed
--- /dev/null
+++ b/src/database/migrations/2020_05_18_000000_update_schema_0_57_0_to_0_58_0.php
@@ -0,0 +1,45 @@
+prefix . 'botan_shortener');
+ Schema::table($this->prefix . 'message', static function (Blueprint $table) {
+ $table->text('reply_markup')->nullable()->comment('Inline keyboard attached to the message')->after('passport_data');
+ });
+ } catch (Throwable $e) {
+ Log::error($e->getMessage());
+ return; // Migration may be partly done already...
+ }
+ }
+
+ public function down(): void
+ {
+ try {
+ Schema::create('botan_shortener', function (Blueprint $table) {
+ $table->bigInteger('id', true)->unsigned()->comment('Unique identifier for this entry');
+ $table->bigInteger('user_id')->nullable()->index('user_id')->comment('Unique user identifier');
+ $table->text('url')->comment('Original URL');
+ $table->char('short_url')->default('')->comment('Shortened URL');
+ $table->timestamp('created_at')->nullable()->comment('Entry date creation');
+ $table->foreign('user_id', 'botan_shortener_ibfk_1')->references('id')->on($this->prefix . 'user')->onUpdate('RESTRICT')->onDelete('RESTRICT');
+ });
+
+ Schema::table($this->prefix . 'message', static function (Blueprint $table) {
+ $table->dropColumn('reply_markup');
+ });
+ } catch (Throwable $e) {
+ Log::error($e->getMessage());
+ return; // Migration may be partly done already...
+ }
+ }
+}
diff --git a/src/database/migrations/2020_05_18_000000_update_schema_0_60_0_to_0_61_0.php b/src/database/migrations/2020_05_18_000000_update_schema_0_60_0_to_0_61_0.php
new file mode 100644
index 0000000..5c7e6b5
--- /dev/null
+++ b/src/database/migrations/2020_05_18_000000_update_schema_0_60_0_to_0_61_0.php
@@ -0,0 +1,47 @@
+prefix . 'telegram_update', static function (Blueprint $table) {
+ $table->dropIndex('message_id');
+ $table->index('message_id', 'message_id');
+ $table->index(['chat_id', 'message_id'], 'chat_message_id');
+ });
+ } catch (Throwable $e) {
+ Log::error($e->getMessage());
+ return; // Migration may be partly done already...
+ }
+
+ Schema::enableForeignKeyConstraints();
+ }
+
+ public function down(): void
+ {
+ Schema::disableForeignKeyConstraints();
+
+ try {
+ Schema::table($this->prefix . 'telegram_update', static function (Blueprint $table) {
+ $table->dropIndex('chat_message_id');
+ $table->dropIndex('message_id');
+ $table->index('message_id', 'message_id');
+ });
+ } catch (Throwable $e) {
+ Log::error($e->getMessage());
+ return; // Migration may be partly done already...
+ }
+
+ Schema::enableForeignKeyConstraints();
+ }
+}
diff --git a/src/database/migrations/2020_05_18_000000_update_schema_0_61_1_to_0_62_0.php b/src/database/migrations/2020_05_18_000000_update_schema_0_61_1_to_0_62_0.php
new file mode 100644
index 0000000..65c4f8f
--- /dev/null
+++ b/src/database/migrations/2020_05_18_000000_update_schema_0_61_1_to_0_62_0.php
@@ -0,0 +1,74 @@
+prefix . 'poll', static function (Blueprint $table) {
+ $table->integer('total_voter_count')->unsigned()->nullable()->comment('Total number of users that voted in the poll')->after('options');
+ $table->boolean('is_anonymous')->default(1)->comment('True, if the poll is anonymous')->after('is_closed');
+ $table->char('type', 255)->comment('Poll type, currently can be "regular" or "quiz"')->after('is_anonymous');
+ $table->boolean('allows_multiple_answers')->default(0)->comment('True, if the poll allows multiple answers')->after('type');
+ $table->integer('correct_option_id')->unsigned()->nullable()->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.')->after('allows_multiple_answers');
+ });
+
+ Schema::table($this->prefix . 'message', static function (Blueprint $table) {
+ $table->text('dice')->nullable()->comment('Message is a dice with random value from 1 to 6')->after('poll');
+ });
+
+ Schema::create($this->prefix . 'poll_answer', function (Blueprint $table) {
+ $table->bigInteger('poll_id')->unsigned()->comment('Unique poll identifier');
+ $table->bigInteger('user_id')->comment('The user, who changed the answer to the poll');
+ $table->text('option_ids')->comment('0-based identifiers of answer options, chosen by the user. May be empty if the user retracted their vote.');
+ $table->timestamp('created_at')->nullable()->comment('Entry date creation');
+ $table->primary(['poll_id', 'user_id']);
+ $table->foreign('poll_id', 'poll_answer_ibfk_1')->references('id')->on($this->prefix . 'poll')->onUpdate('RESTRICT')->onDelete('RESTRICT');
+ });
+
+ Schema::table($this->prefix . 'telegram_update', function (Blueprint $table) {
+ $table->bigInteger('poll_answer_poll_id')->unsigned()->nullable()->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.')->after('poll_id');
+ $table->index('poll_answer_poll_id', 'poll_answer_poll_id');
+ $table->foreign('poll_answer_poll_id', 'telegram_update_ibfk_11')->references('poll_id')->on($this->prefix . 'poll_answer')->onUpdate('RESTRICT')->onDelete('RESTRICT');
+ });
+ } catch (Throwable $e) {
+ Log::error($e->getMessage());
+ return; // Migration may be partly done already...
+ }
+ }
+
+ public function down(): void
+ {
+ try {
+ Schema::table($this->prefix . 'telegram_update', static function (Blueprint $table) {
+ $table->dropForeign('telegram_update_ibfk_11');
+ $table->dropIndex('poll_answer_poll_id');
+ $table->dropColumn('poll_answer_poll_id');
+ });
+
+ Schema::dropIfExists($this->prefix . 'poll_answer');
+
+ Schema::table($this->prefix . 'message', static function (Blueprint $table) {
+ $table->dropColumn('dice');
+ });
+
+ Schema::table($this->prefix . 'poll', static function (Blueprint $table) {
+ $table->dropColumn('correct_option_id');
+ $table->dropColumn('allows_multiple_answers');
+ $table->dropColumn('type');
+ $table->dropColumn('is_anonymous');
+ $table->dropColumn('total_voter_count');
+ });
+ } catch (Throwable $e) {
+ Log::error($e->getMessage());
+ return; // Migration may be partly done already...
+ }
+ }
+}
diff --git a/src/database/migrations/2020_05_18_000000_update_schema_fixes.php b/src/database/migrations/2020_05_18_000000_update_schema_fixes.php
new file mode 100644
index 0000000..6d0db95
--- /dev/null
+++ b/src/database/migrations/2020_05_18_000000_update_schema_fixes.php
@@ -0,0 +1,59 @@
+prefix . 'callback_query', function (Blueprint $table) {
+ $table->dropForeign('callback_query_ibfk_2');
+ $table->foreign(['chat_id', 'message_id'], 'callback_query_ibfk_2')->references(['chat_id', 'id'])->on($this->prefix . 'message')->onUpdate('RESTRICT')->onDelete('RESTRICT');
+ });
+
+ Schema::table($this->prefix . 'edited_message', function (Blueprint $table) {
+ $table->dropForeign('edited_message_ibfk_2');
+ $table->foreign(['chat_id', 'message_id'], 'edited_message_ibfk_2')->references(['chat_id', 'id'])->on($this->prefix . 'message')->onUpdate('RESTRICT')->onDelete('RESTRICT');
+ });
+
+ Schema::table($this->prefix . 'message', function (Blueprint $table) {
+ $table->dropForeign('message_ibfk_5');
+ $table->dropForeign('message_ibfk_6');
+ $table->foreign(['reply_to_chat', 'reply_to_message'], 'message_ibfk_5')->references(['chat_id', 'id'])->on($this->prefix . 'message')->onUpdate('RESTRICT')->onDelete('RESTRICT');
+ });
+ } catch (Throwable $e) {
+ Log::error($e->getMessage());
+ return; // Migration may be partly done already...
+ }
+ }
+
+ public function down(): void
+ {
+ try {
+ Schema::table($this->prefix . 'callback_query', function (Blueprint $table) {
+ $table->dropForeign('callback_query_ibfk_2');
+ $table->foreign('chat_id', 'callback_query_ibfk_2')->references('chat_id')->on($this->prefix . 'message')->onUpdate('RESTRICT')->onDelete('RESTRICT');
+ });
+
+ Schema::table($this->prefix . 'edited_message', function (Blueprint $table) {
+ $table->dropForeign('edited_message_ibfk_2');
+ $table->foreign('chat_id', 'edited_message_ibfk_2')->references('chat_id')->on($this->prefix . 'message')->onUpdate('RESTRICT')->onDelete('RESTRICT');
+ });
+
+ Schema::table($this->prefix . 'message', function (Blueprint $table) {
+ $table->dropForeign('message_ibfk_5');
+ $table->foreign('reply_to_chat', 'message_ibfk_5')->references('chat_id')->on($this->prefix . 'message')->onUpdate('RESTRICT')->onDelete('RESTRICT');
+ $table->foreign('forward_from', 'message_ibfk_6')->references('id')->on($this->prefix . 'user')->onUpdate('RESTRICT')->onDelete('RESTRICT');
+ });
+ } catch (Throwable $e) {
+ Log::error($e->getMessage());
+ return; // Migration may be partly done already...
+ }
+ }
+}
diff --git a/src/database/migrations/2020_05_18_010919_convert_datetime_to_timetamp.php b/src/database/migrations/2020_05_18_010919_convert_datetime_to_timetamp.php
new file mode 100644
index 0000000..68a2356
--- /dev/null
+++ b/src/database/migrations/2020_05_18_010919_convert_datetime_to_timetamp.php
@@ -0,0 +1,28 @@
+ ['created_at'],
+ 'chosen_inline_result' => ['created_at'],
+ 'edited_message' => ['edit_date'],
+ 'inline_query' => ['created_at'],
+ 'message' => ['date', 'forward_date'],
+ 'request_limiter' => ['created_at'],
+ ];
+
+ public function up(): void
+ {
+ $this->changeColumnTypes($this->tableColumns, 'TIMESTAMP NULL DEFAULT NULL');
+ }
+
+ public function down(): void
+ {
+ $this->changeColumnTypes($this->tableColumns, 'DATETIME NULL DEFAULT NULL');
+ }
+}
diff --git a/src/database/migrations/2021_01_04_000000_update_schema_0_62_0_to_0_63_0.php b/src/database/migrations/2021_01_04_000000_update_schema_0_62_0_to_0_63_0.php
new file mode 100644
index 0000000..ea62fec
--- /dev/null
+++ b/src/database/migrations/2021_01_04_000000_update_schema_0_62_0_to_0_63_0.php
@@ -0,0 +1,68 @@
+prefix . 'poll', static function (Blueprint $table) {
+ $table->char('explanation', 255)->nullable()->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')->after('correct_option_id');
+ $table->text('explanation_entities')->nullable()->comment('Special entities like usernames, URLs, bot commands, etc. that appear in the explanation')->after('explanation');
+ $table->integer('open_period')->unsigned()->nullable()->comment('Amount of time in seconds the poll will be active after creation')->after('explanation_entities');
+ $table->timestamp('close_date')->nullable()->comment('Point in time (Unix timestamp) when the poll will be automatically closed')->after('open_period');
+ });
+
+ Schema::table($this->prefix . 'poll_answer', static function (Blueprint $table) {
+ $table->dropPrimary();
+ $table->primary(['poll_id', 'user_id']);
+ });
+
+ Schema::table($this->prefix . 'message', function (Blueprint $table) {
+ $table->dropForeign('message_ibfk_6');
+ $table->dropIndex('message_ibfk_6');
+
+ $table->bigInteger('via_bot')->nullable()->comment('Optional. Bot through which the message was sent')->after('reply_to_message');
+ $table->index('via_bot');
+ $table->foreign('via_bot', 'message_ibfk_9')->references('id')->on($this->prefix . 'user')->onUpdate('RESTRICT')->onDelete('RESTRICT');
+ });
+ } catch (Throwable $e) {
+ Log::error($e->getMessage());
+ return; // Migration may be partly done already...
+ }
+ }
+
+ public function down(): void
+ {
+ try {
+ Schema::table($this->prefix . 'poll', static function (Blueprint $table) {
+ $table->dropColumn('explanation');
+ $table->dropColumn('explanation_entities');
+ $table->dropColumn('open_period');
+ $table->dropColumn('close_date');
+ });
+
+ Schema::table($this->prefix . 'poll_answer', static function (Blueprint $table) {
+ $table->dropPrimary();
+ $table->primary('poll_id');
+ });
+
+ Schema::table($this->prefix . 'message', function (Blueprint $table) {
+ $table->dropForeign('message_ibfk_9');
+ $table->dropIndex('via_bot');
+ $table->dropColumn('via_bot');
+
+ $table->foreign('forward_from', 'message_ibfk_6')->references('id')->on($this->prefix . 'user')->onUpdate('RESTRICT')->onDelete('RESTRICT');
+ });
+ } catch (Throwable $e) {
+ Log::error($e->getMessage());
+ return; // Migration may be partly done already...
+ }
+ }
+}
diff --git a/src/database/migrations/2021_01_04_000000_update_schema_0_64_0_to_0_70_0.php b/src/database/migrations/2021_01_04_000000_update_schema_0_64_0_to_0_70_0.php
new file mode 100644
index 0000000..3f33283
--- /dev/null
+++ b/src/database/migrations/2021_01_04_000000_update_schema_0_64_0_to_0_70_0.php
@@ -0,0 +1,41 @@
+changeColumnTypes(['poll' => ['question']], 'text');
+
+ Schema::table($this->prefix . 'message', static function (Blueprint $table) {
+ $table->bigInteger('sender_chat_id')->comment('Sender of the message, sent on behalf of a chat')->after('chat_id');
+ $table->text('proximity_alert_triggered')->nullable()->comment('Service message. A user in the chat triggered another user\'s proximity alert while sharing Live Location.')->after('passport_data');
+ });
+ } catch (Throwable $e) {
+ Log::error($e->getMessage());
+ return; // Migration may be partly done already...
+ }
+ }
+
+ public function down(): void
+ {
+ try {
+ Schema::table($this->prefix . 'message', static function (Blueprint $table) {
+ $table->dropColumn('proximity_alert_triggered');
+ $table->dropColumn('sender_chat_id');
+ });
+
+ $this->changeColumnTypes(['poll' => ['question']], 'char(255)');
+ } catch (Throwable $e) {
+ Log::error($e->getMessage());
+ return; // Migration may be partly done already...
+ }
+ }
+}
diff --git a/tests/Unit/AbstractTestCase.php b/tests/Unit/AbstractTestCase.php
new file mode 100644
index 0000000..8c42d5f
--- /dev/null
+++ b/tests/Unit/AbstractTestCase.php
@@ -0,0 +1,16 @@
+assertIsInjectable(Repository::class);
+ }
+
+ /** @test */
+ public function database_is_injectable()
+ {
+ $this->assertIsInjectable(Database::class);
+ }
+}
diff --git a/tests/Unit/WebhookCommandTest.php b/tests/Unit/WebhookCommandTest.php
new file mode 100644
index 0000000..2557025
--- /dev/null
+++ b/tests/Unit/WebhookCommandTest.php
@@ -0,0 +1,38 @@
+markTestSkipped('Mock instead of live API calls');
+
+ $this->artisan('telegram:webhook https://example.com/test')
+ ->expectsOutput('Webhook set successfully!')
+ ->assertExitCode(0);
+ }
+
+ /** @test */
+ public function it_can_show_webhook_info()
+ {
+ $this->markTestSkipped('Mock instead of live API calls');
+
+ $this->artisan('telegram:webhook --info')
+ ->expectsOutput('Current webhook info:')
+ ->assertExitCode(0);
+ }
+
+ /** @test */
+ public function it_can_delete_webhook()
+ {
+ $this->markTestSkipped('Mock instead of live API calls');
+
+ $this->artisan('telegram:webhook --delete')
+ ->expectsOutput('Webhook deleted successfully!')
+ ->assertExitCode(0);
+ }
+}