mirror of
https://github.com/usetrmnl/byos_laravel.git
synced 2026-01-13 15:07:49 +00:00
feat: update plugin data via webhook
This commit is contained in:
parent
e13f9708fd
commit
b8a0aa47bf
3 changed files with 135 additions and 29 deletions
|
|
@ -313,41 +313,57 @@ HTML;
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<flux:radio.group wire:model="data_strategy" label="Data Strategy" variant="segmented">
|
<flux:radio.group wire:model.live="data_strategy" label="Data Strategy" variant="segmented">
|
||||||
<flux:radio value="polling" label="Polling"/>
|
<flux:radio value="polling" label="Polling"/>
|
||||||
<flux:radio value="webhook" label="Webhook" disabled/>
|
<flux:radio value="webhook" label="Webhook"/>
|
||||||
</flux:radio.group>
|
</flux:radio.group>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-4">
|
@if($data_strategy === 'polling')
|
||||||
<flux:input label="Polling URL" wire:model="polling_url" id="polling_url"
|
<div class="mb-4">
|
||||||
placeholder="https://example.com/api"
|
<flux:input label="Polling URL" wire:model="polling_url" id="polling_url"
|
||||||
class="block mt-1 w-full" type="text" name="polling_url" autofocus>
|
placeholder="https://example.com/api"
|
||||||
<x-slot name="iconTrailing">
|
class="block mt-1 w-full" type="text" name="polling_url" autofocus>
|
||||||
<flux:button size="sm" variant="subtle" icon="cloud-arrow-down" wire:click="updateData"
|
<x-slot name="iconTrailing">
|
||||||
tooltip="Fetch data now" class="-mr-1"/>
|
<flux:button size="sm" variant="subtle" icon="cloud-arrow-down" wire:click="updateData"
|
||||||
</x-slot>
|
tooltip="Fetch data now" class="-mr-1"/>
|
||||||
</flux:input>
|
</x-slot>
|
||||||
</div>
|
</flux:input>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<flux:radio.group wire:model="polling_verb" label="Polling Verb" variant="segmented">
|
<flux:radio.group wire:model="polling_verb" label="Polling Verb" variant="segmented">
|
||||||
<flux:radio value="get" label="GET"/>
|
<flux:radio value="get" label="GET"/>
|
||||||
<flux:radio value="post" label="POST"/>
|
<flux:radio value="post" label="POST"/>
|
||||||
</flux:radio.group>
|
</flux:radio.group>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<flux:textarea
|
<flux:textarea
|
||||||
label="Polling Headers (one per line, format: Header: Value)"
|
label="Polling Headers (one per line, format: Header: Value)"
|
||||||
wire:model="polling_header"
|
wire:model="polling_header"
|
||||||
id="polling_header"
|
id="polling_header"
|
||||||
class="block mt-1 w-full font-mono"
|
class="block mt-1 w-full font-mono"
|
||||||
name="polling_header"
|
name="polling_header"
|
||||||
rows="3"
|
rows="3"
|
||||||
placeholder="Authorization: Bearer ey.******* Content-Type: application/json"
|
placeholder="Authorization: Bearer ey.******* Content-Type: application/json"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@else
|
||||||
|
<div class="mb-4">
|
||||||
|
<flux:input
|
||||||
|
label="Webhook URL"
|
||||||
|
:value="route('api.custom_plugins.webhook', ['plugin_uuid' => $plugin->uuid])"
|
||||||
|
class="block mt-1 w-full font-mono"
|
||||||
|
readonly
|
||||||
|
copyable
|
||||||
|
>
|
||||||
|
</flux:input>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p>Send JSON payload with key <code>merge_variables</code> to the webhook URL. The payload will be merged with the plugin data.</p>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<flux:spacer/>
|
<flux:spacer/>
|
||||||
|
|
|
||||||
|
|
@ -194,3 +194,24 @@ Route::post('/display/update', function (Request $request) {
|
||||||
})
|
})
|
||||||
->name('display.update')
|
->name('display.update')
|
||||||
->middleware('auth:sanctum', 'ability:update-screen');
|
->middleware('auth:sanctum', 'ability:update-screen');
|
||||||
|
|
||||||
|
Route::post('custom_plugins/{plugin_uuid}', function (string $plugin_uuid) {
|
||||||
|
$plugin = \App\Models\Plugin::where('uuid', $plugin_uuid)->firstOrFail();
|
||||||
|
|
||||||
|
// Check if plugin uses webhook strategy
|
||||||
|
if ($plugin->data_strategy !== 'webhook') {
|
||||||
|
return response()->json(['error' => 'Plugin does not use webhook strategy'], 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
$request = request();
|
||||||
|
if (! $request->has('merge_variables')) {
|
||||||
|
return response()->json(['error' => 'Request must contain merge_variables key'], 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
$plugin->update([
|
||||||
|
'data_payload' => $request->input('merge_variables'),
|
||||||
|
'data_payload_updated_at' => now(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
return response()->json(['message' => 'Data updated successfully']);
|
||||||
|
})->name('api.custom_plugins.webhook');
|
||||||
|
|
|
||||||
69
tests/Feature/PluginWebhookTest.php
Normal file
69
tests/Feature/PluginWebhookTest.php
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use App\Models\Plugin;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
test('webhook updates plugin data for webhook strategy', function () {
|
||||||
|
// Create a plugin with webhook strategy
|
||||||
|
$plugin = Plugin::factory()->create([
|
||||||
|
'data_strategy' => 'webhook',
|
||||||
|
'data_payload' => ['old' => 'data'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Make request to update plugin data
|
||||||
|
$response = $this->postJson("/api/custom_plugins/{$plugin->uuid}", [
|
||||||
|
'merge_variables' => ['new' => 'data'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Assert response
|
||||||
|
$response->assertOk()
|
||||||
|
->assertJson(['message' => 'Data updated successfully']);
|
||||||
|
|
||||||
|
// Assert plugin was updated
|
||||||
|
$this->assertDatabaseHas('plugins', [
|
||||||
|
'id' => $plugin->id,
|
||||||
|
'data_payload' => json_encode(['new' => 'data']),
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('webhook returns 400 for non-webhook strategy plugins', function () {
|
||||||
|
// Create a plugin with non-webhook strategy
|
||||||
|
$plugin = Plugin::factory()->create([
|
||||||
|
'data_strategy' => 'polling',
|
||||||
|
'data_payload' => ['old' => 'data'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Make request to update plugin data
|
||||||
|
$response = $this->postJson("/api/custom_plugins/{$plugin->uuid}", [
|
||||||
|
'merge_variables' => ['new' => 'data'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Assert response
|
||||||
|
$response->assertStatus(400)
|
||||||
|
->assertJson(['error' => 'Plugin does not use webhook strategy']);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('webhook returns 400 when merge_variables is missing', function () {
|
||||||
|
// Create a plugin with webhook strategy
|
||||||
|
$plugin = Plugin::factory()->create([
|
||||||
|
'data_strategy' => 'webhook',
|
||||||
|
'data_payload' => ['old' => 'data'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Make request without merge_variables
|
||||||
|
$response = $this->postJson("/api/custom_plugins/{$plugin->uuid}", []);
|
||||||
|
|
||||||
|
// Assert response
|
||||||
|
$response->assertStatus(400)
|
||||||
|
->assertJson(['error' => 'Request must contain merge_variables key']);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('webhook returns 404 for non-existent plugin', function () {
|
||||||
|
// Make request with non-existent plugin UUID
|
||||||
|
$response = $this->postJson('/api/custom_plugins/'.Str::uuid(), [
|
||||||
|
'merge_variables' => ['new' => 'data'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Assert response
|
||||||
|
$response->assertNotFound();
|
||||||
|
});
|
||||||
Loading…
Add table
Add a link
Reference in a new issue