From 90d864c7014f975818f023ca11982b408d81d669 Mon Sep 17 00:00:00 2001 From: Setiawan Hu Date: Tue, 11 Aug 2020 16:21:11 +0700 Subject: [PATCH 01/11] Updated composer.json --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 5252628..2710129 100644 --- a/composer.json +++ b/composer.json @@ -2,7 +2,7 @@ "name": "setiawanhu/laravel-madeline-proto", "description": "A third party Telegram client library danog/MadelineProto wrapper for Laravel", "type": "library", - "license": "GPL-2.0-only", + "license": "AGPL-3.0-only", "authors": [ { "name": "Setiawan Hu", From 6f5e52d95375b35a0e9efc89eb5cc6faf2f0099f Mon Sep 17 00:00:00 2001 From: Setiawan Hu Date: Tue, 11 Aug 2020 16:22:14 +0700 Subject: [PATCH 02/11] Updated MadelineProto wrapper class updated: - updated documentation - code cleaning --- src/MadelineProto.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/MadelineProto.php b/src/MadelineProto.php index 9bae347..951d5ca 100644 --- a/src/MadelineProto.php +++ b/src/MadelineProto.php @@ -40,8 +40,7 @@ class MadelineProto * * @param string $code * @return TelegramObject auth.Authorization - * @throws NeedTwoFactorAuthException - * @throws SignUpNeededException + * @throws NeedTwoFactorAuthException|SignUpNeededException */ public function completePhoneLogin(string $code): TelegramObject { @@ -50,10 +49,8 @@ class MadelineProto switch ($response->return_type) { case Account::PASSWORD: throw new NeedTwoFactorAuthException($response); - break; case Account::NEED_SIGN_UP: throw new SignUpNeededException(); - break; } return $response; From 90e763b6f757b2ce68beee4fb260640fbca70c06 Mon Sep 17 00:00:00 2001 From: Setiawan Hu Date: Wed, 12 Aug 2020 20:09:54 +0700 Subject: [PATCH 03/11] Updated TelegramAccountLoginCommand Fixing undefined method error --- src/Commands/TelegramAccountLoginCommand.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Commands/TelegramAccountLoginCommand.php b/src/Commands/TelegramAccountLoginCommand.php index d85f50f..1a083a2 100644 --- a/src/Commands/TelegramAccountLoginCommand.php +++ b/src/Commands/TelegramAccountLoginCommand.php @@ -34,12 +34,12 @@ class TelegramAccountLoginCommand extends Command $phoneNumber = $this->ask('Phone number with country code (e.g: +6282112345678)?'); - MadelineProto::sendPhoneCode($phoneNumber); + MadelineProto::phoneLogin($phoneNumber); $code = $this->ask('Phone code?'); try { - MadelineProto::signIn($code); + MadelineProto::completePhoneLogin($code); } catch (NeedTwoFactorAuthException $e) { $password = $this->ask("2FA Password (hint '{$e->account->hint}')"); From f8a4d63caf6f861349f1cfe2d7402f7196e40da0 Mon Sep 17 00:00:00 2001 From: Setiawan Hu Date: Thu, 13 Aug 2020 01:09:42 +0700 Subject: [PATCH 04/11] Added illuminate/database dependency --- composer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 2710129..d9e94bb 100644 --- a/composer.json +++ b/composer.json @@ -13,7 +13,8 @@ "php": "^7.4", "danog/madelineproto": "^5.1", "illuminate/support": "^7.0", - "illuminate/console": "^7.0" + "illuminate/console": "^7.0", + "illuminate/database": "^7.0" }, "autoload": { "psr-4": { From e007b1c592b0470ac63b60fc73f2f735eb3faaba Mon Sep 17 00:00:00 2001 From: Setiawan Hu Date: Thu, 13 Aug 2020 01:21:40 +0700 Subject: [PATCH 05/11] Updated MadelineProto class added: - added message method to return ClientMessages class (messages wrapper class) --- src/MadelineProto.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/MadelineProto.php b/src/MadelineProto.php index 951d5ca..a372adc 100644 --- a/src/MadelineProto.php +++ b/src/MadelineProto.php @@ -139,4 +139,14 @@ class MadelineProto { return $this->fullGetSelf() !== false; } + + /** + * Get MadelineProto Message API wrapper instance. + * + * @return ClientMessages + */ + public function messages() + { + return new ClientMessages($this->client->messages); + } } From 328eeebb47a43cf7c776589848ec1558d88d26c2 Mon Sep 17 00:00:00 2001 From: Setiawan Hu Date: Thu, 13 Aug 2020 01:29:39 +0700 Subject: [PATCH 06/11] Added MadelineProtoFactory class This factory class is used for generating MadelineProto instance from given TelegramSession model instance, TelegramSession record id, or session file path Note: all the danog/MadelineProto session file will be stored in `storage/app/telegram/` directory. --- src/Factories/MadelineProtoFactory.php | 80 ++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 src/Factories/MadelineProtoFactory.php diff --git a/src/Factories/MadelineProtoFactory.php b/src/Factories/MadelineProtoFactory.php new file mode 100644 index 0000000..f48f635 --- /dev/null +++ b/src/Factories/MadelineProtoFactory.php @@ -0,0 +1,80 @@ +database = $manager->connection(); + $this->table = $table; + } + + /** + * Get the MadelineProto (session) instance from session table. + * + * @param int|Model $session can be either id or model instance of TelegramSession which + * generated from madeline-proto:multi-session --model command + * @param array|null $config if this parameter is null, then the config from telegram.php + * file will be used + * @return MadelineProto + */ + public function get($session, array $config = null) + { + if (is_null($config)) { + $config = config('telegram.settings'); + } + + if (is_int($session)) { + $session = $this->database->table($this->table)->find($session); + + $sessionFile = $session->session_file; + } else { + $sessionFile = $session->session_file; + } + + return $this->make($sessionFile, $config); + } + + /** + * Generating MadelineProto (session) instance. + * + * @param string $sessionFile + * @param array $config + * @return MadelineProto + */ + public function make(string $sessionFile, array $config) + { + if (!file_exists(storage_path("app/telegram/"))) { + mkdir(storage_path("app/telegram"), 0755); + } + + $client = new API(storage_path("app/telegram/$sessionFile"), $config); + + return new MadelineProto($client); + } +} From ddda52e786bdf0ca5a1bbaeead5c1d6bbefacb3c Mon Sep 17 00:00:00 2001 From: Setiawan Hu Date: Thu, 13 Aug 2020 01:30:46 +0700 Subject: [PATCH 07/11] Added MultiSessionCommand this command is used for generating model + migration for storing the session file(s) location --- src/Commands/MultiSessionCommand.php | 141 +++++++++++++++++++++++ src/Commands/stubs/migration.stub | 33 ++++++ src/Commands/stubs/telegram_session.stub | 26 +++++ 3 files changed, 200 insertions(+) create mode 100644 src/Commands/MultiSessionCommand.php create mode 100644 src/Commands/stubs/migration.stub create mode 100644 src/Commands/stubs/telegram_session.stub diff --git a/src/Commands/MultiSessionCommand.php b/src/Commands/MultiSessionCommand.php new file mode 100644 index 0000000..d9a498c --- /dev/null +++ b/src/Commands/MultiSessionCommand.php @@ -0,0 +1,141 @@ +option('model')) { + $user = $this->ask('Telegram user model (for relation)', 'App/User'); + + if (file_exists(app_path()) && !$this->option('force')) { + if (!$this->confirm("The App/TelegramSession model is already exist. Replace it?")) { + $this->info('Multi session export aborted.'); + return; + } + } + + $this->exportModel($user); + + $this->info('TelegramSession model generated.'); + } + + $tableName = config('telegram.sessions.multiple.table'); + $migration = "2020_08_12_000000_create_{$tableName}_table.php"; + + if (file_exists(database_path("migrations/$migration")) && !$this->option('force')) { + if (!$this->confirm("The {$migration} migration file is already exist. Replace it?")) { + $this->info('Multi session export aborted.'); + return; + } + } + + $this->exportMigration($tableName, $user ?? null); + + $this->info('Migration file exported.'); + } + + /** + * Export the telegram_session migration file. + * + * @param string $tableName + * @param string|null $relation + */ + public function exportMigration(string $tableName, string $relation = null) + { + if ($relation == null) { + $relation = 'App/User'; + } + + file_put_contents( + database_path("migrations/2020_08_12_000000_create_{$tableName}_table.php"), + $this->compileMigrationStub($tableName, $relation) + ); + } + + /** + * Export the TelegramSession model file. + * + * @param string $relation + */ + public function exportModel(string $relation) + { + file_put_contents( + app_path('TelegramSession.php'), + $this->compileModelStub($relation) + ); + } + + /** + * Compile the TelegramSession stub. + * + * @param string $user + * @return string + */ + public function compileModelStub(string $user) + { + $stub = file_get_contents(__DIR__ . '/stubs/telegram_session.stub'); + $namespace = str_replace( + "/" . class_basename($user), + "", + $user + ); + + return str_replace( + ['{{user}}', '{{package}}'], + [Str::snake(class_basename($user)), $namespace], + $stub + ); + } + + /** + * Compile the TelegramSession migration stub. + * + * @param string $tableName + * @param string $user + * @return string + */ + public function compileMigrationStub(string $tableName, string $user) + { + return str_replace( + ['{{table}}', '{{user}}'], + [$tableName, Str::snake(class_basename($user))], + file_get_contents(__DIR__ . '/stubs/migration.stub') + ); + } +} diff --git a/src/Commands/stubs/migration.stub b/src/Commands/stubs/migration.stub new file mode 100644 index 0000000..b273596 --- /dev/null +++ b/src/Commands/stubs/migration.stub @@ -0,0 +1,33 @@ +id(); + $table->unsignedBigInteger('{{user}}_id'); + $table->string('session_file'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('{{table}}'); + } +} diff --git a/src/Commands/stubs/telegram_session.stub b/src/Commands/stubs/telegram_session.stub new file mode 100644 index 0000000..f768525 --- /dev/null +++ b/src/Commands/stubs/telegram_session.stub @@ -0,0 +1,26 @@ + Date: Thu, 13 Aug 2020 01:32:32 +0700 Subject: [PATCH 08/11] Refactoring MadelineProtoServiceProvider added: - registering the `madeline-proto:multi-session` artisan command changed: - using MadelineProtoFactory as the instance generator for both single and multi telegram session --- src/MadelineProtoServiceProvider.php | 32 ++++++++++++++++++---------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/src/MadelineProtoServiceProvider.php b/src/MadelineProtoServiceProvider.php index 3ed9352..69c8ee9 100644 --- a/src/MadelineProtoServiceProvider.php +++ b/src/MadelineProtoServiceProvider.php @@ -2,8 +2,9 @@ namespace Hu\MadelineProto; -use danog\MadelineProto\API as Client; +use Hu\MadelineProto\Commands\MultiSessionCommand; use Hu\MadelineProto\Commands\TelegramAccountLoginCommand; +use Hu\MadelineProto\Factories\MadelineProtoFactory; use Illuminate\Contracts\Foundation\Application; use Illuminate\Support\ServiceProvider; @@ -16,20 +17,27 @@ class MadelineProtoServiceProvider extends ServiceProvider */ public function register() { - $this->app->singleton('madeline-proto-client', function () { - return new Client(config('telegram.session_file'), config('telegram.settings')); + $this->app->singleton('madeline-proto-factory', function (Application $app) { + return new MadelineProtoFactory($app->make('db'), config('telegram.sessions.multiple.table')); }); - $this->app->alias('madeline-proto-client', Client::class); + $this->app->alias('madeline-proto-factory', MadelineProtoFactory::class); - $this->app->bind('madeline-proto', function (Application $app) { - return new MadelineProto($app->make('madeline-proto-client')); + //Only for single Telegram session. + + $this->app->singleton('madeline-proto', function (Application $app) { + $sessionFactory = $app->make('madeline-proto-factory'); + + return $sessionFactory->make(config('telegram.sessions.single.session_file'), config('telegram.settings')); }); $this->app->alias('madeline-proto', MadelineProto::class); - $this->app->bind('madeline-proto-messages', function (Application $app) { - $client = $app->make('madeline-proto-client'); + $this->app->singleton('madeline-proto-messages', function (Application $app) { + $sessionFactory = $app->make('madeline-proto-factory'); - return new ClientMessages($client->messages); + return $sessionFactory->make( + config('telegram.sessions.single.session_file'), + config('telegram.settings') + )->messages(); }); $this->app->alias('madeline-proto-messages', ClientMessages::class); } @@ -58,7 +66,8 @@ class MadelineProtoServiceProvider extends ServiceProvider public function registerCommands() { $this->commands([ - TelegramAccountLoginCommand::class + TelegramAccountLoginCommand::class, + MultiSessionCommand::class ]); } @@ -69,7 +78,8 @@ class MadelineProtoServiceProvider extends ServiceProvider { return [ 'madeline-proto', - 'madeline-proto-client' + 'madeline-proto-messages', + 'madeline-proto-factory' ]; } } From 2ef30778523c3eaae3c27c57023f2995fe4ac24c Mon Sep 17 00:00:00 2001 From: Setiawan Hu Date: Thu, 13 Aug 2020 02:43:41 +0700 Subject: [PATCH 09/11] Added MadelineProtoFactory facade (Factory) --- src/Facades/Factory.php | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 src/Facades/Factory.php diff --git a/src/Facades/Factory.php b/src/Facades/Factory.php new file mode 100644 index 0000000..e1527e4 --- /dev/null +++ b/src/Facades/Factory.php @@ -0,0 +1,25 @@ + Date: Thu, 13 Aug 2020 03:14:50 +0700 Subject: [PATCH 10/11] Updated telegram.php config file --- config/telegram.php | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/config/telegram.php b/config/telegram.php index 081dadf..73eb5a1 100644 --- a/config/telegram.php +++ b/config/telegram.php @@ -6,7 +6,7 @@ return [ /* |-------------------------------------------------------------------------- - | Madeline Proto Session File Location + | Madeline Proto Sessions |-------------------------------------------------------------------------- | | To store information about an account session and avoid re-logging in, serialization must be done. @@ -15,9 +15,21 @@ return [ | and on shutdown. If the scripts shutdowns normally (without ctrl+c or fatal errors/exceptions), the | session will also be serialized automatically. | + | Types: "single", "multiple" + | */ - 'session_file' => env('MADELINE_PROTO_SESSION_FILE', 'session.madeline'), + 'sessions' => [ + + 'single' => [ + 'session_file' => env('MP_SESSION_FILE', 'session.madeline'), + ], + + 'multiple' => [ + 'table' => 'telegram_sessions' + ], + + ], /* |-------------------------------------------------------------------------- @@ -37,15 +49,15 @@ return [ 'logger' => Logger::FILE_LOGGER, - 'logger_param' => storage_path('logs/madeline-proto.log'), + 'logger_param' => env('MP_LOGGER_PATH', storage_path('logs/madeline-proto.log')), ], 'app_info' => [ - 'api_id' => env('TELEGRAM_API_ID'), + 'api_id' => env('MP_TELEGRAM_API_ID'), - 'api_hash' => env('TELEGRAM_API_HASH'), + 'api_hash' => env('MP_TELEGRAM_API_HASH'), ], ], From 5b404503fce8e8261defa397f6935b47c86ef15e Mon Sep 17 00:00:00 2001 From: Setiawan Hu Date: Thu, 13 Aug 2020 03:23:22 +0700 Subject: [PATCH 11/11] Updated README.md --- README.md | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 6392aef..dd0ccb0 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ A third party Telegram client library [danog/MadelineProto](https://github.com/danog/MadelineProto) wrapper for Laravel. -# Usage +# Getting Started Add the laravel-madeline-proto to the project dependency: @@ -13,7 +13,7 @@ Add the laravel-madeline-proto to the project dependency: composer require setiawanhu/laravel-madeline-proto ``` -Then publish the telegram config file: +Then publish the `telegram.php` config file: ```shell script php artisan vendor:publish --provider="Hu\MadelineProto\MadelineProtoServiceProvider" @@ -26,14 +26,11 @@ MP_TELEGRAM_API_ID=... //your telegram api id here MP_TELEGRAM_API_HASH=... //your telegram api hash here ``` -To do a login: +This wrapper package supports for running both [single](https://github.com/setiawanhu/laravel-madeline-proto/wiki/Single-Telegram-Account) / [multiple](https://github.com/setiawanhu/laravel-madeline-proto/wiki/Multiple-Telegram-Account) telegram account. -* call `MadelineProto::phoneLogin(string $phone)` method to send the phone code. +## Dig Deeper -* call `MadelineProto::completePhoneLogin(string $code)` to complete the phone login by providing the phone code sent by the telegram. - -* You're logged in! Now you can use the `Messages` api. - +Please check [wiki](https://github.com/setiawanhu/sanctum-auth/wiki) for more details about laravel-madeline-proto usage # Notes