Example
n8n — summarize new Tidy emails to Slack
A drop-in n8n workflow that listens for email.created Tidy
events, summarizes the body with an LLM, and posts the summary to a Slack
channel. Full signature verification included.
1. Import the workflow
Copy the JSON below into n8n via Import from URL / JSON. You'll need to configure credentials for Slack and your LLM provider.
{
"name": "Tidy email to Slack",
"nodes": [
{
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"parameters": {
"httpMethod": "POST",
"path": "tidy-email-created",
"responseCode": 204
}
},
{
"name": "Verify Tidy signature",
"type": "n8n-nodes-base.code",
"parameters": {
"jsCode": "const crypto = require('crypto');\nconst sig = $input.first().json.headers['tidy-signature'];\nconst secret = $env.TIDY_WEBHOOK_SECRET;\nconst body = $input.first().json.bodyRaw;\nconst [, t, v1] = sig.match(/t=(\\d+),v1=([a-f0-9]+)/) || [];\nif (!t || !v1) throw new Error('bad sig');\nconst expected = crypto.createHmac('sha256', secret).update(`${t}.` + body).digest('hex');\nif (expected !== v1) throw new Error('sig mismatch');\nreturn $input.all();"
}
},
{
"name": "Summarize with LLM",
"type": "n8n-nodes-base.openAi",
"parameters": {
"resource": "chat",
"operation": "message",
"model": "gpt-4o-mini",
"messages": {
"values": [
{
"role": "user",
"content": "={{ \"Summarize in one line: \" + $json.data.subject + \"\\n\\n\" + $json.data.body_preview }}"
}
]
}
}
},
{
"name": "Post to Slack",
"type": "n8n-nodes-base.slack",
"parameters": {
"resource": "message",
"operation": "post",
"channel": "#inbox",
"text": "={{ \"New email: \" + $json.data.subject + \" — \" + $json('Summarize with LLM').item.json.message.content }}"
}
}
],
"connections": {
"Webhook": { "main": [[{ "node": "Verify Tidy signature", "type": "main", "index": 0 }]] },
"Verify Tidy signature": { "main": [[{ "node": "Summarize with LLM", "type": "main", "index": 0 }]] },
"Summarize with LLM": { "main": [[{ "node": "Post to Slack", "type": "main", "index": 0 }]] }
}
}2. Set the signing secret
In n8n, add an environment variable TIDY_WEBHOOK_SECRET with
the signing secret you got when you created the subscription.
3. Subscribe Tidy to n8n
curl -X POST https://qa.tidy.engineering/api/v1/event_subscriptions \
-H "Authorization: Bearer $TIDY_PAT" \
-H "Content-Type: application/json" \
-d '{
"url": "https://YOUR-N8N.example/webhook/tidy-email-created",
"event_types": ["email.created"]
}'Verification logic
The "Verify Tidy signature" code node implements the same HMAC check
documented on the webhooks page. It splits the Tidy-Signature header, reconstructs the MAC input, and
throws if the signature doesn't match — aborting the workflow and
returning a 401 to Tidy so the delivery retries.
Next steps
- Extend to other event types:
task.created,contact.merged,calendar.event_created. - Chain in a
Tidy · tasks · createstep via the HTTP Request node to auto-create follow-up tasks. - Swap Slack for Discord, Mattermost, Microsoft Teams.