Skip to content

Commit dba401b

Browse files
authored
Merge pull request #92 from ConvertKit/v4-api-webhooks
v4 API: Webhooks
2 parents f7fe5e1 + 8d57692 commit dba401b

File tree

2 files changed

+175
-37
lines changed

2 files changed

+175
-37
lines changed

Diff for: src/ConvertKit_API.php

+40-6
Original file line numberDiff line numberDiff line change
@@ -1522,6 +1522,38 @@ public function delete_broadcast(int $id)
15221522
return $this->delete(sprintf('broadcasts/%s', $id));
15231523
}
15241524

1525+
/**
1526+
* List webhooks.
1527+
*
1528+
* @param boolean $include_total_count To include the total count of records in the response, use true.
1529+
* @param string $after_cursor Return results after the given pagination cursor.
1530+
* @param string $before_cursor Return results before the given pagination cursor.
1531+
* @param integer $per_page Number of results to return.
1532+
*
1533+
* @since 2.0.0
1534+
*
1535+
* @see https://developers.convertkit.com/v4.html#list-webhooks
1536+
*
1537+
* @return false|mixed
1538+
*/
1539+
public function get_webhooks(
1540+
bool $include_total_count = false,
1541+
string $after_cursor = '',
1542+
string $before_cursor = '',
1543+
int $per_page = 100
1544+
) {
1545+
// Send request.
1546+
return $this->get(
1547+
endpoint: 'webhooks',
1548+
args: $this->build_total_count_and_pagination_params(
1549+
include_total_count: $include_total_count,
1550+
after_cursor: $after_cursor,
1551+
before_cursor: $before_cursor,
1552+
per_page: $per_page
1553+
)
1554+
);
1555+
}
1556+
15251557
/**
15261558
* Creates a webhook that will be called based on the chosen event types.
15271559
*
@@ -1531,7 +1563,7 @@ public function delete_broadcast(int $id)
15311563
*
15321564
* @since 1.0.0
15331565
*
1534-
* @see https://developers.convertkit.com/#create-a-webhook
1566+
* @see https://developers.convertkit.com/v4.html#create-a-webhook
15351567
*
15361568
* @throws \InvalidArgumentException If the event is not supported.
15371569
*
@@ -1543,6 +1575,8 @@ public function create_webhook(string $url, string $event, string $parameter = '
15431575
switch ($event) {
15441576
case 'subscriber.subscriber_activate':
15451577
case 'subscriber.subscriber_unsubscribe':
1578+
case 'subscriber.subscriber_bounce':
1579+
case 'subscriber.subscriber_complain':
15461580
case 'purchase.purchase_create':
15471581
$eventData = ['name' => $event];
15481582
break;
@@ -1590,7 +1624,7 @@ public function create_webhook(string $url, string $event, string $parameter = '
15901624

15911625
// Send request.
15921626
return $this->post(
1593-
'automations/hooks',
1627+
'webhooks',
15941628
[
15951629
'target_url' => $url,
15961630
'event' => $eventData,
@@ -1601,17 +1635,17 @@ public function create_webhook(string $url, string $event, string $parameter = '
16011635
/**
16021636
* Deletes an existing webhook.
16031637
*
1604-
* @param integer $rule_id Rule ID.
1638+
* @param integer $id Webhook ID.
16051639
*
16061640
* @since 1.0.0
16071641
*
1608-
* @see https://developers.convertkit.com/#destroy-webhook
1642+
* @see https://developers.convertkit.com/v4.html#delete-a-webhook
16091643
*
16101644
* @return false|object
16111645
*/
1612-
public function destroy_webhook(int $rule_id)
1646+
public function delete_webhook(int $id)
16131647
{
1614-
return $this->delete(sprintf('automations/hooks/%s', $rule_id));
1648+
return $this->delete(sprintf('webhooks/%s', $id));
16151649
}
16161650

16171651
/**

Diff for: tests/ConvertKitAPITest.php

+135-31
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,15 @@ class ConvertKitAPITest extends TestCase
5151
*/
5252
protected $subscriber_ids = [];
5353

54+
/**
55+
* Webhook IDs to delete on teardown of a test.
56+
*
57+
* @since 2.0.0
58+
*
59+
* @var array<int, int>
60+
*/
61+
protected $webhook_ids = [];
62+
5463
/**
5564
* Broadcast IDs to delete on teardown of a test.
5665
*
@@ -107,6 +116,11 @@ protected function tearDown(): void
107116
$this->api->unsubscribe($id);
108117
}
109118

119+
// Delete any Webhooks.
120+
foreach ($this->webhook_ids as $id) {
121+
$this->api->delete_webhook($id);
122+
}
123+
110124
// Delete any Broadcasts.
111125
foreach ($this->broadcast_ids as $id) {
112126
$this->api->delete_broadcast($id);
@@ -3846,7 +3860,82 @@ public function testDeleteBroadcastWithInvalidBroadcastID()
38463860
}
38473861

38483862
/**
3849-
* Test that create_webhook() and destroy_webhook() works.
3863+
* Test that get_webhooks() returns the expected data
3864+
* when pagination parameters and per_page limits are specified.
3865+
*
3866+
* @since 2.0.0
3867+
*
3868+
* @return void
3869+
*/
3870+
public function testGetWebhooksPagination()
3871+
{
3872+
// Create webhooks first.
3873+
$results = [
3874+
$this->api->create_webhook(
3875+
url: 'https://webhook.site/' . str_shuffle('wfervdrtgsdewrafvwefds'),
3876+
event: 'subscriber.subscriber_activate',
3877+
),
3878+
$this->api->create_webhook(
3879+
url: 'https://webhook.site/' . str_shuffle('wfervdrtgsdewrafvwefds'),
3880+
event: 'subscriber.subscriber_activate',
3881+
),
3882+
];
3883+
3884+
// Set webhook_ids to ensure webhooks are deleted after test.
3885+
$this->webhook_ids = [
3886+
$results[0]->webhook->id,
3887+
$results[1]->webhook->id,
3888+
];
3889+
3890+
// Get webhooks.
3891+
$result = $this->api->get_webhooks(
3892+
per_page: 1
3893+
);
3894+
3895+
// Assert webhooks and pagination exist.
3896+
$this->assertDataExists($result, 'webhooks');
3897+
$this->assertPaginationExists($result);
3898+
3899+
// Assert a single webhook was returned.
3900+
$this->assertCount(1, $result->webhooks);
3901+
3902+
// Assert has_previous_page and has_next_page are correct.
3903+
$this->assertFalse($result->pagination->has_previous_page);
3904+
$this->assertTrue($result->pagination->has_next_page);
3905+
3906+
// Use pagination to fetch next page.
3907+
$result = $this->api->get_webhooks(
3908+
per_page: 1,
3909+
after_cursor: $result->pagination->end_cursor
3910+
);
3911+
3912+
// Assert webhooks and pagination exist.
3913+
$this->assertDataExists($result, 'webhooks');
3914+
$this->assertPaginationExists($result);
3915+
3916+
// Assert a single webhook was returned.
3917+
$this->assertCount(1, $result->webhooks);
3918+
3919+
// Assert has_previous_page and has_next_page are correct.
3920+
$this->assertTrue($result->pagination->has_previous_page);
3921+
$this->assertFalse($result->pagination->has_next_page);
3922+
3923+
// Use pagination to fetch previous page.
3924+
$result = $this->api->get_webhooks(
3925+
per_page: 1,
3926+
before_cursor: $result->pagination->start_cursor
3927+
);
3928+
3929+
// Assert webhooks and pagination exist.
3930+
$this->assertDataExists($result, 'webhooks');
3931+
$this->assertPaginationExists($result);
3932+
3933+
// Assert a single webhook was returned.
3934+
$this->assertCount(1, $result->webhooks);
3935+
}
3936+
3937+
/**
3938+
* Test that create_webhook(), get_webhooks() and delete_webhook() works.
38503939
*
38513940
* We do both, so we don't end up with unnecessary webhooks remaining
38523941
* on the ConvertKit account when running tests.
@@ -3855,47 +3944,66 @@ public function testDeleteBroadcastWithInvalidBroadcastID()
38553944
*
38563945
* @return void
38573946
*/
3858-
public function testCreateAndDestroyWebhook()
3947+
public function testCreateGetAndDeleteWebhook()
38593948
{
3860-
$this->markTestIncomplete();
3861-
38623949
// Create a webhook first.
38633950
$result = $this->api->create_webhook(
3864-
url: 'https://webhook.site/9c731823-7e61-44c8-af39-43b11f700ecb',
3951+
url: 'https://webhook.site/' . str_shuffle('wfervdrtgsdewrafvwefds'),
38653952
event: 'subscriber.subscriber_activate',
38663953
);
3867-
$ruleID = $result->rule->id;
3954+
$id = $result->webhook->id;
3955+
3956+
// Get webhooks.
3957+
$result = $this->api->get_webhooks();
38683958

3869-
// Destroy the webhook.
3870-
$result = $this->api->destroy_webhook($ruleID);
3871-
$this->assertEquals($result->success, true);
3959+
// Assert webhooks and pagination exist.
3960+
$this->assertDataExists($result, 'webhooks');
3961+
$this->assertPaginationExists($result);
3962+
3963+
// Get webhooks including total count.
3964+
$result = $this->api->get_webhooks(
3965+
include_total_count: true
3966+
);
3967+
3968+
// Assert webhooks and pagination exist.
3969+
$this->assertDataExists($result, 'webhooks');
3970+
$this->assertPaginationExists($result);
3971+
3972+
// Assert total count is included.
3973+
$this->assertArrayHasKey('total_count', get_object_vars($result->pagination));
3974+
$this->assertGreaterThan(0, $result->pagination->total_count);
3975+
3976+
// Delete the webhook.
3977+
$result = $this->api->delete_webhook($id);
38723978
}
38733979

38743980
/**
3875-
* Test that create_webhook() and destroy_webhook() works with an event parameter.
3876-
*
3877-
* We do both, so we don't end up with unnecessary webhooks remaining
3878-
* on the ConvertKit account when running tests.
3981+
* Test that create_webhook() works with an event parameter.
38793982
*
38803983
* @since 1.0.0
38813984
*
38823985
* @return void
38833986
*/
3884-
public function testCreateAndDestroyWebhookWithEventParameter()
3987+
public function testCreateWebhookWithEventParameter()
38853988
{
3886-
$this->markTestIncomplete();
3887-
3888-
// Create a webhook first.
3989+
// Create a webhook.
3990+
$url = 'https://webhook.site/' . str_shuffle('wfervdrtgsdewrafvwefds');
38893991
$result = $this->api->create_webhook(
3890-
url: 'https://webhook.site/9c731823-7e61-44c8-af39-43b11f700ecb',
3992+
url: $url,
38913993
event: 'subscriber.form_subscribe',
38923994
parameter: $_ENV['CONVERTKIT_API_FORM_ID']
38933995
);
3894-
$ruleID = $result->rule->id;
38953996

3896-
// Destroy the webhook.
3897-
$result = $this->api->destroy_webhook($ruleID);
3898-
$this->assertEquals($result->success, true);
3997+
// Confirm webhook created with correct data.
3998+
$this->assertArrayHasKey('webhook', get_object_vars($result));
3999+
$this->assertArrayHasKey('id', get_object_vars($result->webhook));
4000+
$this->assertArrayHasKey('target_url', get_object_vars($result->webhook));
4001+
$this->assertEquals($result->webhook->target_url, $url);
4002+
$this->assertEquals($result->webhook->event->name, 'form_subscribe');
4003+
$this->assertEquals($result->webhook->event->form_id, $_ENV['CONVERTKIT_API_FORM_ID']);
4004+
4005+
// Delete the webhook.
4006+
$result = $this->api->delete_webhook($result->webhook->id);
38994007
}
39004008

39014009
/**
@@ -3908,29 +4016,25 @@ public function testCreateAndDestroyWebhookWithEventParameter()
39084016
*/
39094017
public function testCreateWebhookWithInvalidEvent()
39104018
{
3911-
$this->markTestIncomplete();
3912-
39134019
$this->expectException(InvalidArgumentException::class);
39144020
$this->api->create_webhook(
3915-
url: 'https://webhook.site/9c731823-7e61-44c8-af39-43b11f700ecb',
4021+
url: 'https://webhook.site/' . str_shuffle('wfervdrtgsdewrafvwefds'),
39164022
event: 'invalid.event'
39174023
);
39184024
}
39194025

39204026
/**
3921-
* Test that destroy_webhook() throws a ClientException when an invalid
3922-
* rule ID is specified.
4027+
* Test that delete_webhook() throws a ClientException when an invalid
4028+
* ID is specified.
39234029
*
39244030
* @since 1.0.0
39254031
*
39264032
* @return void
39274033
*/
3928-
public function testDestroyWebhookWithInvalidRuleID()
4034+
public function testDeleteWebhookWithInvalidID()
39294035
{
3930-
$this->markTestIncomplete();
3931-
39324036
$this->expectException(ClientException::class);
3933-
$this->api->destroy_webhook(12345);
4037+
$this->api->delete_webhook(12345);
39344038
}
39354039

39364040
/**

0 commit comments

Comments
 (0)