diff --git a/src/Webhooks/Delivery/EventBridge.php b/src/Webhooks/Delivery/EventBridge.php index 37c105a1..1dedac22 100644 --- a/src/Webhooks/Delivery/EventBridge.php +++ b/src/Webhooks/Delivery/EventBridge.php @@ -83,6 +83,6 @@ protected function getMutationName(?string $webhookId): string */ protected function queryEndpoint(string $address): string { - return "{arn: \"$address\"}"; + return "arn: \"$address\""; } } diff --git a/src/Webhooks/Delivery/HttpDelivery.php b/src/Webhooks/Delivery/HttpDelivery.php index 13319f39..99406428 100644 --- a/src/Webhooks/Delivery/HttpDelivery.php +++ b/src/Webhooks/Delivery/HttpDelivery.php @@ -94,6 +94,6 @@ protected function getMutationName(?string $webhookId): string */ protected function queryEndpoint(string $address): string { - return "{callbackUrl: \"$address\"}"; + return "callbackUrl: \"$address\""; } } diff --git a/src/Webhooks/Delivery/PubSub.php b/src/Webhooks/Delivery/PubSub.php index 5cacec28..ffc350fd 100644 --- a/src/Webhooks/Delivery/PubSub.php +++ b/src/Webhooks/Delivery/PubSub.php @@ -87,6 +87,6 @@ protected function queryEndpoint(string $address): string { $addressWithoutProtocol = explode("//", $address); list($project, $topic) = explode(":", $addressWithoutProtocol[1]); - return "{pubSubProject: \"$project\", pubSubTopic: \"$topic\"}"; + return "pubSubProject: \"$project\", pubSubTopic: \"$topic\""; } } diff --git a/src/Webhooks/DeliveryMethod.php b/src/Webhooks/DeliveryMethod.php index 89b3becb..65fdf6a7 100644 --- a/src/Webhooks/DeliveryMethod.php +++ b/src/Webhooks/DeliveryMethod.php @@ -15,6 +15,8 @@ abstract public function getCallbackAddress(string $path): string; /** * Builds the mutation name to be used depending on the delivery method and webhook id. + * If the $webhookId is null, it is assumed that the mutation name is for creating a new subscription. + * Otherwise, it is for updating an existing subscription. * * @param string|null $webhookId * @@ -23,51 +25,75 @@ abstract public function getCallbackAddress(string $path): string; abstract protected function getMutationName(?string $webhookId): string; /** - * Assembles a GraphQL query for registering a webhook. + * Assembles the webhook subscription arguments based on the callback address. + * This allows you to customize the structure of the webhook's subscription data. * - * @param string $address + * @param string $address The callback address for the webhook. * - * @return string + * @return string GraphQL formatted string for the webhook subscription arguments. */ abstract protected function queryEndpoint(string $address): string; /** * Builds a GraphQL query to check whether this topic is already registered for the shop. + * This query checks for existing webhook subscriptions for a specific topic. * - * @param string $topic + * @param string $topic The topic to check. * - * @return string + * @return string GraphQL query string to check if a topic is already registered. */ abstract public function buildCheckQuery(string $topic): string; /** - * @param array $body + * Parses the result of the check query and returns the webhookId and current delivery address. + * This method interprets the response to extract meaningful data, like the webhook ID and its delivery address. * - * @return array Array of the webhookId and current delivery address + * @param array $body The response body from the GraphQL query. + * + * @return array Array containing the webhookId and current delivery address. */ abstract public function parseCheckQueryResult(array $body): array; /** - * Assembles a GraphQL query for registering a webhook. + * Assembles a GraphQL query for registering or updating a webhook subscription. + * This method now supports adding additional optional fields and metafield namespaces, + * which allows further customization of the webhook subscription. + * The operation (create/update) is determined by the webhookId. * - * @param string $topic - * @param string $callbackAddress - * @param string|null $webhookId + * @param string $topic The topic for the webhook subscription. + * @param string $callbackAddress The callback URL for the webhook. + * @param string|null $webhookId Optional webhook ID for updating an existing subscription. + * @param array $fields Optional fields to include in the webhook subscription. + * @param array $metafieldNamespaces Optional metafield namespaces to include. * - * @return string + * @return string The GraphQL query to register or update the webhook. */ public function buildRegisterQuery( string $topic, string $callbackAddress, - ?string $webhookId = null + ?string $webhookId = null, + array $fields = [], + array $metafieldNamespaces = [] ): string { $mutationName = $this->getMutationName($webhookId); $identifier = $webhookId ? "id: \"$webhookId\"" : "topic: $topic"; $webhookSubscriptionArgs = $this->queryEndpoint($callbackAddress); + $query = "$identifier, webhookSubscription: {{$webhookSubscriptionArgs}"; + + if (!empty($fields)) { + $query .= ' fields: [' . implode(',', $fields) . ']'; + } + + if (!empty($metafieldNamespaces)) { + $query .= ' metafieldNamespaces: [' . implode(',', $metafieldNamespaces) . ']'; + } + + $query .= "}"; + return <<isSuccess($body, $webhookId); } @@ -228,10 +235,20 @@ private static function sendRegisterRequest( string $topic, string $callbackAddress, DeliveryMethod $deliveryMethod, - ?string $webhookId + ?string $webhookId, + array $fields = [], + array $metafieldNamespaces = [] ): array { + $registerQuery = $deliveryMethod->buildRegisterQuery( + $topic, + $callbackAddress, + $webhookId, + $fields, + $metafieldNamespaces + ); + $registerResponse = $client->query( - data: $deliveryMethod->buildRegisterQuery($topic, $callbackAddress, $webhookId), + data: $registerQuery, ); $statusCode = $registerResponse->getStatusCode(); diff --git a/tests/Clients/GraphqlTest.php b/tests/Clients/GraphqlTest.php index f31b2b5f..62e6d7c4 100644 --- a/tests/Clients/GraphqlTest.php +++ b/tests/Clients/GraphqlTest.php @@ -201,11 +201,12 @@ public function testCanQueryWithExtraHeaders() public function testProxyForwardsBodyAsJsonType() { $queryToProxy = << 'hear_all_about_it']; $client = new Graphql($this->domain, 'token');