diff --git a/app/Http/Controllers/Community/DiscordController.php b/app/Http/Controllers/Community/DiscordController.php index 3907d57b..82503a3a 100644 --- a/app/Http/Controllers/Community/DiscordController.php +++ b/app/Http/Controllers/Community/DiscordController.php @@ -17,6 +17,62 @@ class DiscordController extends Controller { + + // Handel Discord Slash Commands + public function handelDiscordCommand(Request $request) + { + $data = $request->all(); + + return $data; + + // Handle Discord's PING request + if ($data['type'] == 1) { + return response()->json(['type' => 1]); + } + + // Handle the "create_issue" slash command + if ($data['type'] == 2 && $data['data']['name'] == 'report-issue') { + // Open a modal for the user to input the issue details + return response()->json([ + 'type' => 9, // Opens a modal + 'data' => [ + 'custom_id' => 'create_github_issue_modal', + 'title' => 'Create GitHub Issue', + 'components' => [ + [ + 'type' => 1, // Action row (holds input fields) + 'components' => [ + [ + 'type' => 4, // Input field for issue title + 'custom_id' => 'issue_title', + 'label' => 'Issue Title', + 'style' => 1, // Short text + 'placeholder' => 'Enter issue title', + 'required' => true + ] + ] + ], + [ + 'type' => 1, // Action row for issue description + 'components' => [ + [ + 'type' => 4, // Input field for issue description + 'custom_id' => 'issue_description', + 'label' => 'Issue Description', + 'style' => 2, // Paragraph + 'placeholder' => 'Describe the issue in detail...', + 'required' => true + ] + ] + ] + ] + ] + ]); + } + + return response()->json(['error' => 'Invalid request'], 400); + } + public function joinShortcut() { return redirect()->route('index', ['discord' => '1']); @@ -128,7 +184,7 @@ public function linkCallbackDiscord(Request $request) //Edit user $user->discord_user_id = $discord_user['id']; $user->discord_username = $discord_user['username']; - $user->member_of_czqo = true; + // $user->member_of_czqo = true; $user->discord_avatar = $discord_user['avatar'] ? 'https://cdn.discordapp.com/avatars/'.$discord_user['id'].'/'.$discord_user['avatar'].'.png' : null; $user->save(); diff --git a/app/Http/Controllers/DiscordTestController.php b/app/Http/Controllers/DiscordTestController.php index d2a74362..86b9b906 100644 --- a/app/Http/Controllers/DiscordTestController.php +++ b/app/Http/Controllers/DiscordTestController.php @@ -4,7 +4,8 @@ use Illuminate\Http\Request; use App\Services\DiscordClient; -use App\Jobs\ProcessMonthlyBreakdown; +use Illuminate\Support\Facades\Http; +use App\Jobs\DiscordTrainingWeeklyUpdates; class DiscordTestController extends Controller { @@ -26,7 +27,7 @@ public function EditTagTest() public function Job() { // Dispatch the job - $job = ProcessMonthlyBreakdown::dispatch(); + $job = DiscordTrainingWeeklyUpdates::dispatch(); // Call the handle method directly to get the result synchronously $result = $job->handle(); @@ -73,4 +74,19 @@ public function sendMessage() $discord = new DiscordClient(); $discord->sendDM('200426385863344129', 'Test message'); } + + public function SlashCommand() + { + $discord = new DiscordClient(); + + $response = $discord->getClient()->post("applications/".env('DISCORD_CLIENT_ID')."/guilds/".env('DISCORD_GUILD_ID')."/commands", [ + 'json' => [ + 'name' => 'report-issue', + 'description' => 'Report a Web Issue', + 'type' => 1, // 1 for slash commands + ] + ]); + + return $response->json(); + } } diff --git a/app/Jobs/DiscordTrainingWeeklyUpdates.php b/app/Jobs/DiscordTrainingWeeklyUpdates.php index 56ac5461..2b4b222a 100644 --- a/app/Jobs/DiscordTrainingWeeklyUpdates.php +++ b/app/Jobs/DiscordTrainingWeeklyUpdates.php @@ -11,6 +11,7 @@ use GuzzleHttp\Client; use App\Services\DiscordClient; use App\Models\Training\Instructing\Records\TrainingSession; +use App\Models\Users\User; use App\Models\Training\Instructing\Students\Student; use App\Notifications\Training\Instructing\RemovedAsStudent; use App\Models\Training\Instructing\Students\StudentStatusLabel; @@ -35,10 +36,21 @@ public function handle() // Number of Messages Sent $to_activate = 0; + $threads_activated = ["names" => []]; // Get Active Threads $response = $discord->getClient()->get('channels/'.env('DISCORD_TRAINING_FORUM').'/threads/archived/public'); - $results = json_decode($response->getBody(), true); + $all_threads = json_decode($response->getBody(), true); + $results = ["threads" => []]; + + // dd($all_threads); + + // Filter Threads by just Training Threads + foreach($all_threads['threads'] as $each_thread){ + if(isset($each_thread['parent_id']) && $each_thread['parent_id'] === '1226234767138226338') { + $results['threads'][] = $each_thread; + } + } // dd($results); @@ -64,6 +76,8 @@ public function handle() $to_activate++; + $threads_activated["names"][] = $thread['name']; + // Thread should be active, so lets activate it. $discord = new DiscordClient(); $data = $discord->getClient()->patch('channels/'.$thread['id'], [ @@ -75,8 +89,6 @@ public function handle() } } } - - $discord->sendMessageWithEmbed(env('DISCORD_WEB_LOGS'), 'AUTO: Training Thread Opened',$to_activate. ' Threads were automatically reopended as they had expired (more than 1 week since last activity)'); } // Function for Training Thread Availability Updates @@ -84,15 +96,34 @@ public function handle() // Initialize the DiscordClient inside the handle method $discord = new DiscordClient(); - // Number of Messages Sent - $avail_message = 0; - // Get Active Threads $response = $discord->getClient()->get('guilds/'.env('DISCORD_GUILD_ID').'/threads/active'); - $results2 = json_decode($response->getBody(), true); + $all_threads2 = json_decode($response->getBody(), true); + $results2 = ["threads" => []]; + + // dd($all_threads2); + + // Filter Threads by just Training Threads + foreach($all_threads2['threads'] as $each_thread){ + if(isset($each_thread['parent_id']) && $each_thread['parent_id'] === '1226234767138226338') { + $results2['threads'][] = $each_thread; + } + } // dd($results2); + // Initialise Variables for Loop + // Number of Messages Sent + $avail_message = 0; + $avail_maessage_names = ["names" => []]; + // Exam Not Requested + $await_exam_count = 0; + $exam_request_names = ["names" => []]; + // Training Terminated + $term_training = 0; + $terminate_names = ["names" => []]; + + // Lets go through Each Active Thread Now foreach ($results2['threads'] as $thread) { // Get the ID of the Active Training Thread @@ -108,86 +139,75 @@ public function handle() $student = Student::whereCurrent(true)->where('user_id', $cid)->first(); + // If user is not a student, lets go to the next student if($student == null){ continue; } - - //Is the Applied Tag = "In Progress" or "Ready For Pick-Up"? - $tag_completed = (bool) in_array("1271846477966086265", $thread['applied_tags']); - $tag_inProgress = (bool) in_array("1271847420631978107", $thread['applied_tags']); - $tag_PickUp = (bool) in_array("1271846369510035627", $thread['applied_tags']); - - // Thread isnt completed, but is In progress or ready for pick up - if (!$tag_completed && ($tag_inProgress || $tag_PickUp)) { - - // Check Sessions Upcoming - $upcoming_sessions = TrainingSession::where('student_id', $student->id)->whereBetween('scheduled_time', [Carbon::now(), Carbon::now()->addDays(7)])->first(); - - if($upcoming_sessions == null){ - // There is no sessions within the next week - $avail_message++; - - // // SendEmbed to ask student to send availability - $discord->sendEmbedInTrainingThread($cid, "Please Provide Availability", 'Hello, <@'.$student->user->discord_user_id.'> - -As we head into the Weekend, we ask you please provide your availability for next week. Please ensure to tag the `@Instructor` role with all times you are available. Please provide these times in Zulu Format. - -One of our team will make contact with you to organise a session for next if they have availability matching yours. - -*If you have done this in the past few days, or are unable to provide any times for next week, please disregard this message.*'); - - // $discord->sendMessageWithEmbed(env('DISCORD_WEB_LOGS'), 'Thread Sent: '.$thread['name'], 'Availability Message Sent'); - } - } - } - } - // Tell the log chat - $discord->sendMessageWithEmbed(env('DISCORD_WEB_LOGS'), 'AUTO: Training Thread Availability Requests', $avail_message.' Training Threads have been messaged asking for their weekly availability. This is only completed if a student has no scheduled session within the next 7 days.'); - } + // Weekly Availability Requests + { + //Is the Applied Tag = "In Progress" or "Ready For Pick-Up"? + $tag_completed = (bool) in_array("1271846477966086265", $thread['applied_tags']); + $tag_inProgress = (bool) in_array("1271847420631978107", $thread['applied_tags']); + $tag_PickUp = (bool) in_array("1271846369510035627", $thread['applied_tags']); - // Check 'Awaiting Exam' label students between 31-37 Days after Application - { - $count = 0; - - $student = Student::whereBetween('created_at', [Carbon::now()->subDays(37), Carbon::now()->subDays(30)])->where('current', true)->get(); + // Thread isnt completed, but is In progress or ready for pick up + if (!$tag_completed && ($tag_inProgress || $tag_PickUp)) { + // Check Sessions Upcoming + $upcoming_sessions = TrainingSession::where('student_id', $cid)->whereBetween('scheduled_time', [Carbon::now(), Carbon::now()->addDays(7)])->first(); - foreach($student as $s){ - if ($s->hasLabel('Awaiting Exam')) { - // Add one to the count - $count++; - // SendEmbed to ask student to send availability - $discord->sendEmbedInTrainingThread($cid, "Exam Not Requested", 'Hello, <@'.$s->user->discord_user_id.'> + if($upcoming_sessions == null){ + // There is no sessions within the next week + $avail_message++; + $avail_maessage_names["names"][] = $thread['name']; -Our records indicate that you have not requested, or completed your exam within a month of your Application being approved. + // SendEmbed to ask student to send availability + $discord->sendEmbedInTrainingThread($cid, "Please Provide Availability", 'Hello, <@'.$student->user->discord_user_id.'> -Please read the above message in order to understand how to request the exam. +As we head into the Weekend, we ask you please provide your availability for next week. Please ensure to tag the `@Instructor` role with all times you are available. Please provide these times in Zulu Format. -Should you not request, and pass the exam within 60 days of your application being accepted, your training will be automatically terminated, and you will need to reapply to begin your training once more. +One of our team will make contact with you to organise a session for next if they have availability matching yours. -**Kind Regards, -Gander Oceanic Training Team**'); - } - } +*If you have done this in the past few days, or are unable to provide any times for next week, please disregard this message.*'); + } + } + } + + - // Tell the log chat - $discord->sendMessageWithEmbed(env('DISCORD_WEB_LOGS'), 'AUTO: Training Thread Exam Requests Reminder',$count. ' Students are between 30-37 days past application without completing the exam. They have been notified of this.'); - } + // Check 'Awaiting Exam' label students between 31-37 Days after Application + { + + $student_exam = Student::whereBetween('created_at', [Carbon::now()->subDays(37), Carbon::now()->subDays(30)])->where('user_id', $cid)->first(); + // dd($student_exam); - // Check 'Awaiting-Exam' label students 60 Days after Application and Terminate Training Automatically - { - $count2 = 0; + if($student_exam != null && $student_exam->hasLabel('Awaiting Exam')){ + $await_exam_count++; + $exam_request_names["names"][] = $thread['name']; + + // SendEmbed to ask student to send availability + $discord->sendEmbedInTrainingThread($cid, "Exam Not Requested", 'Hello, <@'.$student_exam->user->discord_user_id.'> - $student = Student::where('created_at', '<=', Carbon::now()->subDays(60))->where('current', true)->get(); + Our records indicate that you have not requested, or completed your exam within a month of your Application being approved. + + Please read the above message in order to understand how to request the exam. + + Should you not request, and pass the exam within 60 days of your application being accepted, your training will be automatically terminated, and you will need to reapply to begin your training once more. + + **Kind Regards, + Gander Oceanic Training Team**'); + } + } - foreach($student as $s){ - if ($s->hasLabel('Awaiting Exam')) { - // Add one to the count - $count2++; - // dd($s); + // Terminate Training + { + $term_training++; + $terminate_names["names"][] = $thread['name']; + $s = Student::where('created_at', '<=', Carbon::now()->subDays(60))->where('user_id', $cid)->first(); + if($s != null && $s->hasLabel('Awaiting Exam')){ //Make as not current $s->current = false; @@ -247,9 +267,79 @@ public function handle() } } - // Tell the log chat - $discord->sendMessageWithEmbed(env('DISCORD_WEB_LOGS'), 'AUTO: Training Termination',$count2. ' Students have been terminated automatically. Exam not completed within 60 days.'); + + + + + + + + + + + + + + } + } + } + + ## DISCORD UPDATE + { + // Beginning + if($avail_message > 0 || $avail_message > 0 || $await_exam_count > 0 || $term_training > 0) { + $update_content = "Full list of functions completed this week for the Discord Threads, <@200426385863344129>"; + } else { + $update_content = "No Thread Updates for this week."; + } + + // User Activiations + if($to_activate > 0){ + $update_content .= "\n\n**__Training Thread Activiation__**\n"; + $update_content .= $to_activate." training threads where activated (7 day auto close issue)."; + + // get Thread Names + foreach ($threads_activated["names"] as $name){ + $update_content .= "\n - " . $name; + } + } + + // Availability Message Updates + if($avail_message > 0){ + $update_content .= "\n\n**__Student Availability Messages__**\n"; + $update_content .= $avail_message." students asked for availability"; + + // get Thread Names + foreach ($avail_maessage_names["names"] as $name){ + $update_content .= "\n - " . $name; + } + } + + // No Exam Request after 1 Month + if($await_exam_count > 0){ + $update_content .= "\n\n**__Exam Not Requested__**\n"; + $update_content .= $await_exam_count." students have not requested the exam, they have been in the Training System for 31-37 days."; + + // get Thread Names + foreach ($exam_request_names["names"] as $name){ + $update_content .= "\n - " . $name; + } + } + + // Terminate Training + if($term_training > 0){ + $update_content .= "\n\n**__Training Terminated__**\n"; + $update_content .= $term_training." students have been terminated as they have not completed the exam within 60 days."; + + // get Thread Names + foreach ($terminate_names["names"] as $name){ + $update_content .= "\n - " . $name; + } + } + + // Send Message + $discord->sendMessageWithEmbed(env('DISCORD_WEB_LOGS'), 'WEEKLY: Discord Training Thread Updates', $update_content); } } } diff --git a/app/Jobs/ProcessShanwickController.php b/app/Jobs/ProcessShanwickController.php index caf981ba..4fc8bf72 100644 --- a/app/Jobs/ProcessShanwickController.php +++ b/app/Jobs/ProcessShanwickController.php @@ -266,7 +266,7 @@ public function handle() // Create a Request for the Shanwick Controllers $client = new Client(['timeout' => 1000]); - $response = $client->request('GET', "https://www.vatsim.uk/api/validations?position=EGGX_CTR"); + $response = $client->request('GET', 'https://www.vatsim.uk/api/validations?position=EGGX_CTR'); $data = json_decode($response->getBody(), true); $data_json = $data['validated_members']; diff --git a/routes/web.php b/routes/web.php index 4945251f..a788ed22 100644 --- a/routes/web.php +++ b/routes/web.php @@ -76,6 +76,7 @@ // Discord shortcut Route::get('/discord', [DiscordController::class, 'joinShortcut']); Route::get('/discord/function-test', [DiscordTestController::class, 'Job']); +Route::post('/discord/bot-webhook', [DiscordController::class, 'handelDiscordCommand']); // Public news articles Route::get('/news/{id}', [NewsController::class, 'viewArticlePublic'])->name('news.articlepublic')->where('id', '[0-9]+');