Skip to content

Commit

Permalink
Merge pull request #2 from onurkose/feature/webhooks-graphql-support
Browse files Browse the repository at this point in the history
Feature/webhooks graphql support
  • Loading branch information
onurkose authored Jun 20, 2021
2 parents b3a2f11 + e005312 commit 105b949
Show file tree
Hide file tree
Showing 9 changed files with 137 additions and 88 deletions.
12 changes: 6 additions & 6 deletions src/ShopifyApp/Actions/CreateWebhooks.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ public function __invoke(ShopIdValue $shopId, array $configWebhooks): array
*
* @return bool
*/
$exists = function (array $webhook, ResponseAccess $webhooks): bool {
foreach ($webhooks as $shopWebhook) {
if ($shopWebhook['address'] === $webhook['address']) {
$exists = static function (array $webhook, ResponseAccess $webhooks): bool {
foreach (data_get($webhooks, 'data.webhookSubscriptions.container.edges', []) as $shopWebhook) {
if (data_get($shopWebhook, 'node.endpoint.callbackUrl') === $webhook['address']) {
// Found the webhook in our list
return true;
}
Expand Down Expand Up @@ -82,10 +82,10 @@ public function __invoke(ShopIdValue $shopId, array $configWebhooks): array
}

// Delete unused webhooks
foreach ($webhooks as $webhook) {
if (! in_array($webhook->address, $used)) {
foreach (data_get($webhooks, 'data.webhookSubscriptions.container.edges', []) as $webhook) {
if (! in_array(data_get($webhook, 'node.endpoint.callbackUrl'), $used)) {
// Webhook should be deleted
$apiHelper->deleteWebhook($webhook->id);
$apiHelper->deleteWebhook(data_get($webhook, 'node.id'));
$deleted[] = $webhook;
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/ShopifyApp/Actions/DeleteWebhooks.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ public function __invoke(ShopId $shopId): array
$webhooks = $apiHelper->getWebhooks();

$deleted = [];
foreach ($webhooks as $webhook) {
foreach (data_get($webhooks, 'data.webhookSubscriptions.container.edges', []) as $webhook) {
// Its a webhook in the config, delete it
$apiHelper->deleteWebhook($webhook['id']);
$apiHelper->deleteWebhook(data_get($webhook, 'node.id'));

// Keep track of what was deleted
$deleted[] = $webhook;
Expand Down
4 changes: 2 additions & 2 deletions src/ShopifyApp/Contracts/ApiHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -167,11 +167,11 @@ public function createWebhook(array $payload): ResponseAccess;
/**
* Delete a webhook.
*
* @param int $webhookId The webhook ID to delete.
* @param string $webhookId The webhook ID to delete.
*
* @return void
*/
public function deleteWebhook(int $webhookId);
public function deleteWebhook(string $webhookId);

/**
* Creates a usage charge for a recurring charge.
Expand Down
109 changes: 76 additions & 33 deletions src/ShopifyApp/Services/ApiHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -326,56 +326,99 @@ public function createChargeGraphQL(PlanDetailsTransfer $payload): ResponseAcces

/**
* {@inheritdoc}
* TODO: Convert to GraphQL.
* @throws Exception
*/
public function getWebhooks(array $params = []): ResponseAccess
{
// Setup the params
$reqParams = array_merge(
[
'limit' => 250,
'fields' => 'id,address',
],
$params
);
$query = '
query webhookSubscriptions($first: Int!) {
webhookSubscriptions(first: $first) {
edges {
node {
id
topic
endpoint {
...on WebhookHttpEndpoint {
callbackUrl
}
}
}
}
}
}
';

// Fire the request
$response = $this->doRequest(
ApiMethod::GET(),
'/admin/webhooks.json',
$reqParams
);
$variables = [
'first' => 250,
];

return $response['body']['webhooks'];
$response = $this->doRequestGraphQL($query, $variables);

return $response['body'];
}

/**
* {@inheritdoc}
* TODO: Convert to GraphQL.
* @throws Exception
*/
public function createWebhook(array $payload): ResponseAccess
{
// Fire the request
$response = $this->doRequest(
ApiMethod::POST(),
'/admin/webhooks.json',
['webhook' => $payload]
);
$query = '
mutation webhookSubscriptionCreate(
$topic: WebhookSubscriptionTopic!,
$webhookSubscription: WebhookSubscriptionInput!
) {
webhookSubscriptionCreate(
topic: $topic
webhookSubscription: $webhookSubscription
) {
userErrors {
field
message
}
webhookSubscription {
id
}
}
}
';

return $response['body']['webhook'];
$variables = [
'topic' => $payload['topic'],
'webhookSubscription' => [
'callbackUrl' => $payload['address'],
'format' => 'JSON',
],
];

$response = $this->doRequestGraphQL($query, $variables);

return $response['body'];
}

/**
* {@inheritdoc}
* TODO: Convert to GraphQL.
* @throws Exception
*/
public function deleteWebhook(int $webhookId): ResponseAccess
public function deleteWebhook(string $webhookId): ResponseAccess
{
// Fire the request
$response = $this->doRequest(
ApiMethod::DELETE(),
"/admin/webhooks/{$webhookId}.json"
);
$query = '
mutation webhookSubscriptionDelete($id: ID!) {
webhookSubscriptionDelete(id: $id) {
userErrors {
field
message
}
deletedWebhookSubscriptionId
}
}
';

$variables = [
'id' => $webhookId,
];

$response = $this->doRequestGraphQL($query, $variables);

return $response['body'];
}
Expand Down Expand Up @@ -428,7 +471,7 @@ protected function chargeApiPath(ChargeType $chargeType): string
*
* @param ApiMethod $method The HTTP method.
* @param string $path The endpoint path.
* @param array $payload The optional payload to send to the endpoint.
* @param ?array $payload The optional payload to send to the endpoint.
*
* @throws RequestException
*
Expand Down Expand Up @@ -459,7 +502,7 @@ protected function doRequest(ApiMethod $method, string $path, array $payload = n
*
* @return array
*/
protected function doRequestGraphQL(string $query, array $payload = null)
protected function doRequestGraphQL(string $query, array $payload = []): array
{
$response = $this->api->graph($query, $payload);
if ($response['errors'] !== false) {
Expand Down
12 changes: 6 additions & 6 deletions tests/Actions/CreateWebhooksTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public function testShouldNotCreateIfExists(): void
// Create the config
$webhooks = [
[
'topic' => 'orders/create',
'topic' => 'ORDERS_CREATE',
'address' => 'https://localhost/webhooks/orders-create',
],
];
Expand All @@ -35,7 +35,7 @@ public function testShouldNotCreateIfExists(): void
$this->setApiStub();
ApiStub::stubResponses([
'get_webhooks',
'post_webhook',
'delete_webhook',
]);

// Create the shop
Expand All @@ -50,23 +50,23 @@ public function testShouldNotCreateIfExists(): void

$this->assertCount(0, $result['created']);
$this->assertCount(1, $result['deleted']);
$this->assertSame($result['deleted'][0]['address'], 'http://apple.com/uninstall');
$this->assertSame($result['deleted'][0]['node']['endpoint']['callbackUrl'], 'http://apple.com/uninstall');
}

public function testShouldCreate(): void
{
// Create the config
$webhooks = [
[
'topic' => 'orders/create',
'topic' => 'ORDERS_CREATE',
'address' => 'https://localhost/webhooks/orders-create',
],
[
'topic' => 'orders/create',
'topic' => 'ORDERS_CREATE',
'address' => 'https://localhost/webhooks/orders-create-different',
],
[
'topic' => 'app/uninstalled',
'topic' => 'APP_UNINSTALLED',
'address' => 'http://apple.com/uninstall',
],
];
Expand Down
6 changes: 3 additions & 3 deletions tests/Actions/DeleteWebhooksTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use Osiset\ShopifyApp\Test\Stubs\Api as ApiStub;
use Osiset\ShopifyApp\Test\TestCase;

class DeleteWebhooksTestTest extends TestCase
class DeleteWebhooksTest extends TestCase
{
/**
* @var \Osiset\ShopifyApp\Actions\DeleteWebhooks
Expand All @@ -26,8 +26,8 @@ public function testShouldDelete(): void
$this->setApiStub();
ApiStub::stubResponses([
'get_webhooks',
'empty',
'empty',
'delete_webhook',
'delete_webhook',
]);

// Create the shop
Expand Down
7 changes: 7 additions & 0 deletions tests/fixtures/delete_webhook.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"data": {
"webhookSubscriptionDelete": {
"id": "gid://shopify/WebhookSubscription/1016678842437"
}
}
}
56 changes: 30 additions & 26 deletions tests/fixtures/get_webhooks.json
Original file line number Diff line number Diff line change
@@ -1,28 +1,32 @@
{
"webhooks": [
{
"id": 4759306,
"address": "https:\/\/localhost\/webhooks\/orders-create",
"topic": "orders\/create",
"created_at": "2017-03-20T16:02:17-04:00",
"updated_at": "2017-03-20T16:02:17-04:00",
"format": "json",
"fields": [
],
"metafield_namespaces": [
]
},
{
"id": 901431826,
"address": "http:\/\/apple.com\/uninstall",
"topic": "app\/uninstalled",
"created_at": "2017-03-20T16:02:17-04:00",
"updated_at": "2017-03-20T16:02:17-04:00",
"format": "json",
"fields": [
],
"metafield_namespaces": [
]
"data": {
"webhookSubscriptions": {
"edges": [
{
"node": {
"id": "gid://shopify/WebhookSubscription/1016678842437",
"topic": "ORDERS_CREATE",
"endpoint": {
"callbackUrl": "https:\/\/localhost\/webhooks\/orders-create"
},
"created_at": "2017-03-20T16:02:17-04:00",
"updated_at": "2017-03-20T16:02:17-04:00",
"format": "JSON"
}
},
{
"node": {
"id": "gid://shopify/WebhookSubscription/1016678907973",
"topic": "APP_UNINSTALLED",
"endpoint": {
"callbackUrl": "http://apple.com/uninstall"
},
"created_at": "2017-03-20T16:02:17-04:00",
"updated_at": "2017-03-20T16:02:17-04:00",
"format": "JSON"
}
}
]
}
}
]
}
}
15 changes: 5 additions & 10 deletions tests/fixtures/post_webhook.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
{
"webhook": {
"id": 1047897670,
"address": "https://localhost/webhooks/app-uninstalled",
"topic": "app/uninstalled",
"created_at": "2018-12-18T09:51:03-05:00",
"updated_at": "2018-12-18T09:51:03-05:00",
"format": "json",
"fields": [],
"metafield_namespaces": []
"data": {
"webhookSubscriptionCreate": {
"id": "gid://shopify/WebhookSubscription/1016678842437"
}
}
}
}

0 comments on commit 105b949

Please sign in to comment.