7 Commits

Author SHA1 Message Date
faf408582f Deactivate free giveaways slides
All checks were successful
Push image to registry / build-image (push) Successful in 7m44s
2025-04-19 15:27:46 +02:00
b49af7e56e Fix creating new battles
All checks were successful
Push image to registry / build-image (push) Successful in 4m25s
2025-03-20 21:11:57 +01:00
85aa0c7a04 Fix notification not sending
All checks were successful
Push image to registry / build-image (push) Successful in 4m14s
2025-03-20 20:35:27 +01:00
c26a09701a Allow sending helcase battle to custom discord webhook
All checks were successful
Push image to registry / build-image (push) Successful in 4m24s
2025-03-20 19:28:40 +01:00
fadb4d2748 Added job artifacts, dealing with cancelled battle & fixed and improved notification
All checks were successful
Push image to registry / build-image (push) Successful in 4m29s
2025-03-20 19:16:00 +01:00
c5f5d94912 Make better output 2025-03-20 19:14:45 +01:00
af96f996ee Fix debug notifications not being sent
All checks were successful
Push image to registry / build-image (push) Successful in 4m16s
2025-03-19 18:15:06 +01:00
9 changed files with 163 additions and 23 deletions

View File

@@ -171,7 +171,8 @@ class HellcaseJob extends BrowserJob implements ShouldBeUniqueUntilProcessing
])); ]));
} }
try { try {
$nextSlideButton = $browser->driver->findElement(WebDriverBy::xpath('//button[@class="_button_1ygbm_7 _next_1ygbm_24"]')); // $nextSlideButton = $browser->driver->findElement(WebDriverBy::xpath('//button[@class="_button_1ygbm_7 _next_1ygbm_24"]'));
$nextSlideButton = "Button next slide is deactivated";
} catch (\Exception $e) { } catch (\Exception $e) {
$browser->screenshot(JobDebugScreenshot::getFileName($this->jobId)); $browser->screenshot(JobDebugScreenshot::getFileName($this->jobId));
AllNotification::send(new JobDebugNotification($this->jobId, "No next slide button found")); AllNotification::send(new JobDebugNotification($this->jobId, "No next slide button found"));
@@ -186,7 +187,7 @@ class HellcaseJob extends BrowserJob implements ShouldBeUniqueUntilProcessing
} catch (\Exception $e) { } catch (\Exception $e) {
$clickedFailsCounter++; $clickedFailsCounter++;
try { try {
$nextSlideButton->click(); // $nextSlideButton->click();
} catch (\Exception $_) {} } catch (\Exception $_) {}
sleep(3); sleep(3);
continue; continue;

View File

@@ -0,0 +1,23 @@
<?php
namespace App\Browser\Jobs\HellcaseBattles;
use Laravel\Dusk\Browser;
use function rtrim;
class HellcaseBattleScreenshot {
public const IMG_FILE_NAME = "Hellcase-battle";
public static function getImgFileAbsolutePath(): string {
return rtrim(Browser::$storeScreenshotsAt, '/') . "/HellcaseBattles/" . static::IMG_FILE_NAME;
}
public static function getImgFileProjectPath(): string {
return app_path("Browser/screenshots/HellcaseBattles/" . static::IMG_FILE_NAME);
}
public static function getImgFileExternalPath(): string {
return "screenshots/HellcaseBattles/" . static::IMG_FILE_NAME;
}
}

View File

@@ -2,9 +2,11 @@
namespace App\Browser\Jobs\HellcaseBattles; namespace App\Browser\Jobs\HellcaseBattles;
use App\Browser\JobDebugScreenshot;
use App\Browser\Jobs\Hellcase\HellcaseJob; use App\Browser\Jobs\Hellcase\HellcaseJob;
use App\Models\HellcaseBattle; use App\Models\HellcaseBattle;
use App\Models\Job; use App\Models\Job;
use App\Models\JobArtifact;
use App\Models\JobRun; use App\Models\JobRun;
use App\Notification\Notifications\JobDebugNotification; use App\Notification\Notifications\JobDebugNotification;
use App\Notification\Providers\AllNotification; use App\Notification\Providers\AllNotification;
@@ -20,6 +22,7 @@ class HellcaseBattlesJob extends HellcaseJob implements ShouldBeUniqueUntilProce
{ {
private Collection $jobInfos; private Collection $jobInfos;
private array $battlesToAdd = []; private array $battlesToAdd = [];
private array $battlesSent = [];
public function __construct() public function __construct()
{ {
@@ -47,8 +50,16 @@ class HellcaseBattlesJob extends HellcaseJob implements ShouldBeUniqueUntilProce
$this->sendFinishedBattles($browser); $this->sendFinishedBattles($browser);
$this->jobRun->addArtifact(new JobArtifact([
"name" => count($this->battlesSent) . " battailles envoyées",
]));
$this->createNewBattles(); $this->createNewBattles();
$this->jobRun->addArtifact(new JobArtifact([
"name" => count($this->battlesToAdd) . " nouvelles battailles ajoutées pour surveillage",
]));
$this->jobRun->success = true; $this->jobRun->success = true;
$this->jobRun->save(); $this->jobRun->save();
@@ -70,13 +81,12 @@ class HellcaseBattlesJob extends HellcaseJob implements ShouldBeUniqueUntilProce
$browser->visit('https://hellcase.com/casebattle'); $browser->visit('https://hellcase.com/casebattle');
$browser->waitForText("CASES", 30, true); $browser->waitForText("CASES", 30, true);
AllNotification::send(new JobDebugNotification($this->jobId, "I hate niggers"));
// Sort by price // Sort by price
try { try {
$sortByPriceDiv = $browser->driver->findElement(WebDriverBy::xpath("//*[span[contains(text(), 'Value')]]")); $sortByPriceDiv = $browser->driver->findElement(WebDriverBy::xpath("//*[span[contains(text(), 'Value')]]"));
$sortByPriceDiv->click(); $sortByPriceDiv->click();
} catch (Exception $e) { } catch (Exception $e) {
$browser->screenshot(JobDebugScreenshot::getFileName($this->jobId));
AllNotification::send(new JobDebugNotification($this->jobId, "Failed to sort by price")); AllNotification::send(new JobDebugNotification($this->jobId, "Failed to sort by price"));
return; return;
} }
@@ -103,25 +113,28 @@ class HellcaseBattlesJob extends HellcaseJob implements ShouldBeUniqueUntilProce
$battleLinkButton = $battle->findElement(WebDriverBy::xpath('./div//button[text() = "watch"]')); $battleLinkButton = $battle->findElement(WebDriverBy::xpath('./div//button[text() = "watch"]'));
$battleLinkButton->sendKeys("\n"); $battleLinkButton->sendKeys("\n");
sleep(3); sleep(3);
$battleLink = $browser->driver->getCurrentURL(); try { // If we still are on the casebattle page, it means the battle was cancelled or something else
$browser->waitForLocation("https://hellcase.com/casebattle/", 3);
} catch (Exception $e) {
$battleLink = $browser->driver->getCurrentURL();
$this->battlesToAdd[$battleLink] = $battleValue; $this->battlesToAdd[$battleLink] = $battleValue;
}
} }
} }
private function sendFinishedBattles(Browser $browser) { private function sendFinishedBattles(Browser $browser) {
// foreach battle that we didn"t already planned to add with $this->battlesToAdd // foreach battle that we didn"t already planned to add with $this->battlesToAdd
foreach (HellcaseBattle::all() as $battle) { foreach (HellcaseBattle::all() as $battle) {
dump($battle);
if (!array_key_exists($battle->getUrl(), $this->battlesToAdd)) { if (!array_key_exists($battle->getUrl(), $this->battlesToAdd)) {
dump("finished");
$browser->visit($battle->getUrl()); $browser->visit($battle->getUrl());
try { sleep(2);
$browser->waitForText("Started at"); $browser->waitForText("Case Battle");
if ($this->findElementContainingText($browser, "Started at:") != null) { // battle is finished
// Send the battle // Send the battle
$this->sendBattle($browser, $battle); $this->sendBattle($browser, $battle);
} catch (Exception $e) { // Battle is not finished or error (like battle cancelled)
} }
$battle->delete(); $battle->delete();
@@ -130,16 +143,35 @@ class HellcaseBattlesJob extends HellcaseJob implements ShouldBeUniqueUntilProce
} }
private function sendBattle(Browser $browser, HellcaseBattle $battle) { private function sendBattle(Browser $browser, HellcaseBattle $battle) {
AllNotification::send(new JobDebugNotification($this->jobId, "Battle sent" . $battle->getUrl())); try {
$battleHeader = $browser->driver->findElement(WebDriverBy::xpath("//*[contains(@class, 'case-battle-game__header')]"));
sleep(2); // Wait for the animations to finish
$battleHeader->takeElementScreenshot(HellcaseBattleScreenshot::getImgFileAbsolutePath());
} catch (Exception $e) {
$browser->screenshot(JobDebugScreenshot::getFileName($this->jobId));
AllNotification::send(new JobDebugNotification($this->jobId, "Failed to screenshot battle"));
}
$this->battlesSent[$battle->getUrl()] = $battle->value;
$options = [];
if ($this->jobInfos->get("hellcase_battles_discord_webhook_url") !== null) { // Custom discord webhook
$options["discord_webhook_url"] = $this->jobInfos->get("hellcase_battles_discord_webhook_url");
}
AllNotification::send(new HellcaseBattlesNofication($this->jobId, $battle), $options);
} }
private function createNewBattles() { private function createNewBattles() {
foreach ($this->battlesToAdd as $battleLink => $battleValue) { foreach ($this->battlesToAdd as $battleLink => $battleValue) {
$battleLink = explode("/", $battleLink); $battleLink = explode("/", $battleLink);
HellcaseBattle::firstOrCreate([ try {
"battle_id" => $battleLink[count($battleLink) - 1], HellcaseBattle::create([
"value" => $battleValue, "battle_id" => $battleLink[count($battleLink) - 1],
]); "value" => $battleValue,
]);
} catch (Exception $e) {
}
} }
} }
} }

View File

@@ -0,0 +1,43 @@
<?php
namespace App\Browser\Jobs\HellcaseBattles;
use App\Models\HellcaseBattle;
use App\Notification\Notification;
use App\Notification\Stringifiable;
use App\Notification\Stringifiable\StringifiableSimpleText;
class HellcaseBattlesNofication extends Notification {
private HellcaseBattle $battle;
public function __construct(int $jobId, HellcaseBattle $battle) {
parent::__construct($jobId);
$this->battle = $battle;
$this->setBody($this->generateBody());
}
private function generateBody() {
return new HellcaseBattlesNotificationBody($this->battle);
}
public function getTitle(): Stringifiable {
return new StringifiableSimpleText("Nouvelle bataille de caisses Hellcase");
}
/**
* @inheritDoc
*/
public function getImageProjectPath(): string|null {
return HellcaseBattleScreenshot::getImgFileProjectPath();
}
/**
* @inheritDoc
*/
public function getLinkURL(): string|null {
return $this->battle->getUrl();
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace App\Browser\Jobs\HellcaseBattles;
use App\Models\HellcaseBattle;
use App\Notification\NotificationBody;
class HellcaseBattlesNotificationBody extends NotificationBody {
private HellcaseBattle $battle;
public function __construct(HellcaseBattle $battle) {
parent::__construct();
$this->battle = $battle;
}
/**
* @inheritDoc
*/
public function toMarkdownString(): string {
return "
- Valeur : **{$this->battle->value} **
- Lien : **{$this->battle->getUrl()}**
";
}
/**
* @inheritDoc
*/
public function toString(): string {
return "
- Valeur : {$this->battle->value}
- Lien : {$this->battle->getUrl()}
";
}
}

View File

@@ -3,5 +3,5 @@
namespace App\Notification; namespace App\Notification;
abstract class NotificationProvider { abstract class NotificationProvider {
abstract public static function send(Notification $notification): void; abstract public static function send(Notification $notification, array $options): void;
} }

View File

@@ -12,9 +12,9 @@ class AllNotification extends NotificationProvider {
/** /**
* @inheritDoc * @inheritDoc
*/ */
public static function send(\App\Notification\Notification $notification): void { public static function send(\App\Notification\Notification $notification, array $options = []): void {
foreach (self::NOTIFICATIONS_PROVIDERS as $provider) { foreach (self::NOTIFICATIONS_PROVIDERS as $provider) {
$provider::send($notification); $provider::send($notification, $options);
} }
} }
} }

View File

@@ -13,7 +13,7 @@ class DiscordWebHookNotification extends NotificationProvider {
/** /**
* @inheritDoc * @inheritDoc
*/ */
public static function send(\App\Notification\Notification $notification): void { public static function send(\App\Notification\Notification $notification, array $options): void {
/* /*
Test Json for a complete embed : Test Json for a complete embed :
{ {
@@ -44,7 +44,7 @@ class DiscordWebHookNotification extends NotificationProvider {
"avatar_url": "https://www.fairytailrp.com/t40344-here-come-dat-boi" "avatar_url": "https://www.fairytailrp.com/t40344-here-come-dat-boi"
} }
*/ */
$webHookUrl = static::getDiscordWebHookUrl($notification->isError); $webHookUrl = static::getDiscordWebHookUrl($notification->isError, $options);
$body = [ $body = [
"content"=> "", "content"=> "",
"tts"=> false, "tts"=> false,
@@ -86,7 +86,11 @@ class DiscordWebHookNotification extends NotificationProvider {
curl_close($ch); curl_close($ch);
} }
private static function getDiscordWebHookUrl(bool $isError): string { private static function getDiscordWebHookUrl(bool $isError, array $options): string {
if (isset($options["discord_webhook_url"]) && $options["discord_webhook_url"] !== null) {
return $options["discord_webhook_url"];
}
$generalWebHookUrlKey = 'discord_webhook_url'; $generalWebHookUrlKey = 'discord_webhook_url';
$generalWebHookUrl = Cache::rememberForever($generalWebHookUrlKey, function () use ($generalWebHookUrlKey) { $generalWebHookUrl = Cache::rememberForever($generalWebHookUrlKey, function () use ($generalWebHookUrlKey) {
return JobInfo::where('key', $generalWebHookUrlKey)->first()->value; return JobInfo::where('key', $generalWebHookUrlKey)->first()->value;

View File

@@ -13,7 +13,7 @@ Route::get('/jobs', function (Request $request) {
Route::get('/test/{id}', function (Request $request, $id, BrowserJobsInstances $BrowserJobsInstances) { Route::get('/test/{id}', function (Request $request, $id, BrowserJobsInstances $BrowserJobsInstances) {
$log = $BrowserJobsInstances->getJobInstance($id)->execute(); $log = $BrowserJobsInstances->getJobInstance($id)->execute();
dump($log); dump($log);
return response()->json(['message' => 'Job ' . $id . ' ran', 'jobRun' => $log->load('artifacts')]); dump(response()->json(['message' => 'Job ' . $id . ' ran', 'jobRun' => $log->load('artifacts')]));
}); });
Route::get('jobs/{job}/test', [JobController::class, 'test'])->name('jobs.test'); Route::get('jobs/{job}/test', [JobController::class, 'test'])->name('jobs.test');