feat: web, webhook and telegram channel drivers
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BCrwHHnGCB5XH968Nxokqw
This commit is contained in:
70
core/app/Channels/WebhookChannel.php
Normal file
70
core/app/Channels/WebhookChannel.php
Normal file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
namespace App\Channels;
|
||||
|
||||
use App\Enums\Presence;
|
||||
use App\Http\Controllers\Api\EventsController as Presenter;
|
||||
use App\Models\Delivery;
|
||||
use App\Models\Event;
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Throwable;
|
||||
|
||||
/** Универсальный webhook. В нашем случае — Home Assistant. */
|
||||
final class WebhookChannel implements ChannelDriver
|
||||
{
|
||||
public function __construct(private readonly int $presenceTimeout) {}
|
||||
|
||||
public function presence(User $user, array $config): Presence
|
||||
{
|
||||
try {
|
||||
$response = Http::timeout($this->presenceTimeout)->acceptJson()->get($config['presence_url']);
|
||||
if (! $response->successful()) {
|
||||
return Presence::Unknown;
|
||||
}
|
||||
|
||||
return $response->json('present') === true ? Presence::Present : Presence::Absent;
|
||||
} catch (Throwable) {
|
||||
return Presence::Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
public function deliver(Event $event, User $user, array $config, Delivery $delivery): DeliveryOutcome
|
||||
{
|
||||
try {
|
||||
$response = Http::timeout(5)->asJson()->post($config['deliver_url'], self::payload($event, $delivery));
|
||||
if ($response->successful()) {
|
||||
return DeliveryOutcome::ok();
|
||||
}
|
||||
|
||||
return DeliveryOutcome::failed("HTTP {$response->status()}: ".mb_substr($response->body(), 0, 200));
|
||||
} catch (Throwable $e) {
|
||||
return DeliveryOutcome::failed($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function onDone(Event $event, Delivery $delivery): void {}
|
||||
|
||||
/** @return array<string,mixed> */
|
||||
public static function payload(Event $event, Delivery $delivery): array
|
||||
{
|
||||
$presented = Presenter::present($event);
|
||||
|
||||
return [
|
||||
'event' => [
|
||||
'id' => $event->id,
|
||||
'state' => $presented['state'],
|
||||
'due_at' => $presented['due_at'],
|
||||
'source' => $event->source->name,
|
||||
'title' => $event->payload['title'],
|
||||
'subtitle' => $event->payload['subtitle'] ?? null,
|
||||
'deep_link' => $event->payload['deep_link'] ?? null,
|
||||
'done_label' => $event->payload['done_label'] ?? 'Сделано',
|
||||
],
|
||||
'actions' => [
|
||||
'ack' => route('action.ack', $delivery->action_token),
|
||||
'done' => route('action.done', $delivery->action_token),
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user