]> BookStack Code Mirror - bookstack/commitdiff
Added webhook_call_before theme event hook 3138/head
authorDan Brown <redacted>
Mon, 3 Jan 2022 18:22:03 +0000 (18:22 +0000)
committerDan Brown <redacted>
Mon, 3 Jan 2022 18:22:03 +0000 (18:22 +0000)
app/Actions/DispatchWebhookJob.php
app/Theming/ThemeEvents.php
tests/ThemeTest.php

index ece6b6f0828b4a5015e27eb9ef86d23e44ed76ca..c7e75552d2b2b0f6eea226adbccb9cd24fc8e264 100644 (file)
@@ -4,8 +4,10 @@ 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;
@@ -68,10 +70,13 @@ class DispatchWebhookJob implements ShouldQueue
      */
     public function handle()
     {
+        $themeResponse = Theme::dispatch(ThemeEvents::WEBHOOK_CALL_BEFORE, $this->event, $this->webhook, $this->detail);
+        $webhookData = $themeResponse ?? $this->buildWebhookData();
+
         $response = Http::asJson()
             ->withOptions(['allow_redirects' => ['strict' => true]])
             ->timeout(3)
-            ->post($this->webhook->endpoint, $this->buildWebhookData());
+            ->post($this->webhook->endpoint, $webhookData);
 
         if ($response->failed()) {
             Log::error("Webhook call to endpoint {$this->webhook->endpoint} failed with status {$response->status()}");
index 1965556a9f13e47f6962cfcedcd0e67431295232..7acb3fac9223dbc875ab9e354b63d95ef191052c 100644 (file)
@@ -79,4 +79,20 @@ class ThemeEvents
      * @returns \League\CommonMark\ConfigurableEnvironmentInterface|null
      */
     const COMMONMARK_ENVIRONMENT_CONFIGURE = 'commonmark_environment_configure';
+
+    /**
+     * Webhook call before event.
+     * Runs before a webhook endpoint is called. Allows for customization
+     * of the data format & content within the webhook POST request.
+     * Provides the original event name as a string (see \BookStack\Actions\ActivityType)
+     * along with the webhook instance along with the event detail which may be a
+     * "Loggable" model type or a string.
+     * If the listener returns a non-null value, that will be used as the POST data instead
+     * of the system default.
+     *
+     * @param string $event
+     * @param \BookStack\Actions\Webhook $webhook
+     * @param string|\BookStack\Interfaces\Loggable $detail
+     */
+    const WEBHOOK_CALL_BEFORE = 'webhook_call_before';
 }
index 364bf6900517e65a7e727bb80613fb7e0b61d3ad..fe816255997b638d0233c6c175ba642734083e6a 100644 (file)
@@ -2,16 +2,21 @@
 
 namespace Tests;
 
+use BookStack\Actions\ActivityType;
+use BookStack\Actions\DispatchWebhookJob;
+use BookStack\Actions\Webhook;
 use BookStack\Auth\User;
 use BookStack\Entities\Models\Page;
 use BookStack\Entities\Tools\PageContent;
 use BookStack\Facades\Theme;
 use BookStack\Theming\ThemeEvents;
 use Illuminate\Console\Command;
+use Illuminate\Http\Client\Request as HttpClientRequest;
 use Illuminate\Http\Request;
 use Illuminate\Http\Response;
 use Illuminate\Support\Facades\Artisan;
 use Illuminate\Support\Facades\File;
+use Illuminate\Support\Facades\Http;
 use League\CommonMark\ConfigurableEnvironmentInterface;
 
 class ThemeTest extends TestCase
@@ -160,6 +165,36 @@ class ThemeTest extends TestCase
         $this->assertInstanceOf(User::class, $args[1]);
     }
 
+    public function test_event_webhook_call_before()
+    {
+        $args = [];
+        $callback = function (...$eventArgs) use (&$args) {
+            $args = $eventArgs;
+            return ['test' => 'hello!'];
+        };
+        Theme::listen(ThemeEvents::WEBHOOK_CALL_BEFORE, $callback);
+
+        Http::fake([
+            '*' => Http::response('', 200),
+        ]);
+
+        $webhook = new Webhook(['name' => 'Test webhook', 'endpoint' => 'https://example.com']);
+        $webhook->save();
+        $event = ActivityType::PAGE_UPDATE;
+        $detail = Page::query()->first();
+
+        dispatch((new DispatchWebhookJob($webhook, $event, $detail)));
+
+        $this->assertCount(3, $args);
+        $this->assertEquals($event, $args[0]);
+        $this->assertEquals($webhook->id, $args[1]->id);
+        $this->assertEquals($detail->id, $args[2]->id);
+
+        Http::assertSent(function (HttpClientRequest $request) {
+            return $request->isJson() && $request->data()['test'] === 'hello!';
+        });
+    }
+
     public function test_add_social_driver()
     {
         Theme::addSocialDriver('catnet', [
Morty Proxy This is a proxified and sanitized view of the page, visit original site.