Skip to content

Commit 729667a

Browse files
committed
fix(notion): align webhook lifecycle and outputs
Handle Notion verification requests safely, expose the documented webhook fields in the trigger contract, and update setup guidance so runtime data and user-facing configuration stay aligned. Made-with: Cursor
1 parent 317d4ab commit 729667a

File tree

2 files changed

+94
-9
lines changed

2 files changed

+94
-9
lines changed

apps/sim/lib/webhooks/providers/notion.ts

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,21 +53,59 @@ export const notionHandler: WebhookProviderHandler = {
5353
providerLabel: 'Notion',
5454
}),
5555

56+
handleReachabilityTest(body: unknown, requestId: string) {
57+
const obj = body as Record<string, unknown> | null
58+
const verificationToken = obj?.verification_token
59+
60+
if (typeof verificationToken === 'string' && verificationToken.length > 0) {
61+
logger.info(`[${requestId}] Notion verification request detected - returning 200`)
62+
return NextResponse.json({
63+
status: 'ok',
64+
message: 'Webhook endpoint verified',
65+
})
66+
}
67+
68+
return null
69+
},
70+
5671
async formatInput({ body }: FormatInputContext): Promise<FormatInputResult> {
5772
const b = body as Record<string, unknown>
73+
const rawEntity =
74+
b.entity && typeof b.entity === 'object' ? (b.entity as Record<string, unknown>) : {}
75+
const rawData = b.data && typeof b.data === 'object' ? (b.data as Record<string, unknown>) : {}
76+
const rawParent =
77+
rawData.parent && typeof rawData.parent === 'object'
78+
? (rawData.parent as Record<string, unknown>)
79+
: null
80+
5881
return {
5982
input: {
6083
id: b.id,
6184
type: b.type,
6285
timestamp: b.timestamp,
86+
api_version: b.api_version,
6387
workspace_id: b.workspace_id,
6488
workspace_name: b.workspace_name,
6589
subscription_id: b.subscription_id,
6690
integration_id: b.integration_id,
6791
attempt_number: b.attempt_number,
6892
authors: b.authors || [],
69-
entity: b.entity || {},
70-
data: b.data || {},
93+
accessible_by: b.accessible_by || [],
94+
entity: {
95+
...rawEntity,
96+
entity_type: rawEntity.type,
97+
},
98+
data: {
99+
...rawData,
100+
...(rawParent
101+
? {
102+
parent: {
103+
...rawParent,
104+
parent_type: rawParent.type,
105+
},
106+
}
107+
: {}),
108+
},
71109
},
72110
}
73111
},

apps/sim/triggers/notion/utils.ts

Lines changed: 54 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,14 @@ export function notionSetupInstructions(eventType: string): string {
3232
'Ensure the integration has access to the pages/databases you want to monitor (share them with the integration).',
3333
]
3434

35+
if (eventType === 'comment.created') {
36+
instructions.splice(
37+
7,
38+
0,
39+
'Enable the <strong>comment read</strong> capability in your Notion integration settings so comment events can be delivered.'
40+
)
41+
}
42+
3543
return instructions
3644
.map(
3745
(instruction, index) =>
@@ -71,11 +79,16 @@ function buildBaseOutputs(): Record<string, TriggerOutput> {
7179
description: 'Event type (e.g., page.created, database.schema_updated)',
7280
},
7381
timestamp: { type: 'string', description: 'ISO 8601 timestamp of the event' },
82+
api_version: { type: 'string', description: 'Notion API version included with the event' },
7483
workspace_id: { type: 'string', description: 'Workspace ID where the event occurred' },
7584
workspace_name: { type: 'string', description: 'Workspace name' },
7685
subscription_id: { type: 'string', description: 'Webhook subscription ID' },
7786
integration_id: { type: 'string', description: 'Integration ID that received the event' },
7887
attempt_number: { type: 'number', description: 'Delivery attempt number' },
88+
accessible_by: {
89+
type: 'array',
90+
description: 'Array of users and bots that can access the entity',
91+
},
7992
}
8093
}
8194

@@ -85,7 +98,7 @@ function buildBaseOutputs(): Record<string, TriggerOutput> {
8598
function buildEntityOutputs(): Record<string, TriggerOutput> {
8699
return {
87100
id: { type: 'string', description: 'Entity ID (page or database ID)' },
88-
entity_type: { type: 'string', description: 'Entity type (page or database)' },
101+
entity_type: { type: 'string', description: 'Entity type (page, database, block, or comment)' },
89102
}
90103
}
91104

@@ -101,9 +114,20 @@ export function buildPageEventOutputs(): Record<string, TriggerOutput> {
101114
},
102115
entity: buildEntityOutputs(),
103116
data: {
117+
updated_blocks: {
118+
type: 'array',
119+
description: 'Blocks updated as part of the event, when provided by Notion',
120+
},
121+
updated_properties: {
122+
type: 'array',
123+
description: 'Property IDs updated as part of the event, when provided by Notion',
124+
},
104125
parent: {
105126
id: { type: 'string', description: 'Parent page or database ID' },
106-
parent_type: { type: 'string', description: 'Parent type (database, page, workspace)' },
127+
parent_type: {
128+
type: 'string',
129+
description: 'Parent type (database, page, block, or workspace)',
130+
},
107131
},
108132
},
109133
}
@@ -121,9 +145,17 @@ export function buildDatabaseEventOutputs(): Record<string, TriggerOutput> {
121145
},
122146
entity: buildEntityOutputs(),
123147
data: {
148+
updated_blocks: {
149+
type: 'array',
150+
description: 'Blocks updated as part of the event, when provided by Notion',
151+
},
152+
updated_properties: {
153+
type: 'array',
154+
description: 'Database properties updated as part of the event, when provided by Notion',
155+
},
124156
parent: {
125157
id: { type: 'string', description: 'Parent page or workspace ID' },
126-
parent_type: { type: 'string', description: 'Parent type (page, workspace)' },
158+
parent_type: { type: 'string', description: 'Parent type (page, database, or workspace)' },
127159
},
128160
},
129161
}
@@ -144,9 +176,10 @@ export function buildCommentEventOutputs(): Record<string, TriggerOutput> {
144176
entity_type: { type: 'string', description: 'Entity type (comment)' },
145177
},
146178
data: {
179+
page_id: { type: 'string', description: 'Page ID that owns the comment thread' },
147180
parent: {
148-
id: { type: 'string', description: 'Parent page ID' },
149-
parent_type: { type: 'string', description: 'Parent type (page)' },
181+
id: { type: 'string', description: 'Parent page or block ID' },
182+
parent_type: { type: 'string', description: 'Parent type (page or block)' },
150183
},
151184
},
152185
}
@@ -164,8 +197,22 @@ export function buildGenericWebhookOutputs(): Record<string, TriggerOutput> {
164197
},
165198
entity: buildEntityOutputs(),
166199
data: {
167-
type: 'json',
168-
description: 'Event-specific data including parent information',
200+
parent: {
201+
id: { type: 'string', description: 'Parent entity ID, when provided by Notion' },
202+
parent_type: {
203+
type: 'string',
204+
description: 'Parent entity type (page, database, block, or workspace), when present',
205+
},
206+
},
207+
page_id: { type: 'string', description: 'Page ID related to the event, when present' },
208+
updated_blocks: {
209+
type: 'array',
210+
description: 'Blocks updated as part of the event, when provided by Notion',
211+
},
212+
updated_properties: {
213+
type: 'array',
214+
description: 'Updated properties included with the event, when provided by Notion',
215+
},
169216
},
170217
}
171218
}

0 commit comments

Comments
 (0)