Skip to content

Commit 6118b89

Browse files
authored
Fix GraphQL webhook creation and support skip_empty_messages (#440)
1 parent ff5c576 commit 6118b89

File tree

4 files changed

+56
-20
lines changed

4 files changed

+56
-20
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
### Minor Changes
88

9+
- Fixed a bug with `NotifyNamespace.createWebhook()` when using `WebhookType.GRAPHQL`. Also added the option use `skipEmptyMessages` when creating graphQL webhooks to skip empty blocks.
10+
911
## 3.3.1
1012

1113
### Minor Changes

src/api/notify-namespace.ts

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,19 @@ export class NotifyNamespace {
345345
}
346346
);
347347
}
348+
/**
349+
* Create a new {@link CustomGraphqlWebhook} to track any event on every block.
350+
*
351+
* @param url The URL that the webhook should send events to.
352+
* @param type The type of webhook to create.
353+
* @param params Parameters object containing the graphql query to be executed
354+
* on every block
355+
*/
356+
createWebhook(
357+
url: string,
358+
type: WebhookType.GRAPHQL,
359+
params: CustomGraphqlWebhookParams
360+
): Promise<CustomGraphqlWebhook>;
348361

349362
/**
350363
* Create a new {@link MinedTransactionWebhook} to track mined transactions
@@ -400,20 +413,6 @@ export class NotifyNamespace {
400413
params: NftWebhookParams
401414
): Promise<NftMetadataUpdateWebhook>;
402415

403-
/**
404-
* Create a new {@link CustomGraphqlWebhook} to track any event on every block.
405-
*
406-
* @param url The URL that the webhook should send events to.
407-
* @param type The type of webhook to create.
408-
* @param params Parameters object containing the graphql query to be executed
409-
* on every block
410-
*/
411-
createWebhook(
412-
url: string,
413-
type: WebhookType.GRAPHQL,
414-
params: CustomGraphqlWebhookParams
415-
): Promise<CustomGraphqlWebhook>;
416-
417416
/**
418417
* Create a new {@link AddressActivityWebhook} to track address activity.
419418
*
@@ -446,10 +445,11 @@ export class NotifyNamespace {
446445
let appId;
447446
if (
448447
type === WebhookType.MINED_TRANSACTION ||
449-
type === WebhookType.DROPPED_TRANSACTION
448+
type === WebhookType.DROPPED_TRANSACTION ||
449+
type === WebhookType.GRAPHQL
450450
) {
451451
if (!('appId' in params)) {
452-
throw new Error('Transaction Webhooks require an app id.');
452+
throw new Error('Transaction and GraphQL Webhooks require an app id.');
453453
}
454454
appId = params.appId;
455455
}
@@ -458,6 +458,7 @@ export class NotifyNamespace {
458458
let nftFilterObj;
459459
let addresses;
460460
let graphqlQuery;
461+
let skipEmptyMessages;
461462
if (
462463
type === WebhookType.NFT_ACTIVITY ||
463464
type === WebhookType.NFT_METADATA_UPDATE
@@ -510,6 +511,7 @@ export class NotifyNamespace {
510511
? NETWORK_TO_WEBHOOK_NETWORK.get(params.network)
511512
: network;
512513
graphqlQuery = params.graphqlQuery;
514+
skipEmptyMessages = params.skipEmptyMessages;
513515
}
514516

515517
const data = {
@@ -521,7 +523,10 @@ export class NotifyNamespace {
521523
// Only include the filters/addresses in the final response if they're defined
522524
...nftFilterObj,
523525
...(addresses && { addresses }),
524-
...(graphqlQuery && { graphql_query: graphqlQuery })
526+
...(graphqlQuery && {
527+
graphql_query: graphqlQuery
528+
}),
529+
...(skipEmptyMessages && { skip_empty_messages: skipEmptyMessages })
525530
};
526531

527532
const response = await this.sendWebhookRequest<RawCreateWebhookResponse>(

src/types/types.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1202,6 +1202,25 @@ export interface CustomGraphqlWebhookParams {
12021202
* created on network of the app provided in the api key config.
12031203
*/
12041204
network?: Network;
1205+
/**
1206+
* Whether to only receive webhooks if the query on the block is not empty.
1207+
* Defaults to false.
1208+
*/
1209+
skipEmptyMessages?: boolean;
1210+
/**
1211+
* App IDs are now required for graphQL webhooks. You can find the app ID
1212+
* following the steps here:
1213+
* {@link https://docs.alchemy.com/reference/notify-api-faq#where-can-i-find-the-app-id}.
1214+
*
1215+
* The webhook will be created on the app and network associated with the appId.
1216+
* To find the app id of a project, go to the Alchemy Dashboard in the Apps tab.
1217+
* After clicking on an app, the app id is the string in the URL following 'apps/'.
1218+
*
1219+
* Note that although this property is marked as optional, it is *actually required*
1220+
* for creating a custom GraphQL webhook. This is a workaround to avoid a breaking
1221+
* change in the API.
1222+
*/
1223+
appId?: string;
12051224
}
12061225

12071226
/**

test/integration/notify.test.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,12 @@ describe('E2E integration tests', () => {
5757
customWh = await alchemy.notify.createWebhook(
5858
webhookUrl,
5959
WebhookType.GRAPHQL,
60-
{ graphqlQuery, network: Network.ETH_MAINNET }
60+
{
61+
graphqlQuery,
62+
network: Network.ETH_MAINNET,
63+
appId,
64+
skipEmptyMessages: true
65+
}
6166
);
6267
}
6368

@@ -247,11 +252,16 @@ describe('E2E integration tests', () => {
247252
const customWebhook = await alchemy.notify.createWebhook(
248253
webhookUrl,
249254
WebhookType.GRAPHQL,
250-
{ graphqlQuery, network: Network.ETH_GOERLI }
255+
{
256+
graphqlQuery,
257+
network: Network.ETH_MAINNET,
258+
appId,
259+
skipEmptyMessages: true
260+
}
251261
);
252262
expect(customWebhook.url).toEqual(webhookUrl);
253263
expect(customWebhook.type).toEqual(WebhookType.GRAPHQL);
254-
expect(customWebhook.network).toEqual(Network.ETH_GOERLI);
264+
expect(customWebhook.network).toEqual(Network.ETH_MAINNET);
255265
let response = await alchemy.notify.getAllWebhooks();
256266
expect(
257267
response.webhooks.filter(wh => wh.id === customWebhook.id).length

0 commit comments

Comments
 (0)