Add bot logs
All checks were successful
Deploy App / deploy (push) Successful in 11s

This commit is contained in:
2025-08-31 21:54:18 +02:00
parent 77ebc6bce1
commit 378355ad5b
16 changed files with 355 additions and 20 deletions

46
app/Bots/BashScript.php Normal file
View File

@@ -0,0 +1,46 @@
<?php
namespace App\Bots;
use Illuminate\Support\Facades\Log;
class BashScript implements BotContract
{
protected array $config;
public function __construct(array $config = [])
{
$this->config = $config;
}
public function run(): void
{
if (!empty($this->config['script'])) {
// Execute the bash script
$script = $this->config['script'];
$output = [];
$returnVar = null;
exec($script, $output, $returnVar);
if ($returnVar !== 0) {
// Log error if the script failed
\Illuminate\Support\Facades\Log::error("Bash script execution failed: " . implode("\n", $output));
} else {
Log::info("Bash script executed successfully: " . implode("\n", $output));
}
}
}
public static function configSchema(): array
{
return [
'script' => [
'type' => 'textarea',
'label' => 'Bash Script',
'rules' => [
'required',
]
],
];
}
}

View File

@@ -3,12 +3,13 @@
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class DashboardController extends Controller
{
public function index()
{
$bots = \App\Models\Bot::all();
$bots = Auth::user()->bots;
return view('dashboard', compact('bots'));
}

View File

@@ -3,6 +3,7 @@
namespace App\Jobs;
use App\Models\Bot;
use App\Models\BotLog;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;
@@ -13,9 +14,7 @@ class RunBot implements ShouldQueue
/**
* Create a new job instance.
*/
public function __construct(private Bot $bot)
{
}
public function __construct(private Bot $bot, private BotLog $log) {}
/**
* Execute the job.
@@ -24,6 +23,22 @@ class RunBot implements ShouldQueue
{
$class = new $this->bot->class($this->bot->config ?? []);
$class->run();
try {
$class->run();
// Update the log entry on success
$this->log->update([
'finished_at' => now(),
'status' => 'success',
// 'output' => is_string($result) ? $result : json_encode($result, JSON_PRETTY_PRINT),
]);
} catch (\Throwable $e) {
// Log the error in the bot log
$this->log->update([
'finished_at' => now(),
'status' => 'failed',
'error' => $e->getMessage(),
]);
}
}
}

35
app/Livewire/BotLogs.php Normal file
View File

@@ -0,0 +1,35 @@
<?php
namespace App\Livewire;
use App\Models\BotLog;
use Illuminate\Support\Facades\Auth;
use Livewire\Component;
use Livewire\WithoutUrlPagination;
use Livewire\WithPagination;
class BotLogs extends Component
{
use WithPagination;
use WithoutUrlPagination;
// public function mount()
// {
// $this->getLogs();
// }
// public function getLogs(): void
// {
// $this->logs = Auth::user()->bots->pluck('logs')->flatten()->sortByDesc('created_at');
// }
public function render()
{
return view('livewire.bot-logs', [
'logs' => BotLog::whereHas('bot', fn($q) => $q->where('user_id', Auth::id()))
->orderBy('created_at', 'desc')
->latest()
->paginate(10),
]);
}
}

View File

@@ -12,11 +12,21 @@ class BotsList extends Component
{
public $bots;
public string $query = '';
public function mount()
{
$this->bots = Auth::user()->bots;
}
public function search()
{
$this->bots = Auth::user()->bots()
->where('name', 'like', '%' . $this->query . '%')
->orWhere('class', 'like', '%' . $this->query . '%')
->get();
}
public function toggleBot($botId)
{
$bot = \App\Models\Bot::find($botId);
@@ -62,8 +72,13 @@ class BotsList extends Component
public function confirmRunBot(Bot $bot): void
{
$log = $bot->logs()->create([
'status' => 'pending',
'started_at' => now(),
]);
// Dispatch the job to run the bot
dispatch(new RunBot($bot));
dispatch(new RunBot($bot, $log));
flash()->success("Bot '{$bot->name}' is being executed.");
}

38
app/Livewire/ViewBot.php Normal file
View File

@@ -0,0 +1,38 @@
<?php
namespace App\Livewire;
use App\Jobs\RunBot;
use App\Models\Bot;
use Jantinnerezo\LivewireAlert\Facades\LivewireAlert;
use Livewire\Component;
class ViewBot extends Component
{
public Bot $bot;
public function runBot()
{
LivewireAlert::title('Are you sure you want to run ' . $this->bot->name . '?')
->asConfirm()
->onConfirm('confirmRunBot')
->show();
}
public function confirmRunBot(): void
{
$log = $this->bot->logs()->create([
'status' => 'pending',
]);
// Dispatch the job to run the bot
dispatch(new RunBot($this->bot, $log));
flash()->success("Bot '{$this->bot->name}' is being executed.");
}
public function render()
{
return view('livewire.view-bot');
}
}

View File

@@ -51,4 +51,19 @@ class Bot extends Model
{
return $this->belongsTo(User::class);
}
public function logs()
{
return $this->hasMany(BotLog::class);
}
public function latestLog()
{
return $this->hasOne(BotLog::class)->latestOfMany();
}
public function failedLogs()
{
return $this->hasMany(BotLog::class)->where('status', 'failed');
}
}

30
app/Models/BotLog.php Normal file
View File

@@ -0,0 +1,30 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class BotLog extends Model
{
protected $fillable = [
'bot_id',
'started_at',
'finished_at',
'status',
'output',
'error',
];
protected function casts(): array
{
return [
'started_at' => 'datetime',
'finished_at' => 'datetime',
];
}
public function bot()
{
return $this->belongsTo(Bot::class);
}
}

View File

@@ -4,6 +4,7 @@ namespace App\Services;
use App\Models\Bot;
use App\Bots\BotContract;
use App\Jobs\RunBot;
use Cron\CronExpression;
use Illuminate\Support\Facades\Log;
@@ -16,14 +17,29 @@ class BotService
foreach ($bots as $bot) {
$cron = new CronExpression($bot->schedule);
if ($cron->isDue()) {
$log = $bot->logs()->create([
'status' => 'pending',
'started_at' => now(),
]);
try {
$instance = app($bot->class, ['config' => $bot->config]);
if ($instance instanceof BotContract) {
$instance->run();
dispatch(RunBot::class, $bot, $log);
$log->update([
'started_at' => now(),
'status' => 'running'
]);
}
} catch (\Throwable $e) {
Log::error("Bot [{$bot->name}] failed: " . $e->getMessage());
$log->update([
'finished_at' => now(),
'status' => 'failed',
'error' => $e->getMessage(),
]);
}
Log::info("Bot [{$bot->name}] executed successfully.");