Skip to content

Commit fe1e7ae

Browse files
heiskrCopilot
andauthored
Article API: extract common webhook parameters and remove JSON examples (#60076)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 3621c10 commit fe1e7ae

File tree

3 files changed

+77
-16
lines changed

3 files changed

+77
-16
lines changed

src/article-api/templates/webhooks-page.template.md

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,19 @@
88
{{ manualContent }}
99
{% endif %}
1010

11+
{% if commonParams.size > 0 %}
12+
## Common payload parameters
13+
14+
Most webhook events include these standard parameters:
15+
16+
| Name | Type | Description |
17+
|------|------|-------------|
18+
{% for param in commonParams %}| `{{ param.name }}` | `{{ param.type }}` | {% if param.isRequired %}**Required.** {% endif %}{{ param.description }} |
19+
{% endfor %}
20+
21+
Events below list only their additional parameters beyond these common ones.
22+
23+
{% endif %}
1124
{% for webhook in webhooks %}
1225
## {{ webhook.name }}
1326

@@ -40,13 +53,5 @@
4053
{% for param in webhook.bodyParameters %}| `{{ param.name }}` | `{{ param.type }}` | {% if param.isRequired %}**Required.** {% endif %}{{ param.description }} |
4154
{% endfor %}
4255

43-
{% endif %}
44-
{% if webhook.payloadExample %}
45-
### Webhook payload example
46-
47-
```json
48-
{{ webhook.payloadExample }}
49-
```
50-
5156
{% endif %}
5257
{% endfor %}

src/article-api/tests/webhooks-transformer.ts

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,11 +122,46 @@ describe('Webhooks transformer', () => {
122122
const res = await get(makeURL('/en/webhooks/webhook-events-and-payloads'))
123123
expect(res.statusCode).toBe(200)
124124

125-
// NOTE: The current webhook source data does not include payloadExample fields,
126-
// so this section won't appear in the output. The transformer code (lines 115-120)
127-
// is ready to display payload examples if/when they are added to the source data.
128-
// For now, we just verify the transformer doesn't crash on missing examples.
125+
// Payload examples are deliberately omitted from the article API output to save space.
126+
// The property tables describe the payload structure instead.
127+
expect(res.body).not.toContain('### Webhook payload example')
128+
expect(res.body).not.toMatch(/```json/)
129+
})
130+
131+
test('common parameters are extracted into a shared section', async () => {
132+
const res = await get(makeURL('/en/webhooks/webhook-events-and-payloads'))
129133
expect(res.statusCode).toBe(200)
134+
135+
// Should have a common parameters section at the top
136+
expect(res.body).toContain('## Common payload parameters')
137+
expect(res.body).toContain('Most webhook events include these standard parameters')
138+
139+
// Common params like 'sender' and 'repository' should appear in the common section
140+
// (they're in 60%+ of webhook events)
141+
const commonSection = res.body.split('## Common payload parameters')[1]?.split('\n## ')[0] || ''
142+
expect(commonSection).toContain('`sender`')
143+
expect(commonSection).toContain('`repository`')
144+
})
145+
146+
test('common parameters are not repeated in individual webhook sections', async () => {
147+
const res = await get(makeURL('/en/webhooks/webhook-events-and-payloads'))
148+
expect(res.statusCode).toBe(200)
149+
150+
// Find individual webhook sections after the common section
151+
const sections = res.body.split('\n## ')
152+
const webhookSections = sections.filter(
153+
(s: string) => !s.startsWith('Common payload parameters') && !s.startsWith(sections[0]), // skip content before first ##
154+
)
155+
156+
// In individual webhook parameter tables, common params should not appear
157+
for (const section of webhookSections.slice(0, 3)) {
158+
// If the section has a parameter table
159+
if (section.includes('#### Webhook payload object parameters')) {
160+
const tableContent = section.split('#### Webhook payload object parameters')[1] || ''
161+
// 'sender' should NOT appear in individual tables
162+
expect(tableContent).not.toMatch(/\|\s*`sender`\s*\|/)
163+
}
164+
}
130165
})
131166

132167
test('Non-webhooks pages are not transformed', async () => {

src/article-api/transformers/webhooks-transformer.ts

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ export class WebhooksTransformer implements PageTransformer {
4848
}
4949
}
5050

51-
// Prepare webhooks data for template
51+
// Prepare webhooks data for template (payload examples are omitted to save space)
5252
const preparedWebhooks = webhooksData.map((webhook) => ({
5353
name: webhook.name,
5454
actionTypes: webhook.actionTypes,
@@ -63,11 +63,31 @@ export class WebhooksTransformer implements PageTransformer {
6363
: '',
6464
isRequired: param.isRequired || false,
6565
})),
66-
payloadExample: webhook.data.payloadExample
67-
? JSON.stringify(webhook.data.payloadExample, null, 2)
68-
: null,
6966
}))
7067

68+
// Identify common body parameters that appear in most webhooks
69+
const paramCounts = new Map<string, number>()
70+
for (const webhook of preparedWebhooks) {
71+
for (const param of webhook.bodyParameters) {
72+
paramCounts.set(param.name, (paramCounts.get(param.name) || 0) + 1)
73+
}
74+
}
75+
const threshold = preparedWebhooks.length * 0.6
76+
const commonParamNames = new Set(
77+
[...paramCounts.entries()].filter(([, count]) => count >= threshold).map(([name]) => name),
78+
)
79+
80+
// Remove common params from each webhook and collect them for summary
81+
const commonParams =
82+
preparedWebhooks[0]?.bodyParameters.filter((p: { name: string }) =>
83+
commonParamNames.has(p.name),
84+
) || []
85+
for (const webhook of preparedWebhooks) {
86+
webhook.bodyParameters = webhook.bodyParameters.filter(
87+
(p: { name: string }) => !commonParamNames.has(p.name),
88+
)
89+
}
90+
7191
// Prepare template data
7292
const templateData: Record<string, unknown> = {
7393
page: {
@@ -76,6 +96,7 @@ export class WebhooksTransformer implements PageTransformer {
7696
},
7797
manualContent,
7898
webhooks: preparedWebhooks,
99+
commonParams,
79100
}
80101

81102
// Load and render template

0 commit comments

Comments
 (0)