X-Git-Url: http://source.bookstackapp.com/bookstack/blobdiff_plain/04f37e21e2d1552ed537b35faba37ec53971a5bc..refs/pull/3365/head:/app/Actions/DispatchWebhookJob.php diff --git a/app/Actions/DispatchWebhookJob.php b/app/Actions/DispatchWebhookJob.php index ece6b6f08..2d805228c 100644 --- a/app/Actions/DispatchWebhookJob.php +++ b/app/Actions/DispatchWebhookJob.php @@ -3,15 +3,14 @@ namespace BookStack\Actions; use BookStack\Auth\User; -use BookStack\Entities\Models\Entity; +use BookStack\Facades\Theme; use BookStack\Interfaces\Loggable; -use BookStack\Model; +use BookStack\Theming\ThemeEvents; 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\Carbon; use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Log; @@ -22,31 +21,16 @@ class DispatchWebhookJob implements ShouldQueue use Queueable; use SerializesModels; - /** - * @var Webhook - */ - protected $webhook; - - /** - * @var string - */ - protected $event; + protected Webhook $webhook; + protected string $event; + protected User $initiator; + protected int $initiatedTime; /** * @var string|Loggable */ protected $detail; - /** - * @var User - */ - protected $initiator; - - /** - * @var int - */ - protected $initiatedTime; - /** * Create a new job instance. * @@ -68,45 +52,31 @@ class DispatchWebhookJob implements ShouldQueue */ public function handle() { - $response = Http::asJson() - ->withOptions(['allow_redirects' => ['strict' => true]]) - ->timeout(3) - ->post($this->webhook->endpoint, $this->buildWebhookData()); - - if ($response->failed()) { - Log::error("Webhook call to endpoint {$this->webhook->endpoint} failed with status {$response->status()}"); - } - } - - protected function buildWebhookData(): array - { - $textParts = [ - $this->initiator->name, - trans('activities.' . $this->event), - ]; - - if ($this->detail instanceof Entity) { - $textParts[] = '"' . $this->detail->name . '"'; + $themeResponse = Theme::dispatch(ThemeEvents::WEBHOOK_CALL_BEFORE, $this->event, $this->webhook, $this->detail, $this->initiator, $this->initiatedTime); + $webhookData = $themeResponse ?? WebhookFormatter::getDefault($this->event, $this->webhook, $this->detail, $this->initiator, $this->initiatedTime)->format(); + $lastError = null; + + try { + $response = Http::asJson() + ->withOptions(['allow_redirects' => ['strict' => true]]) + ->timeout($this->webhook->timeout) + ->post($this->webhook->endpoint, $webhookData); + } catch (\Exception $exception) { + $lastError = $exception->getMessage(); + Log::error("Webhook call to endpoint {$this->webhook->endpoint} failed with error \"{$lastError}\""); } - $data = [ - 'event' => $this->event, - 'text' => implode(' ', $textParts), - 'triggered_at' => Carbon::createFromTimestampUTC($this->initiatedTime)->toISOString(), - 'triggered_by' => $this->initiator->attributesToArray(), - 'triggered_by_profile_url' => $this->initiator->getProfileUrl(), - 'webhook_id' => $this->webhook->id, - 'webhook_name' => $this->webhook->name, - ]; - - if (method_exists($this->detail, 'getUrl')) { - $data['url'] = $this->detail->getUrl(); + if (isset($response) && $response->failed()) { + $lastError = "Response status from endpoint was {$response->status()}"; + Log::error("Webhook call to endpoint {$this->webhook->endpoint} failed with status {$response->status()}"); } - if ($this->detail instanceof Model) { - $data['related_item'] = $this->detail->attributesToArray(); + $this->webhook->last_called_at = now(); + if ($lastError) { + $this->webhook->last_errored_at = now(); + $this->webhook->last_error = $lastError; } - return $data; + $this->webhook->save(); } }