├── .editorconfig ├── .env.example ├── .gitattributes ├── .gitignore ├── .styleci.yml ├── CONTRIBUTING.md ├── LICENSE.md ├── Procfile ├── app ├── Commands │ ├── HelpCommand.php │ ├── OptionsCommand.php │ ├── RulesCommand.php │ └── StartCommand.php ├── Console │ ├── Commands │ │ └── ProcessMessages.php │ └── Kernel.php ├── Contracts │ ├── Collector │ │ ├── CollectorInterface.php │ │ └── ExtraFieldsInterface.php │ ├── Repositories │ │ ├── GroupRepository.php │ │ ├── OpportunityRepository.php │ │ └── UserRepository.php │ └── Validation │ │ └── CreateUpdateInterface.php ├── Enums │ ├── Arguments.php │ ├── BrazilianStates.php │ ├── Callbacks.php │ ├── Countries.php │ ├── Days.php │ ├── GroupTypes.php │ └── Months.php ├── Events │ ├── Listeners │ │ └── RegisterNotificationIdentification.php │ └── TelegramMessageSent.php ├── Exceptions │ ├── Handler.php │ ├── InvalidCloudWatchConfigException.php │ └── TelegramOpportunityException.php ├── Helpers │ ├── BotHelper.php │ ├── ExtractorHelper.php │ ├── Helper.php │ └── SanitizerHelper.php ├── Http │ ├── Controllers │ │ ├── Api │ │ │ └── OpportunityController.php │ │ ├── ApiController.php │ │ ├── Auth │ │ │ ├── ForgotPasswordController.php │ │ │ ├── LoginController.php │ │ │ ├── RegisterController.php │ │ │ ├── ResetPasswordController.php │ │ │ └── VerificationController.php │ │ ├── Bot │ │ │ └── DefaultController.php │ │ ├── Controller.php │ │ └── Web │ │ │ └── OpportunityController.php │ ├── Kernel.php │ ├── Middleware │ │ ├── Authenticate.php │ │ ├── CheckForMaintenanceMode.php │ │ ├── Cors.php │ │ ├── EncryptCookies.php │ │ ├── RedirectIfAuthenticated.php │ │ ├── TrimStrings.php │ │ ├── TrustProxies.php │ │ └── VerifyCsrfToken.php │ └── Requests │ │ ├── OpportunityCreateRequest.php │ │ └── OpportunityUpdateRequest.php ├── Mail │ └── SendOpportunity.php ├── Models │ ├── Config.php │ ├── Group.php │ ├── Opportunity.php │ └── User.php ├── Notifications │ ├── Channels │ │ └── TelegramChannel.php │ ├── GroupSummaryOpportunities.php │ ├── NotifySenderUser.php │ └── SendOpportunity.php ├── Presenters │ └── OpportunityPresenter.php ├── Providers │ ├── AppServiceProvider.php │ ├── AuthServiceProvider.php │ ├── BroadcastServiceProvider.php │ ├── CloudWatchServiceProvider.php │ ├── EventServiceProvider.php │ ├── RepositoryServiceProvider.php │ ├── ResponseMacroServiceProvider.php │ └── RouteServiceProvider.php ├── Repositories │ ├── GroupRepositoryEloquent.php │ ├── OpportunityRepositoryEloquent.php │ └── UserRepositoryEloquent.php ├── Services │ ├── Collectors │ │ ├── ComoQueTaLaMessages.php │ │ ├── GMailMessages.php │ │ ├── GitHubMessages.php │ │ └── TelegramChatMessages.php │ ├── CommandsHandler.php │ ├── GmailService.php │ ├── MadelineProtoService.php │ └── TelegramMessage.php ├── Traits │ ├── HasSharedLogic.php │ └── RoutesNotifications.php ├── Transformers │ └── OpportunityTransformer.php └── Validators │ └── CollectedOpportunityValidator.php ├── artisan ├── bootstrap ├── app.php └── cache │ └── .gitignore ├── composer.json ├── composer.lock ├── config ├── api.php ├── app.php ├── auth.php ├── aws.php ├── broadcasting.php ├── cache.php ├── cloudder.php ├── constants.php ├── database.php ├── filesystems.php ├── github.php ├── gmail.php ├── hashing.php ├── logging.php ├── madeline.php ├── mail.php ├── markdown.php ├── queue.php ├── repository.php ├── services.php ├── session.php ├── telegram.php └── view.php ├── database ├── .gitignore ├── factories │ └── UserFactory.php ├── migrations │ ├── 2019_06_17_121203_create_opportunities_table.php │ ├── 2019_06_17_211516_create_notifications_table.php │ ├── 2019_06_17_235119_alter_table_opportunities.php │ ├── 2019_07_16_235119_alter_table_opportunities_change_title.php │ ├── 2019_07_18_143859_create_config_table.php │ ├── 2019_07_18_144158_seeder_config_table.php │ ├── 2019_07_18_235158_alter_table_opportunities_add_status.php │ ├── 2019_08_28_142253_alter_table_opportunities_add_telegram_user_id.php │ ├── 2019_12_26_163326_alter_table_opportunities_add_source.php │ ├── 2020_01_12_163326_alter_table_opportunities_add_tags.php │ ├── 2020_01_15_163326_alter_table_opportunities_add_emails.php │ ├── 2020_01_20_181443_re_create_notifications_table.php │ ├── 2020_01_22_142038_create_groups_table.php │ ├── 2020_01_22_144257_rename_config_table.php │ ├── 2020_01_22_144542_seeder_groups_table.php │ └── 2020_01_29_125436_create_users_table.php └── seeds │ └── DatabaseSeeder.php ├── package.json ├── patches ├── dacastro4-laravel-gmail-136.patch └── graham-campbell-github-102.patch ├── phpunit.xml ├── public ├── .htaccess ├── css │ └── app.css ├── favicon.ico ├── img │ ├── phpdf-full.webp │ └── phpdf.webp ├── index.php ├── js │ ├── app.js │ └── phpdfbot.js ├── mix-manifest.json ├── robots.txt └── web.config ├── readme.md ├── resources ├── js │ ├── app.js │ ├── bootstrap.js │ └── components │ │ └── ExampleComponent.vue ├── lang │ └── en │ │ ├── auth.php │ │ ├── pagination.php │ │ ├── passwords.php │ │ └── validation.php ├── sass │ └── app.scss └── views │ ├── home.blade.php │ ├── layouts │ ├── app.blade.php │ └── components │ │ ├── footer.blade.php │ │ ├── header.blade.php │ │ ├── navbar.blade.php │ │ └── sidebar.blade.php │ ├── notifications │ └── opportunity.blade.php │ └── welcome.blade.php ├── routes ├── api.php ├── channels.php ├── console.php └── web.php ├── server.php ├── storage ├── app │ ├── .gitignore │ ├── logs │ │ └── .gitignore │ └── public │ │ └── .gitignore ├── framework │ ├── .gitignore │ ├── cache │ │ └── .gitignore │ ├── sessions │ │ └── .gitignore │ ├── testing │ │ └── .gitignore │ └── views │ │ └── .gitignore └── logs │ └── .gitignore ├── tests ├── CreatesApplication.php ├── Feature │ └── ExampleTest.php ├── TestCase.php └── Unit │ └── ExampleTest.php └── webpack.mix.js /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | insert_final_newline = true 7 | indent_style = space 8 | indent_size = 4 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | 14 | [*.yml] 15 | indent_size = 2 16 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | APP_NAME=Laravel 2 | APP_ENV=local 3 | APP_KEY= 4 | APP_DEBUG=true 5 | APP_URL=http://localhost 6 | 7 | LOG_CHANNEL=stack 8 | 9 | DB_CONNECTION=mysql 10 | DB_HOST=127.0.0.1 11 | DB_PORT=3306 12 | DB_DATABASE=homestead 13 | DB_USERNAME=homestead 14 | DB_PASSWORD=secret 15 | 16 | BROADCAST_DRIVER=log 17 | CACHE_DRIVER=file 18 | QUEUE_CONNECTION=sync 19 | SESSION_DRIVER=file 20 | SESSION_LIFETIME=120 21 | 22 | REDIS_HOST=127.0.0.1 23 | REDIS_PASSWORD=null 24 | REDIS_PORT=6379 25 | 26 | MAIL_DRIVER='smtp' 27 | MAIL_HOST='smtp.gmail.com' 28 | MAIL_PORT='465' 29 | MAIL_USERNAME='****@gmail.com' 30 | MAIL_PASSWORD='****' 31 | MAIL_ENCRYPTION='ssl' 32 | MAIL_FROM_ADDRESS 33 | MAIL_FROM_NAME 34 | 35 | AWS_ACCESS_KEY_ID= 36 | AWS_SECRET_ACCESS_KEY= 37 | AWS_DEFAULT_REGION=us-east-1 38 | AWS_BUCKET= 39 | 40 | PUSHER_APP_ID= 41 | PUSHER_APP_KEY= 42 | PUSHER_APP_SECRET= 43 | PUSHER_APP_CLUSTER=mt1 44 | 45 | MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}" 46 | MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" 47 | 48 | TELEGRAM_BOT_NAME= 49 | TELEGRAM_BOT_TOKEN= 50 | TELEGRAM_OWNER_ID= 51 | TELEGRAM_GROUP_ADM= 52 | 53 | TELEGRAM_API_ID= 54 | TELEGRAM_API_HASH= 55 | TELEGRAM_SERVER=149.154.167.40:443 56 | 57 | DIALOGFLOW_TOKEN= 58 | 59 | GOOGLE_PROJECT_ID= 60 | GOOGLE_CLIENT_ID= 61 | GOOGLE_CLIENT_SECRET= 62 | GOOGLE_REDIRECT_URI= 63 | GOOGLE_ALLOW_MULTITPLE_CREDENTIALS 64 | GOOGLE_ALLOW_JSON_ENCRYPT 65 | 66 | CRAWLER_SKIP_DATA_CHECK=false 67 | 68 | CLOUDINARY_API_KEY= 69 | CLOUDINARY_API_SECRET= 70 | CLOUDINARY_CLOUD_NAME= 71 | 72 | API_STANDARDS_TREE=vnd 73 | API_SUBTYPE=phpdfbot 74 | API_PREFIX=api 75 | API_DOMAIN=local.phpdfbot.com 76 | API_VERSION=v1 77 | API_NAME=PHPDFBOT 78 | API_CONDITIONAL_REQUEST=false 79 | API_DEFAULT_FORMAT=json 80 | API_DEBUG=true 81 | 82 | GITHUB_TOKEN= 83 | GITHUB_USERNAME= 84 | GITHUB_REPO= 85 | 86 | FTP_HOST= 87 | FTP_USERNAME= 88 | FTP_PASSWORD= 89 | FTP_ROOT= 90 | FTP_PORT= -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | *.css linguist-vendored 3 | *.scss linguist-vendored 4 | *.js linguist-vendored 5 | CHANGELOG.md export-ignore 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /public/hot 3 | /public/storage 4 | /storage/*.key 5 | /vendor 6 | .env 7 | .env.backup 8 | .phpunit.result.cache 9 | Homestead.json 10 | Homestead.yaml 11 | npm-debug.log 12 | yarn-error.log 13 | /.idea 14 | /storage/framework/* -------------------------------------------------------------------------------- /.styleci.yml: -------------------------------------------------------------------------------- 1 | php: 2 | preset: laravel 3 | disabled: 4 | - unused_use 5 | finder: 6 | not-name: 7 | - index.php 8 | - server.php 9 | js: 10 | finder: 11 | not-name: 12 | - webpack.mix.js 13 | css: true 14 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Como contribuir? 2 | Infelizmente, o Telegram nao dispoe de uma sandbox ou ambiente de desenvolvimento, portanto, nao possibilidade de testar a nao ser em producao. 3 | Para contribuir, realize o clone desse projeto: 4 |
5 | git clone https://github.com/celorodovalho/phpdfbot.git 6 |7 | Mude para a branch de desenvolvimento: 8 |
9 | git checkout develop 10 |11 | Instale o projeto via composer: 12 |
13 | cp .env.example .env 14 | composer install 15 |16 | Esse projeto utiliza a metodologia "git flow" (https://danielkummer.github.io/git-flow-cheatsheet/index.pt_BR.html), portanto, crie uma branch a partir da branch de desenvolvimento: 17 |
18 | git flow feature start NOME_DA_FEATURE 19 |20 | Faca o commit e um PULL REQUEST para a develop. 21 | 22 | 23 | Dados importantes que so estao disponiveis no ambiente de producao: 24 |
25 | TELEGRAM_BOT_NAME=phpdfbot 26 | TELEGRAM_BOT_TOKEN=000000000:XXXXXXXxxxxxXXXXXXXXXXXXXXXXXXxxxx 27 | TELEGRAM_CHANNEL=@phpdfvagas 28 | TELEGRAM_GROUP=@phpdf 29 | TELEGRAM_OWNER_ID= 30 | TELEGRAM_GROUP_ADM= 31 |32 | 33 | 34 | ## Logs 35 | Os logs de erros sao enviados automaticamente para o grupo de administracao do Bot. -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: vendor/bin/heroku-php-apache2 public/ && echo $APP_URL && wget https://phpdfbot.s3-sa-east-1.amazonaws.com/online.txt -------------------------------------------------------------------------------- /app/Commands/HelpCommand.php: -------------------------------------------------------------------------------- 1 | 12 | */ 13 | class HelpCommand extends Command 14 | { 15 | /** 16 | * @var string Command Name 17 | */ 18 | protected $name = 'help'; 19 | 20 | /** 21 | * @var array Command Aliases 22 | */ 23 | // protected $aliases = ['listcommands']; 24 | 25 | /** 26 | * @var string Command Description 27 | */ 28 | protected $description = 'Help command, Get a list of commands'; 29 | 30 | /** 31 | * {@inheritdoc} 32 | * @throws TelegramSDKException 33 | */ 34 | public function handle(): void 35 | { 36 | $commands = $this->telegram->getCommands(); 37 | 38 | $text = ''; 39 | foreach ($commands as $name => $handler) { 40 | $text .= sprintf('/%s - %s' . PHP_EOL, $name, $handler->getDescription()); 41 | } 42 | 43 | $this->replyWithMessage(compact('text')); 44 | 45 | // TODO: change way of get admin group 46 | $this->telegram->sendMessage([ 47 | 'chat_id' => env('TELEGRAM_GROUP_ADM'), 48 | 'text' => json_encode([$this->getUpdate()]) 49 | ]); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /app/Commands/OptionsCommand.php: -------------------------------------------------------------------------------- 1 | 16 | */ 17 | class OptionsCommand extends Command 18 | { 19 | 20 | /** 21 | * @var string Command Name 22 | */ 23 | protected $name = Callbacks::OPTIONS; 24 | 25 | /** 26 | * @var string Command Description 27 | */ 28 | protected $description = 'Show the options for this bot'; 29 | 30 | /** 31 | * @inheritdoc 32 | */ 33 | public function handle() 34 | { 35 | $this->replyWithChatAction(['action' => Actions::TYPING]); 36 | 37 | // TODO: chage way of get owner id 38 | if ($this->getUpdate()->getMessage()->from->id !== (int)env('TELEGRAM_OWNER_ID')) { 39 | return $this->replyWithMessage([ 40 | 'text' => 'Lamento, mas esse comando é restrito. Para maiores informações entre em contato: @se45ky', 41 | ]); 42 | } 43 | 44 | $keyboard = Keyboard::make() 45 | ->inline() 46 | ->row( 47 | Keyboard::inlineButton([ 48 | 'text' => 'Notificar Grupo', 49 | 'callback_data' => $this->name . ' ' . Arguments::NOTIFY 50 | ]), 51 | Keyboard::inlineButton([ 52 | 'text' => 'Realizar Coleta', 53 | 'callback_data' => $this->name . ' ' . Arguments::PROCESS 54 | ]) 55 | ); 56 | 57 | $this->replyWithMessage([ 58 | 'text' => 'Qual acao deseja realizar?', 59 | 'reply_markup' => $keyboard 60 | ]); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /app/Commands/RulesCommand.php: -------------------------------------------------------------------------------- 1 | 14 | */ 15 | class RulesCommand extends Command 16 | { 17 | /** 18 | * @var string Command Name 19 | */ 20 | protected $name = 'rules'; 21 | 22 | /** 23 | * @var string Command Description 24 | */ 25 | protected $description = 'The group rules'; 26 | 27 | /** 28 | * @inheritdoc 29 | */ 30 | public function handle(): void 31 | { 32 | $this->replyWithChatAction(['action' => Actions::TYPING]); 33 | 34 | $rules = Config::where('key', 'rules')->first(); 35 | 36 | $this->replyWithMessage([ 37 | 'parse_mode' => BotHelper::PARSE_MARKDOWN, 38 | 'text' => $rules 39 | ]); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /app/Commands/StartCommand.php: -------------------------------------------------------------------------------- 1 | 15 | */ 16 | class StartCommand extends Command 17 | { 18 | /** @var string Command Name */ 19 | protected $name = 'start'; 20 | 21 | /** @var string Command Description */ 22 | protected $description = 'Start Command to get you started'; 23 | 24 | /** @var UserRepository */ 25 | private $userRepository; 26 | 27 | /** 28 | * StartCommand constructor. 29 | * 30 | * @param UserRepository $userRepository 31 | */ 32 | public function __construct(UserRepository $userRepository) 33 | { 34 | $this->userRepository = $userRepository; 35 | } 36 | 37 | /** 38 | * @inheritdoc 39 | */ 40 | public function handle(): void 41 | { 42 | $this->replyWithChatAction(['action' => Actions::TYPING]); 43 | 44 | $message = $this->update->getMessage(); 45 | 46 | $username = $message->from->username; 47 | if (!$username) { 48 | $username = $message->from->firstName; 49 | // . ' ' . $this->update->getMessage()->from->lastName; 50 | } 51 | 52 | // $keyboard = Keyboard::make() 53 | // ->inline() 54 | // ->row( 55 | // Keyboard::inlineButton([ 56 | // 'text' => 'Leia as Regras', 57 | // 'url' => 'https://t.me/phpdf/8726' 58 | // ]), 59 | // Keyboard::inlineButton([ 60 | // 'text' => 'Vagas de TI', 61 | // 'url' => 'https://t.me/VagasBrasil_TI' 62 | // ]) 63 | // ); 64 | 65 | $this->replyWithMessage([ 66 | // 'parse_mode' => BotHelper::PARSE_MARKDOWN, 67 | 'text' => sprintf( 68 | 'Olá %s! Eu sou o Bot de vagas. Voce pode começar me enviando o texto da vaga que quer publicar:', 69 | $username 70 | ), 71 | // 'reply_markup' => $keyboard 72 | ]); 73 | 74 | $this->triggerCommand('help'); 75 | 76 | if ($message->chat->type === BotHelper::TG_CHAT_TYPE_PRIVATE) { 77 | $telegramUser = $message->from; 78 | $user = $this->userRepository->updateOrCreate( 79 | ['id' => $telegramUser->id,], 80 | [ 81 | 'username' => $telegramUser->username, 82 | 'is_bot' => $telegramUser->isBot, 83 | 'first_name' => $telegramUser->firstName, 84 | 'last_name' => $telegramUser->lastName, 85 | 'language_code' => $telegramUser->languageCode, 86 | ] 87 | ); 88 | Log::info('USER_CREATED_StartCommand', [$user]); 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /app/Console/Kernel.php: -------------------------------------------------------------------------------- 1 | 12 | */ 13 | 14 | /** 15 | * Class Kernel 16 | * 17 | * @author Marcelo Rodovalho
{{$opportunity->position}}
15 | @endif 16 | 17 | @foreach(json_decode($opportunity->files) as $file) 18 |{!! \GrahamCampbell\Markdown\Facades\Markdown::convertToHtml($opportunity->description) !!}
23 | @endif 24 | 25 | 26 | @if($opportunity->salary) 27 |{{$opportunity->salary}}
28 | @endif 29 | @if($opportunity->company) 30 |{{$opportunity->company}}
31 | @endif 32 | @if($opportunity->location) 33 |{{$opportunity->location}}
34 | @endif 35 | @if($opportunity->tags) 36 |{{$opportunity->tags}}
37 | @endif 38 |