Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
CalumTowers committed Jan 9, 2025
1 parent 2eb48f2 commit 18cff1b
Show file tree
Hide file tree
Showing 6 changed files with 157 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace App\Http\Controllers\External\VatsimNet;

use App\Http\Controllers\BaseController;

class ProcessVatsimNetWebhook extends BaseController
{
public function __invoke()
{
if (request()->header('Authorization') !== config('services.vatsim-net.webhook.key')) {
return response()->json([
'status' => 'forbidden',
], 403);
}

foreach (request()->json('actions') as $action) {
if (class_exists($class = config("services.vatsim-net.webhook.jobs.{$action['action']}"))) {
dispatch(new $class(request()->json('resource'), $action));
// ->afterResponse();
}
}

return response()->json([
'status' => 'ok',
]);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php

namespace App\Jobs\ExternalServices\VatsimNet\Webhooks;

use App\Models\Mship\Account;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;

class MemberChangedAction implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

protected int $memberId;

protected array $data;

public function __construct(int $memberId, array $data)
{
$this->memberId = $memberId;
$this->data = $data;
}

public function handle()
{
foreach ($this->data['deltas'] as $delta) {
match ($delta['field']) {
'id', 'name_first', 'name_last', 'email', 'reg_date' => $this->processAccountChange($delta['field'], $delta['after']),
'rating' => $this->processAtcRatingChange($delta['after']),
'pilotrating' => $this->processPilotRatingChange($delta['after']),
'division_id', 'region_id' => $this->processStateChange($delta['after']),
default => null
};
}
}

private function processAccountChange(string $field, mixed $value): void
{
Account::firstWhere('id', $this->memberId)->update([
$field => $value,
]);
}

private function processAtcRatingChange(mixed $value): void
{
Account::firstWhere('id', $this->memberId)->updateVatsimRatings(atcRating: $value);
}

private function processPilotRatingChange(mixed $value): void
{
Account::firstWhere('id', $this->memberId)->updateVatsimRatings(pilotRating: $value);
}

private function processStateChange(mixed $value): void
{
// if both a division and region is changed in the deltas
// this will run twice, which is not ideal

$account = Account::with('states')->firstWhere('id', $this->memberId);

$currentRegion = $account->primary_permanent_state->pivot->region;
$currentDivision = $account->primary_permanent_state->pivot->division;

$regionChange = collect($this->data['deltas'])->firstWhere('field', 'region_id');
$divisionChange = collect($this->data['deltas'])->firstWhere('field', 'division_id');

$account->updateDivision(
division: is_null($divisionChange) ? $currentDivision : $divisionChange['after'],
region: is_null($regionChange) ? $currentRegion : $regionChange['after'],
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

namespace App\Jobs\ExternalServices\VatsimNet\Webhooks;

use App\Models\Mship\Account;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Arr;

class MemberCreatedAction implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

protected int $memberId;

protected array $data;

public function __construct(int $memberId, array $data)
{
$this->memberId = $memberId;
$this->data = $data;
}

public function handle()
{
$account = Account::updateOrCreate(['id' => $this->getField('id')], [
'name_first' => $this->getField('name_first'),
'name_last' => $this->getField('name_last'),
'email' => $this->getField('email'),
'joined_at' => $this->getField('reg_date'),
]);
$account->updateVatsimRatings($this->getField('rating'), $this->getField('pilotrating'));
$account->updateDivision($this->getField('division_id'), $this->getField('region_id'));
$account->save();
}

private function getField(string $field)
{
return Arr::get(collect($this->data['deltas'])->firstWhere('field', $field), 'after');
}
}
2 changes: 1 addition & 1 deletion app/Models/Mship/Concerns/HasQualifications.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public function removeQualification(Qualification $qualification)
* @param int|null $atcRating The VATSIM ATC rating
* @param int|null $pilotRating The VATSIM pilot rating
*/
public function updateVatsimRatings(?int $atcRating, ?int $pilotRating)
public function updateVatsimRatings(?int $atcRating = null, ?int $pilotRating = null)
{
if ($atcRating === 0) {
$this->addNetworkBan('Network ban discovered via Cert login.');
Expand Down
7 changes: 7 additions & 0 deletions config/services.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
<?php

use App\Jobs\ExternalServices\VatsimNet\Webhooks\MemberChangedAction;
use App\Jobs\ExternalServices\VatsimNet\Webhooks\MemberCreatedAction;

return [

/*
Expand Down Expand Up @@ -78,6 +81,10 @@
'vatsim-net' => [
'webhook' => [
'key' => env('VATSIM_NET_WEBHOOK_KEY'),
'jobs' => [
'member_created_action' => MemberCreatedAction::class,
'member_changed_action' => MemberChangedAction::class,
],
],
'api' => [
'base' => env('VATSIM_API_BASE', 'https://api.vatsim.net/api/'),
Expand Down
16 changes: 3 additions & 13 deletions routes/web-external.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php

use App\Http\Controllers\External\VatsimNet\ProcessVatsimNetWebhook;

Route::group([
'prefix' => 'external',
'as' => 'external.',
Expand All @@ -9,19 +11,7 @@
'prefix' => 'vatsim-net',
'as' => 'vatsim-net.',
], function () {

Route::post('webhook', function () {
Log::info(print_r([
'Authorization' => request()->header('Authorization'),
'User-Agent' => request()->header('User-Agent'),
'Body' => request()->all(),
], true));

return response()->json([
'status' => 'ok',
]);
})->name('webhook');

Route::post('webhook', ProcessVatsimNetWebhook::class)->name('webhook');
});

});

0 comments on commit 18cff1b

Please sign in to comment.