From 088323a40780c345e3e4f0724f15a2fb951f2bcb Mon Sep 17 00:00:00 2001 From: Fedor Date: Tue, 10 Sep 2024 15:42:21 +0700 Subject: [PATCH] task-132687 telegram integration + links in FAQ --- .env.example | 23 ++- .../Integrations/Telegram/VacancyChannel.php | 48 +++++ app/Http/Controllers/Ad_jobsController.php | 48 ++--- app/Http/Controllers/MainController.php | 2 +- app/Models/Faq.php | 7 + composer.json | 1 + composer.lock | 144 +++++++++++++- config/services.php | 3 + config/telegram.php | 205 ++++++++++++++++++++ public/css/style_may2024.css | 3 + resources/views/admin/faq/form.blade.php | 11 ++ resources/views/employers/faq.blade.php | 8 +- resources/views/employers/list_vacancy.blade.php | 14 +- routes/web.php | 3 + 14 files changed, 467 insertions(+), 53 deletions(-) create mode 100644 app/Components/Integrations/Telegram/VacancyChannel.php create mode 100644 config/telegram.php diff --git a/.env.example b/.env.example index 478972c..0b62de7 100644 --- a/.env.example +++ b/.env.example @@ -1,8 +1,8 @@ APP_NAME=Laravel APP_ENV=local -APP_KEY= +APP_KEY=base64:U2p8XpTThMOYELolzlhevl2YGmuVRyF+eVazcnclAUQ= APP_DEBUG=true -APP_URL=http://localhost +APP_URL=http://rekamore.nologostudio.ru/ LOG_CHANNEL=stack LOG_DEPRECATIONS_CHANNEL=null @@ -11,7 +11,7 @@ LOG_LEVEL=debug DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 -DB_DATABASE=laravel +DB_DATABASE=rekamore DB_USERNAME=root DB_PASSWORD= @@ -29,12 +29,12 @@ REDIS_PASSWORD=null REDIS_PORT=6379 MAIL_MAILER=smtp -MAIL_HOST=mailpit -MAIL_PORT=1025 -MAIL_USERNAME=null -MAIL_PASSWORD=null -MAIL_ENCRYPTION=null -MAIL_FROM_ADDRESS="hello@example.com" +MAIL_HOST=smtp.googlemail.com +MAIL_PORT=465 +MAIL_USERNAME=alarionov@nologostudio.ru +MAIL_PASSWORD="PwdSky10121984!" +MAIL_ENCRYPTION=ssl +MAIL_FROM_ADDRESS=alarionov@nologostudio.ru MAIL_FROM_NAME="${APP_NAME}" AWS_ACCESS_KEY_ID= @@ -56,3 +56,8 @@ VITE_PUSHER_HOST="${PUSHER_HOST}" VITE_PUSHER_PORT="${PUSHER_PORT}" VITE_PUSHER_SCHEME="${PUSHER_SCHEME}" VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" + +EMAIL_ADMIN=info@rekamore.su + +TELEGRAM_API_KEY= +TELEGRAM_GROUP_ID= diff --git a/app/Components/Integrations/Telegram/VacancyChannel.php b/app/Components/Integrations/Telegram/VacancyChannel.php new file mode 100644 index 0000000..0894f2e --- /dev/null +++ b/app/Components/Integrations/Telegram/VacancyChannel.php @@ -0,0 +1,48 @@ +botApi = Telegram::bot('channel_bot'); + } + + /** + * @throws TelegramSDKException + */ + public function sendVacancy(Ad_employer $vacancy): void + { + $updates = $this->botApi->getUpdates(); + /** @var Update $update*/ + $chatId = null; + foreach ($updates as $update) { + if ($update->myChatMember?->chat->title === config('services.telegram.chat_title')) { + $chatId = $update->myChatMember->chat->id; + } + } + if ($chatId === null) { + throw new TelegramSDKException('Cant locate group chat id'); + } + + $text = str_ireplace('

', '', $vacancy->text); + $text = str_ireplace('

', '', $text); + + $this->botApi->sendMessage([ + 'chat_id' => $chatId, + 'text' => $text, + 'disable_web_page_preview' => true, + 'parse_mode' => 'HTML' + ]); + } +} diff --git a/app/Http/Controllers/Ad_jobsController.php b/app/Http/Controllers/Ad_jobsController.php index beb10cf..21376d9 100644 --- a/app/Http/Controllers/Ad_jobsController.php +++ b/app/Http/Controllers/Ad_jobsController.php @@ -2,40 +2,17 @@ namespace App\Http\Controllers; -use App\Classes\RusDate; -use App\Classes\Tools; -use App\Http\Requests\FlotRequest; -use App\Http\Requests\MessagesRequiest; -use App\Http\Requests\VacancyRequestEdit; -use App\Http\Requests\VacansiaRequiest; +use App\Components\Integrations\Telegram\VacancyChannel; use App\Mail\MailSotrudnichestvo; -use App\Mail\SendAllMessages; use App\Models\Ad_employer; use App\Models\Ad_jobs; -use App\Models\ad_response; use App\Models\Category; -use App\Models\Education; use App\Models\Employer; -use App\Models\employers_main; -use App\Models\Flot; use App\Models\Job_title; -use App\Models\Like_vacancy; -use App\Models\Like_worker; -use App\Models\Message; -use App\Models\Positions; -use App\Models\Worker; -use Carbon\Carbon; -use Illuminate\Auth\Events\Registered; -use Illuminate\Database\Eloquent\Builder; -use Illuminate\Database\Eloquent\Model; -use Illuminate\Foundation\Auth\User; +use http\Exception\RuntimeException; +use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; -use Illuminate\Support\Facades\Auth; -use Illuminate\Support\Facades\Hash; -use Illuminate\Support\Facades\Mail; -use Illuminate\Support\Facades\Storage; -use App\Models\User as User_Model; -use Illuminate\Support\Facades\Validator; +use Telegram\Bot\Exceptions\TelegramSDKException; class Ad_jobsController extends Controller { @@ -126,4 +103,21 @@ class Ad_jobsController extends Controller $ad_job->delete(); return redirect()->route('employer.vacancy_list'); } + + /** + * @throws TelegramSDKException + */ + public function sendVacancyToSocial(string $social, Ad_employer $vacancy): RedirectResponse + { + switch ($social) { + case 'tg': + $handler = new VacancyChannel(); + break; + default: + throw new RuntimeException('Unkown social'); + } + + $handler->sendVacancy($vacancy); + return response()->redirectTo(route('employer.vacancy_list')); + } } diff --git a/app/Http/Controllers/MainController.php b/app/Http/Controllers/MainController.php index 882188c..a32d96a 100644 --- a/app/Http/Controllers/MainController.php +++ b/app/Http/Controllers/MainController.php @@ -157,7 +157,7 @@ class MainController extends Controller $Data->where('job_title_id', $request->get('job')); } - $Data->leftJoin('ad_jobs', 'ad_jobs.job_title_id', '=', 'job_titles.id') + $Data = $Data->leftJoin('ad_jobs', 'ad_jobs.job_title_id', '=', 'job_titles.id') ->join('categories', 'categories.id', '=', 'job_titles.position_id') ->groupBy('job_titles.id') ->orderBy('categories.id') diff --git a/app/Models/Faq.php b/app/Models/Faq.php index d4fe70e..c0db617 100644 --- a/app/Models/Faq.php +++ b/app/Models/Faq.php @@ -3,6 +3,7 @@ namespace App\Models; use Illuminate\Database\Eloquent\Model; +use Illuminate\Support\Facades\Blade; /** * @property string $question @@ -16,4 +17,10 @@ class Faq extends Model 'created_at', 'updated_at' ]; + + protected static function boot() + { + parent::boot(); + Blade::withoutDoubleEncoding(); + } } diff --git a/composer.json b/composer.json index b2ea035..83ad51a 100644 --- a/composer.json +++ b/composer.json @@ -12,6 +12,7 @@ "filament/notifications": "^2.17", "filament/tables": "^2.17", "guzzlehttp/guzzle": "^7.2", + "irazasyed/telegram-bot-sdk": "^3.14", "laravel-lang/lang": "^12.17", "laravel/framework": "^9.19", "laravel/sanctum": "^3.0", diff --git a/composer.lock b/composer.lock index df10535..2ce008f 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "4b776d8fe63faa11f5e875dbed55d528", + "content-hash": "a7eb5dd83a46d4d36bcfd6dc5e419b75", "packages": [ { "name": "akaunting/laravel-money", @@ -2081,6 +2081,89 @@ "time": "2021-10-07T12:57:01+00:00" }, { + "name": "irazasyed/telegram-bot-sdk", + "version": "v3.14.0", + "source": { + "type": "git", + "url": "https://github.com/irazasyed/telegram-bot-sdk.git", + "reference": "c72ef585556578105c4d5cc56324575ef3677fd2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/irazasyed/telegram-bot-sdk/zipball/c72ef585556578105c4d5cc56324575ef3677fd2", + "reference": "c72ef585556578105c4d5cc56324575ef3677fd2", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/guzzle": "^7.5.1", + "guzzlehttp/psr7": "^2.5", + "illuminate/support": "9 - 11", + "league/event": "^2.2 || ^3.0", + "php": ">=8.0", + "psr/container": "^1.1 || ^2.0", + "psr/event-dispatcher": "^1.0" + }, + "require-dev": { + "irazasyed/docgen": "^0.2", + "pestphp/pest": "^1.22 || ^2.0", + "php-parallel-lint/php-parallel-lint": "^1.3", + "phpspec/prophecy": "^1.17", + "phpspec/prophecy-phpunit": "^2.0", + "rector/rector": "^0.16.0 || ^0.17.0 || ^0.18.0 || ^0.19.0 || ^1.0.0" + }, + "suggest": { + "illuminate/container": "Hold dependencies to be injected in commands constructors", + "irazasyed/larasupport": "Allows you to use any Laravel Package in Lumen by adding support!" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + }, + "laravel": { + "aliases": { + "Telegram": "Telegram\\Bot\\Laravel\\Facades\\Telegram" + }, + "providers": [ + "Telegram\\Bot\\Laravel\\TelegramServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Telegram\\Bot\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Irfaq Syed", + "email": "github@lukonet.net", + "homepage": "https://github.com/irazasyed" + } + ], + "description": "The Unofficial Telegram Bot API PHP SDK", + "homepage": "https://github.com/irazasyed/telegram-bot-sdk", + "keywords": [ + "laravel", + "laravel telegram", + "telegram", + "telegram bot", + "telegram bot api", + "telegram php", + "telegram sdk" + ], + "support": { + "issues": "https://github.com/irazasyed/telegram-bot-sdk/issues", + "source": "https://github.com/irazasyed/telegram-bot-sdk/tree/v3.14.0" + }, + "time": "2024-03-11T03:11:26+00:00" + }, + { "name": "laravel-lang/lang", "version": "12.17.1", "source": { @@ -2798,6 +2881,65 @@ "time": "2022-12-11T20:36:23+00:00" }, { + "name": "league/event", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/event.git", + "reference": "ec38ff7ea10cad7d99a79ac937fbcffb9334c210" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/event/zipball/ec38ff7ea10cad7d99a79ac937fbcffb9334c210", + "reference": "ec38ff7ea10cad7d99a79ac937fbcffb9334c210", + "shasum": "" + }, + "require": { + "php": ">=7.2.0", + "psr/event-dispatcher": "^1.0" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.16", + "phpstan/phpstan": "^0.12.45", + "phpunit/phpunit": "^8.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Event\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frenky.net" + } + ], + "description": "Event package", + "keywords": [ + "emitter", + "event", + "listener" + ], + "support": { + "issues": "https://github.com/thephpleague/event/issues", + "source": "https://github.com/thephpleague/event/tree/3.0.3" + }, + "time": "2024-09-04T16:06:53+00:00" + }, + { "name": "league/flysystem", "version": "3.15.1", "source": { diff --git a/config/services.php b/config/services.php index 0ace530..09dc5d8 100644 --- a/config/services.php +++ b/config/services.php @@ -31,4 +31,7 @@ return [ 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), ], + 'telegram' => [ + 'chat_title' => env('TELEGRAM_GROUP_TITLE'), + ] ]; diff --git a/config/telegram.php b/config/telegram.php new file mode 100644 index 0000000..395ec71 --- /dev/null +++ b/config/telegram.php @@ -0,0 +1,205 @@ + [ + 'channel_bot' => [ + 'token' => env('TELEGRAM_BOT_API_KEY'), + ] + ], + + /* + |-------------------------------------------------------------------------- + | Default Bot Name + |-------------------------------------------------------------------------- + | + | Here you may specify which of the bots you wish to use as + | your default bot for regular use. + | + */ + 'default' => 'channel_bot', + + /* + |-------------------------------------------------------------------------- + | Asynchronous Requests [Optional] + |-------------------------------------------------------------------------- + | + | When set to True, All the requests would be made non-blocking (Async). + | + | Default: false + | Possible Values: (Boolean) "true" OR "false" + | + */ + 'async_requests' => env('TELEGRAM_ASYNC_REQUESTS', false), + + /* + |-------------------------------------------------------------------------- + | HTTP Client Handler [Optional] + |-------------------------------------------------------------------------- + | + | If you'd like to use a custom HTTP Client Handler. + | Should be an instance of \Telegram\Bot\HttpClients\HttpClientInterface + | + | Default: GuzzlePHP + | + */ + 'http_client_handler' => null, + + /* + |-------------------------------------------------------------------------- + | Base Bot Url [Optional] + |-------------------------------------------------------------------------- + | + | If you'd like to use a custom Base Bot Url. + | Should be a local bot api endpoint or a proxy to the telegram api endpoint + | + | Default: https://api.telegram.org/bot + | + */ + 'base_bot_url' => null, + + /* + |-------------------------------------------------------------------------- + | Resolve Injected Dependencies in commands [Optional] + |-------------------------------------------------------------------------- + | + | Using Laravel's IoC container, we can easily type hint dependencies in + | our command's constructor and have them automatically resolved for us. + | + | Default: true + | Possible Values: (Boolean) "true" OR "false" + | + */ + 'resolve_command_dependencies' => true, + + /* + |-------------------------------------------------------------------------- + | Register Telegram Global Commands [Optional] + |-------------------------------------------------------------------------- + | + | If you'd like to use the SDK's built in command handler system, + | You can register all the global commands here. + | + | Global commands will apply to all the bots in system and are always active. + | + | The command class should extend the \Telegram\Bot\Commands\Command class. + | + | Default: The SDK registers, a help command which when a user sends /help + | will respond with a list of available commands and description. + | + */ + 'commands' => [ + HelpCommand::class, + ], + + /* + |-------------------------------------------------------------------------- + | Command Groups [Optional] + |-------------------------------------------------------------------------- + | + | You can organize a set of commands into groups which can later, + | be re-used across all your bots. + | + | You can create 4 types of groups: + | 1. Group using full path to command classes. + | 2. Group using shared commands: Provide the key name of the shared command + | and the system will automatically resolve to the appropriate command. + | 3. Group using other groups of commands: You can create a group which uses other + | groups of commands to bundle them into one group. + | 4. You can create a group with a combination of 1, 2 and 3 all together in one group. + | + | Examples shown below are by the group type for you to understand each of them. + */ + 'command_groups' => [ + /* // Group Type: 1 + 'commmon' => [ + Acme\Project\Commands\TodoCommand::class, + Acme\Project\Commands\TaskCommand::class, + ], + */ + + /* // Group Type: 2 + 'subscription' => [ + 'start', // Shared Command Name. + 'stop', // Shared Command Name. + ], + */ + + /* // Group Type: 3 + 'auth' => [ + Acme\Project\Commands\LoginCommand::class, + Acme\Project\Commands\SomeCommand::class, + ], + + 'stats' => [ + Acme\Project\Commands\UserStatsCommand::class, + Acme\Project\Commands\SubscriberStatsCommand::class, + Acme\Project\Commands\ReportsCommand::class, + ], + + 'admin' => [ + 'auth', // Command Group Name. + 'stats' // Command Group Name. + ], + */ + + /* // Group Type: 4 + 'myBot' => [ + 'admin', // Command Group Name. + 'subscription', // Command Group Name. + 'status', // Shared Command Name. + 'Acme\Project\Commands\BotCommand' // Full Path to Command Class. + ], + */ + ], + + /* + |-------------------------------------------------------------------------- + | Shared Commands [Optional] + |-------------------------------------------------------------------------- + | + | Shared commands let you register commands that can be shared between, + | one or more bots across the project. + | + | This will help you prevent from having to register same set of commands, + | for each bot over and over again and make it easier to maintain them. + | + | Shared commands are not active by default, You need to use the key name to register them, + | individually in a group of commands or in bot commands. + | Think of this as a central storage, to register, reuse and maintain them across all bots. + | + */ + 'shared_commands' => [ + // 'start' => Acme\Project\Commands\StartCommand::class, + // 'stop' => Acme\Project\Commands\StopCommand::class, + // 'status' => Acme\Project\Commands\StatusCommand::class, + ], +]; diff --git a/public/css/style_may2024.css b/public/css/style_may2024.css index 19cb011..30dbe85 100644 --- a/public/css/style_may2024.css +++ b/public/css/style_may2024.css @@ -7688,6 +7688,9 @@ main + .news { .faqs__item-body p { margin: 0; } +.faqs__item-body a { + color: #0f74a8; +} .active + .faqs__item-body { opacity: 1; height: auto; diff --git a/resources/views/admin/faq/form.blade.php b/resources/views/admin/faq/form.blade.php index 00d7047..c1623cc 100644 --- a/resources/views/admin/faq/form.blade.php +++ b/resources/views/admin/faq/form.blade.php @@ -98,3 +98,14 @@ + + + + + diff --git a/resources/views/employers/faq.blade.php b/resources/views/employers/faq.blade.php index 1e431fd..11fcf1a 100644 --- a/resources/views/employers/faq.blade.php +++ b/resources/views/employers/faq.blade.php @@ -40,7 +40,9 @@ -
{{ $question->answer }}
+
+ {!! $question->answer !!} +
@endforeach @@ -59,7 +61,9 @@ -
{{ $question->answer }}
+
+ {!! $question->answer !!} +
@endforeach diff --git a/resources/views/employers/list_vacancy.blade.php b/resources/views/employers/list_vacancy.blade.php index 82754da..0850efc 100644 --- a/resources/views/employers/list_vacancy.blade.php +++ b/resources/views/employers/list_vacancy.blade.php @@ -151,24 +151,12 @@ @endif @if ($Employer->social_is == 1) - + @endif - - - diff --git a/routes/web.php b/routes/web.php index e8b29b7..bfab8b5 100644 --- a/routes/web.php +++ b/routes/web.php @@ -603,6 +603,9 @@ Route::group([ Route::post('cabinet/flot_edit/{Flot}', [EmployerController::class, 'update_flot'])->name('update_flot_save'); Route::get('cabinet/flot', [EmployerController::class, 'slider_flot'])->name('slider_flot'); + Route::get('social/{social}/{vacancy}', [Ad_jobsController::class, 'sendVacancyToSocial']) + ->name('send-vacancy-to-social'); + // 2 страница - Добавление вакансий Route::get('cabinet/vacancie', [EmployerController::class, 'cabinet_vacancie'])->name('cabinet_vacancie'); Route::post('vacancie', [EmployerController::class, 'cabinet_vacancy_save1'])->name('vac_save'); -- 1.7.10.4