use OCP\AppFramework\Db\QBMapper;
use OCP\DB\Exception;
use OCP\DB\QueryBuilder\IQueryBuilder;
+use OCP\EventDispatcher\IWebhookCompatibleEvent;
use OCP\IDBConnection;
/**
AuthMethod $authMethod,
?array $authData,
): WebhookListener {
+ if (!class_exists($event) || !is_a($event, IWebhookCompatibleEvent::class, true)) {
+ throw new \UnexpectedValueException("$event is not an event class compatible with webhooks");
+ }
$webhookListener = WebhookListener::fromParams(
[
'appId' => $appId,
AuthMethod $authMethod,
?array $authData,
): WebhookListener {
+ if (!class_exists($event) || !is_a($event, IWebhookCompatibleEvent::class, true)) {
+ throw new \UnexpectedValueException("$event is not an event class compatible with webhooks");
+ }
$webhookListener = WebhookListener::fromParams(
[
'id' => $id,
use OCP\BackgroundJob\IJobList;
use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventListener;
+use OCP\EventDispatcher\IWebhookCompatibleEvent;
use OCP\EventDispatcher\JsonSerializer;
use OCP\IUserSession;
use Psr\Log\LoggerInterface;
/**
* The class to handle the share events
- * @template-implements IEventListener<Event>
+ * @template-implements IEventListener<IWebhookCompatibleEvent>
*/
class WebhooksEventListener implements IEventListener {
public function __construct(
}
}
- private function serializeEvent(Event $event): array|\JsonSerializable {
- if ($event instanceof \JsonSerializable) {
- return $event;
- } else {
- /* Event is not serializable, we fallback to reflection to still send something */
- $data = ['class' => $event::class];
- $ref = new \ReflectionClass($event);
- foreach ($ref->getMethods() as $method) {
- if (str_starts_with($method->getName(), 'get')) {
- $key = strtolower(substr($method->getName(), 3));
- $value = $method->invoke($event);
- if ($value instanceof \OCP\Files\FileInfo) {
- $value = [
- 'id' => $value->getId(),
- 'path' => $value->getPath(),
- ];
- }
- $data[$key] = $value;
- }
- }
- $this->logger->debug('Webhook had to use fallback to serialize event '.$event::class);
- return $data;
- }
+ private function serializeEvent(IWebhookCompatibleEvent $event): array {
+ $data = $event->getWebhookSerializable();
+ $data['class'] = $event::class;
+ return $data;
}
private function filterMatch(array $filter, array $data): bool {
'OCP\\EventDispatcher\\GenericEvent' => $baseDir . '/lib/public/EventDispatcher/GenericEvent.php',
'OCP\\EventDispatcher\\IEventDispatcher' => $baseDir . '/lib/public/EventDispatcher/IEventDispatcher.php',
'OCP\\EventDispatcher\\IEventListener' => $baseDir . '/lib/public/EventDispatcher/IEventListener.php',
+ 'OCP\\EventDispatcher\\IWebhookCompatibleEvent' => $baseDir . '/lib/public/EventDispatcher/IWebhookCompatibleEvent.php',
'OCP\\EventDispatcher\\JsonSerializer' => $baseDir . '/lib/public/EventDispatcher/JsonSerializer.php',
'OCP\\Exceptions\\AbortedEventException' => $baseDir . '/lib/public/Exceptions/AbortedEventException.php',
'OCP\\Exceptions\\AppConfigException' => $baseDir . '/lib/public/Exceptions/AppConfigException.php',
'OCP\\EventDispatcher\\GenericEvent' => __DIR__ . '/../../..' . '/lib/public/EventDispatcher/GenericEvent.php',
'OCP\\EventDispatcher\\IEventDispatcher' => __DIR__ . '/../../..' . '/lib/public/EventDispatcher/IEventDispatcher.php',
'OCP\\EventDispatcher\\IEventListener' => __DIR__ . '/../../..' . '/lib/public/EventDispatcher/IEventListener.php',
+ 'OCP\\EventDispatcher\\IWebhookCompatibleEvent' => __DIR__ . '/../../..' . '/lib/public/EventDispatcher/IWebhookCompatibleEvent.php',
'OCP\\EventDispatcher\\JsonSerializer' => __DIR__ . '/../../..' . '/lib/public/EventDispatcher/JsonSerializer.php',
'OCP\\Exceptions\\AbortedEventException' => __DIR__ . '/../../..' . '/lib/public/Exceptions/AbortedEventException.php',
'OCP\\Exceptions\\AppConfigException' => __DIR__ . '/../../..' . '/lib/public/Exceptions/AppConfigException.php',
--- /dev/null
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace OCP\EventDispatcher;
+
+/**
+ * Interface for events which can be listened to by webhooks
+ *
+ * @since 30.0.0
+ */
+interface IWebhookCompatibleEvent {
+ /**
+ * Return data to be serialized and sent to the webhook. Will be serialized using json_encode.
+ *
+ * @since 30.0.0
+ */
+ public function getWebhookSerializable(): array;
+}
namespace OCP\Files\Events\Node;
use OCP\EventDispatcher\Event;
+use OCP\EventDispatcher\IWebhookCompatibleEvent;
use OCP\EventDispatcher\JsonSerializer;
use OCP\Files\Node;
/**
* @since 20.0.0
*/
-abstract class AbstractNodeEvent extends Event implements \JsonSerializable {
+abstract class AbstractNodeEvent extends Event implements IWebhookCompatibleEvent {
/**
* @since 20.0.0
*/
/**
* @since 30.0.0
*/
- public function jsonSerialize(): array {
+ public function getWebhookSerializable(): array {
return [
- 'class' => static::class,
'node' => JsonSerializer::serializeFileInfo($this->node),
];
}
namespace OCP\Files\Events\Node;
use OCP\EventDispatcher\Event;
+use OCP\EventDispatcher\IWebhookCompatibleEvent;
use OCP\EventDispatcher\JsonSerializer;
use OCP\Files\Node;
/**
* @since 20.0.0
*/
-abstract class AbstractNodesEvent extends Event {
+abstract class AbstractNodesEvent extends Event implements IWebhookCompatibleEvent {
/**
* @since 20.0.0
*/
/**
* @since 30.0.0
*/
- public function jsonSerialize(): array {
+ public function getWebhookSerializable(): array {
return [
- 'class' => static::class,
'source' => JsonSerializer::serializeFileInfo($this->source),
'target' => JsonSerializer::serializeFileInfo($this->target),
];