This workflow corresponds to n8n.io template #16697 — we link there as the canonical source.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"id": "mUEXvxg3mTX2d52n",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "Figma fire event - ping Slack",
"tags": [],
"nodes": [
{
"id": "5f8f5bff-1a84-4d4f-be51-db6961d26d5f",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
368,
-160
],
"parameters": {
"width": 480,
"height": 896,
"content": "Figma fire event - ping slack\n\n### How it works\n\nThis workflow monitors three Figma event types: library published, file comment, and file deleted. Each trigger runs through its own formatting code node to create an appropriate Slack message, then all formatted messages converge into a single Slack posting node. It provides an internal event log in Slack for key Figma activity.\n\n### Setup steps\n\n- Configure the Figma trigger credentials and webhook/event subscriptions for library publish, file comment, and file delete events.\n- Configure the Slack credentials on the Post to Slack node and select the target workspace and channel.\n- Review each formatting code node to confirm it matches the actual Figma payload fields and produces the Slack message format expected by the Slack node.\n- Activate the workflow and test each Figma event type to verify the notification reaches Slack.\n\n### Customization\n\nAdjust the three formatting code nodes to change message text, include links or metadata, mention users, or add routing logic. The Slack node can be pointed to a different channel for staging, production, or event-specific logging."
},
"typeVersion": 1
},
{
"id": "b7dce9c0-d5d8-4ea0-9d90-317b3de7ab61",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
928,
-160
],
"parameters": {
"color": 7,
"width": 512,
"height": 304,
"content": "## Library publish event\n\nTop lane that listens for Figma library publish events and formats the event details into a Slack-ready message."
},
"typeVersion": 1
},
{
"id": "d641dddf-8946-46ee-a761-6aa429a75f7f",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
928,
176
],
"parameters": {
"color": 7,
"width": 512,
"height": 320,
"content": "## File comment event\n\nMiddle lane that listens for new Figma file comments and converts the comment payload into the standard Slack message structure."
},
"typeVersion": 1
},
{
"id": "4704aba6-52c3-4f14-a3b7-bc44da67a988",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
928,
528
],
"parameters": {
"color": 7,
"width": 512,
"height": 304,
"content": "## File deletion event\n\nBottom lane that listens for Figma file deletion events and formats the deletion details for Slack notification."
},
"typeVersion": 1
},
{
"id": "42cb07d9-5952-4024-950f-ff45fcb4de21",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
1584,
-16
],
"parameters": {
"color": 7,
"height": 400,
"content": "## Shared Slack notification\n\nShared output node on the right that receives formatted messages from all three Figma event lanes and posts them to Slack."
},
"typeVersion": 1
},
{
"id": "467999f0-d517-47a6-b85d-c59e0fe7a6c7",
"name": "When Library Published",
"type": "n8n-nodes-base.figmaTrigger",
"position": [
976,
-32
],
"parameters": {
"triggerOn": "libraryPublish"
},
"typeVersion": 1
},
{
"id": "46e8a9cd-35be-4d84-b76d-92236b1c4592",
"name": "When File Commented",
"type": "n8n-nodes-base.figmaTrigger",
"position": [
976,
336
],
"parameters": {
"triggerOn": "fileComment"
},
"typeVersion": 1
},
{
"id": "4f6ba317-da21-4496-a26d-4946b9d42140",
"name": "When File Deleted",
"type": "n8n-nodes-base.figmaTrigger",
"position": [
976,
656
],
"parameters": {
"triggerOn": "fileDelete"
},
"typeVersion": 1
},
{
"id": "1ce9f3f1-ac52-40ba-9c46-d65531aae29b",
"name": "Send Message to Slack",
"type": "n8n-nodes-base.slack",
"position": [
1632,
224
],
"parameters": {
"text": "={{ $json.slackText }}",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "id",
"value": "C0BD9B326S3"
},
"otherOptions": {
"mrkdwn": true,
"includeLinkToWorkflow": false
}
},
"typeVersion": 2.5
},
{
"id": "dd62da13-4b3b-489c-a4a7-e434baf1cc5a",
"name": "Build Library Event Message",
"type": "n8n-nodes-base.code",
"position": [
1296,
-32
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "// LIBRARY_PUBLISH \u2192 Slack message\n// Payload has created/modified/deleted arrays for components, styles and\n// variables. Each array item looks like { name, key }.\nconst j = $json;\n\nconst count = (arr) => (arr || []).length;\nconst names = (arr) => (arr || []).map((x) => x.name).filter(Boolean);\n\n// Summarise only the categories that actually changed,\n// e.g. \"4 components, 1 style, 2 variables updated\".\nconst group = (label, created, modified, deleted) => {\n const total = count(created) + count(modified) + count(deleted);\n if (!total) return null;\n return total + ' ' + label + (total !== 1 ? 's' : '');\n};\nconst summary = [\n group('component', j.created_components, j.modified_components, j.deleted_components),\n group('style', j.created_styles, j.modified_styles, j.deleted_styles),\n group('variable', j.created_variables, j.modified_variables, j.deleted_variables),\n].filter(Boolean).join(', ');\n\n// Preview the first few changed item names: \"Button, Card (+4 more)\".\nconst changedNames = [].concat(\n names(j.created_components), names(j.modified_components), names(j.deleted_components),\n names(j.created_styles), names(j.modified_styles), names(j.deleted_styles),\n names(j.created_variables), names(j.modified_variables), names(j.deleted_variables),\n);\nconst preview = changedNames.slice(0, 3).join(', ');\nconst more = changedNames.length > 3 ? ' (+' + (changedNames.length - 3) + ' more)' : '';\n\nconst author = (j.triggered_by && j.triggered_by.handle) || 'Unknown';\nconst when = slackDate(j.timestamp);\n\n// Build the message line by line; skip lines we have no data for.\nconst lines = ['\ud83c\udfa8 *Library published* \u2014 *' + j.file_name + '*'];\nif (summary) lines.push(summary + ' updated');\nif (preview) lines.push('Changed: ' + preview + more);\nif (j.description) lines.push('Note: ' + j.description);\nlines.push('by ' + author + (when ? ' \u00b7 ' + when : ''));\nlines.push('<https://www.figma.com/file/' + j.file_key + '|Open in Figma>');\n\nreturn { slackText: lines.join('\\n') };\n\n// Absolute, viewer-local timestamp via a Slack date token\n// (renders as e.g. \"Jun 28, 2026 at 5:24 PM\" in each reader's timezone).\nfunction slackDate(iso) {\n if (!iso) return '';\n const epoch = Math.floor(new Date(iso).getTime() / 1000);\n return '<!date^' + epoch + '^{date_short} at {time}|' + iso + '>';\n}"
},
"typeVersion": 2
},
{
"id": "c48bfa08-adf4-4edb-bd58-35d7bd6051fd",
"name": "Build Comment Event Message",
"type": "n8n-nodes-base.code",
"position": [
1296,
336
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "// FILE_COMMENT \u2192 Slack message\n// The same event fires for new comments, replies (parent_id set) and\n// resolves (resolved_at set). The comment body is an array of fragments,\n// each either { text } or { mention: <userId> }.\nconst j = $json;\n\n// Map mentioned user ids \u2192 handles, using the top-level mentions[] list.\nconst handleById = {};\nfor (const u of (j.mentions || [])) {\n if (u && u.id) handleById[u.id] = u.handle;\n}\n\n// Rebuild the comment text, swapping mention ids for \"@handle\".\nconst body = (j.comment || [])\n .map((frag) => {\n if (frag && frag.text != null) return frag.text;\n if (frag && frag.mention) return '@' + (handleById[frag.mention] || 'someone');\n return '';\n })\n .join('')\n .trim();\n\nconst author = (j.triggered_by && j.triggered_by.handle) || 'Someone';\nconst mentioned = (j.mentions || []).map((u) => u.handle).filter(Boolean);\n\n// Heading depends on the kind of comment event.\nlet heading = '\ud83d\udcac *New comment*';\nif (j.resolved_at) heading = '\ud83d\udcac *Comment resolved*';\nelse if (j.parent_id) heading = '\ud83d\udcac *New reply*';\n\nconst lines = [heading + ' \u2014 *' + j.file_name + '*'];\nlines.push(author + (mentioned.length ? ' \u2192 ' + mentioned.join(', ') : '') + ': \"' + body + '\"');\nlines.push(\n (slackDate(j.timestamp) ? slackDate(j.timestamp) + ' \u00b7 ' : '') +\n '<https://www.figma.com/file/' + j.file_key + '?comment-id=' + j.comment_id + '|Reply in Figma>'\n);\n\nreturn { slackText: lines.join('\\n') };\n\n// Absolute, viewer-local timestamp via a Slack date token.\nfunction slackDate(iso) {\n if (!iso) return '';\n const epoch = Math.floor(new Date(iso).getTime() / 1000);\n return '<!date^' + epoch + '^{date_short} at {time}|' + iso + '>';\n}"
},
"typeVersion": 2
},
{
"id": "6f6e4de0-3175-4600-93c8-e67921afb34d",
"name": "Build Delete Event Message",
"type": "n8n-nodes-base.code",
"position": [
1296,
656
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "// FILE_DELETE \u2192 Slack message\nconst j = $json;\n\nconst author = (j.triggered_by && j.triggered_by.handle) || 'Someone';\nconst when = slackDate(j.timestamp);\n\nconst lines = ['\ud83d\uddd1\ufe0f *File deleted* \u2014 *' + j.file_name + '*'];\nlines.push('by ' + author + (when ? ' \u00b7 ' + when : ''));\nlines.push('Recoverable from Figma trash for 30 days');\n\nreturn { slackText: lines.join('\\n') };\n\n// Absolute, viewer-local timestamp via a Slack date token.\nfunction slackDate(iso) {\n if (!iso) return '';\n const epoch = Math.floor(new Date(iso).getTime() / 1000);\n return '<!date^' + epoch + '^{date_short} at {time}|' + iso + '>';\n}"
},
"typeVersion": 2
}
],
"active": false,
"settings": {
"binaryMode": "separate",
"availableInMCP": false,
"executionOrder": "v1"
},
"versionId": "45b5e0a6-dfca-40c3-9199-572994aad555",
"nodeGroups": [],
"connections": {
"When File Deleted": {
"main": [
[
{
"node": "Build Delete Event Message",
"type": "main",
"index": 0
}
]
]
},
"When File Commented": {
"main": [
[
{
"node": "Build Comment Event Message",
"type": "main",
"index": 0
}
]
]
},
"When Library Published": {
"main": [
[
{
"node": "Build Library Event Message",
"type": "main",
"index": 0
}
]
]
},
"Build Delete Event Message": {
"main": [
[
{
"node": "Send Message to Slack",
"type": "main",
"index": 0
}
]
]
},
"Build Comment Event Message": {
"main": [
[
{
"node": "Send Message to Slack",
"type": "main",
"index": 0
}
]
]
},
"Build Library Event Message": {
"main": [
[
{
"node": "Send Message to Slack",
"type": "main",
"index": 0
}
]
]
}
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow listens for Figma team events (library publishes, file comments, and file deletions), formats each event into a readable message, and posts the result to a chosen Slack channel. Triggers when a Figma team library is published. Triggers when a new Figma file comment…
Source: https://n8n.io/workflows/16697/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
Track all n8n workflow failures with automatic error capture, severity classification, duplicate detection, Slack alerting, performance metrics, and log retention.
This workflow captures n8n workflow execution errors, classifies and deduplicates them, logs incidents to a Notion database, and routes high-severity alerts to a Slack channel, with an optional daily
Automates monitoring of error logs and notifies developers of critical errors. Sends Slack alerts for critical and non-critical errors, with auto-creation of Jira tickets for critical issues. Triggers
Stay ahead of payment disputes with this automated n8n workflow that integrates Stripe, Slack, and ClickUp. Perfect for finance teams, payment ops specialists, and SaaS businesses, this template fetch
Teams that live in Notion and want an instant ping to the right person when a task changes state. Perfect for content creators, project managers, or any small team that tracks work in a Notion databas