Azure Event Grid script with preprocessor template

Template for scripts triggered by Azure Event Grid. Uses a preprocessor to unpack CloudEvents envelope fields into individual `main()` arguments. Payload is already the parsed CloudEvents `data` field (or the base64 string if the publisher used `data_base64`).

Script windmill Verified

by hugo989 · 4/23/2026

The script

Submitted by hugo989 Bun
Verified 19 days ago
1
/**
2
 * General Trigger Preprocessor
3
 *
4
 * ⚠️ This function runs BEFORE the main function.
5
 *
6
 * It processes raw trigger data (e.g., Azure Event Grid, MQTT, HTTP, SQS)
7
 * before passing it to `main()`.
8
 * Common tasks:
9
 * - Extract metadata
10
 * - Filter messages
11
 * - Add timestamps/context
12
 *
13
 * The returned object determines `main()` parameters:
14
 * - `{a: 1, b: 2}` → `main(a, b)`
15
 * - `{payload}` → `main(payload)`
16
 *
17
 * @param event - Azure Event Grid trigger data. `payload` is the already-parsed
18
 *   CloudEvent `data` field (object / array / string / number / null) when the
19
 *   publisher used `data`. If the publisher used `data_base64` instead (binary
20
 *   payload), `payload` contains the base64 string — decode it here if needed.
21
 */
22
export async function preprocessor(event: {
23
	payload: any
24
	kind: 'azure'
25
	id: string
26
	source: string
27
	type: string
28
	subject?: string
29
	time?: string
30
	specversion: string
31
	datacontenttype?: string
32
	dataschema?: string
33
	headers?: Record<string, string>
34
	delivery_type: 'push' | 'pull'
35
	trigger_path: string
36
}) {
37
	if (event.kind !== 'azure') {
38
		// We assume the script is triggered by an Azure Event Grid message. If you
39
		// also want to wire it to other trigger kinds, extend this branch.
40
		throw new Error(`Expected azure trigger kind got: ${event.kind}`)
41
	}
42

43
	return {
44
		payload: event.payload,
45
		eventType: event.type,
46
		subject: event.subject,
47
		source: event.source,
48
		eventId: event.id,
49
		time: event.time,
50
		deliveryType: event.delivery_type
51
	}
52
}
53

54
/**
55
 * Main Function — handles processed Azure Event Grid events.
56
 *
57
 * Called AFTER `preprocessor()` with its return values.
58
 *
59
 * @param payload - The CloudEvent `data` field (parsed JSON) or base64 string.
60
 * @param eventType - e.g. `Microsoft.Storage.BlobCreated`.
61
 * @param subject - CloudEvents subject; for Azure system topics this is often
62
 *   a resource path (blob path, key vault secret id, etc.).
63
 * @param source - CloudEvents source; usually the producer resource.
64
 * @param eventId - Unique event id (useful for deduplication).
65
 * @param time - Event time (RFC 3339).
66
 * @param deliveryType - 'push' when Azure delivered via webhook, 'pull' when
67
 *   Windmill fetched from a Namespace queue.
68
 */
69
export async function main(
70
	payload: any,
71
	eventType: string,
72
	subject: string | undefined,
73
	source: string,
74
	eventId: string,
75
	time: string | undefined,
76
	deliveryType: 'push' | 'pull'
77
) {
78
	console.log(`[${deliveryType}] ${eventType} from ${source} (${eventId})`)
79
	return { received: payload, type: eventType, subject }
80
}
81