My first try on n8n. It works but at times it throws this error.
Quota exceeded for quota metric ‘Read requests’ and limit ‘Read requests per minute per user’ of service ‘sheets.googleapis.com’ for consumer 'project_number
I don’t have heavy usage. maybe one task is created/ being edited in a few minutes
`{
"meta": {
"instanceId": "ec4bdfbf077be82e0e49dee9d238326c809b54fcaf2d63e9e9623ecc4bcf6f75"
},
"nodes": [
{
"parameters": {
"authentication": "oAuth2",
"team": "9016449242",
"events": [
"taskCreated",
"taskUpdated",
"taskStatusUpdated",
"taskDeleted"
],
"filters": {}
},
"id": "5a482740-181f-49e6-ad15-a0b45b6f99b9",
"name": "ClickUp Trigger",
"type": "n8n-nodes-base.clickUpTrigger",
"typeVersion": 1,
"position": [
-900,
340
],
"webhookId": "41f86b8a-8c4d-4660-b6e0-143ed87e804e",
"credentials": {
"clickUpOAuth2Api": {
"id": "3tF4fqsQAQpDdRrQ",
"name": "ClickUp account"
}
}
},
{
"parameters": {
"jsCode": "return items.map(item => {\n // Ensure event from the trigger is retained in output\n item.json.event = item.json.event || 'Unknown';\n\n // Ensure task_id is retained in output, renamed to id\n item.json.id = item.json.task_id || 'Unknown';\n\n // Return modified item\n return item;\n});"
},
"id": "68188e0a-614f-4d7e-b3b8-103fff946bc0",
"name": "Extract Event and Task ID",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-360,
300
]
},
{
"parameters": {
"url": "=https://api.clickup.com/api/v2/task/{{$json[\"task_id\"]}}\n",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "clickUpOAuth2Api",
"options": {}
},
"id": "4f751bf1-d6ed-47fd-a207-a76f16c38fc6",
"name": "HTTP Request-Fetch Task Details",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
-360,
460
],
"credentials": {
"clickUpOAuth2Api": {
"id": "3tF4fqsQAQpDdRrQ",
"name": "ClickUp account"
}
}
},
{
"parameters": {
"operation": "append",
"documentId": {
"__rl": true,
"value": "1HyY8XPIC-s8s2Xx-vasti0NKI7AoxjBWaSTNOvURCh4",
"mode": "list",
"cachedResultName": "clickup_n8n",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1HyY8XPIC-s8s2Xx-vasti0NKI7AoxjBWaSTNOvURCh4/edit?usp=drivesdk"
},
"sheetName": {
"__rl": true,
"value": "gid=0",
"mode": "list",
"cachedResultName": "task_created",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1HyY8XPIC-s8s2Xx-vasti0NKI7AoxjBWaSTNOvURCh4/edit#gid=0"
},
"columns": {
"mappingMode": "autoMapInputData",
"value": {},
"matchingColumns": [
"id"
],
"schema": [
{
"id": "id",
"displayName": "id",
"required": false,
"defaultMatch": true,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "task_name",
"displayName": "task_name",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "description",
"displayName": "description",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "status",
"displayName": "status",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "date_created",
"displayName": "date_created",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "date_updated",
"displayName": "date_updated",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "date_deleted",
"displayName": "date_deleted",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "due_date",
"displayName": "due_date",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "time_spent",
"displayName": "time_spent",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "creator",
"displayName": "creator",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "assignees",
"displayName": "assignees",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "tags",
"displayName": "tags",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "priority",
"displayName": "priority",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "list",
"displayName": "list",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "folder",
"displayName": "folder",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "space",
"displayName": "space",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "parent",
"displayName": "parent",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "url",
"displayName": "url",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "event",
"displayName": "event",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
}
]
},
"options": {}
},
"id": "4b71f28c-cb0f-4339-bc2d-6108aaf83ffe",
"name": "Update Task Log in Google Sheets",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.5,
"position": [
1280,
440
],
"credentials": {
"googleSheetsOAuth2Api": {
"id": "cr5GBfzdNsWoDAkY",
"name": "Google Sheets account"
}
}
},
{
"parameters": {
"jsCode": "return items.map((item, index) => {\n // Extract HTTP data from the current item\n const httpData = item.json;\n\n // Extract event info from the Code1 node\n const eventData = $input.first().json.event; // Assuming the first input is from Code1 node\n\n // Extract and format status if it exists\n if (httpData.status) {\n const statusObj = httpData.status;\n httpData.status = statusObj.status; // Replace with only the \"status\" value, like \"to do\"\n } else {\n httpData.status = 'Deleted'; // Set to 'Deleted' if status does not exist (for deleted tasks)\n }\n\n // Convert timestamp to date-time format for \"date_created\", \"due_date\", \"date_updated\", and \"date_deleted\"\n const convertTimestamp = (timestamp) => {\n timestamp = Number(timestamp); // Convert to number\n\n if (!isNaN(timestamp)) {\n // Handle potential timestamp format issues\n if (timestamp.toString().length === 13) {\n // Timestamp is in milliseconds\n } else if (timestamp.toString().length === 10) {\n // Timestamp is in seconds, convert to milliseconds\n timestamp = timestamp * 1000;\n }\n\n const dateUtc = new Date(timestamp); // Convert to Date object\n\n // Check if the date is valid\n if (!isNaN(dateUtc.getTime())) {\n // Adjust the date to Indian Standard Time (GMT +5:30)\n const offsetMilliseconds = 5.5 * 60 * 60 * 1000; // 5 hours 30 minutes in milliseconds\n const adjustedDate = new Date(dateUtc.getTime() + offsetMilliseconds);\n\n // Format the date in a more readable form for Google Sheets\n return adjustedDate.toLocaleString('en-IN', {\n hour12: true\n }); // Format with Indian locale\n } else {\n return 'Invalid Date';\n }\n } else {\n return 'Invalid Timestamp';\n }\n };\n\n // Keep the raw timestamp values for comparison purposes\n const dateCreatedTimestampRaw = httpData.date_created;\n const dateUpdatedTimestampRaw = httpData.date_updated;\n\n // Handle \"date_created\"\n if (httpData.date_created) {\n httpData.date_created = convertTimestamp(httpData.date_created);\n } else {\n httpData.date_created = ''; // Set to empty if equal to \"date_created\"\n }\n\n // Handle \"date_updated\"\n if (dateUpdatedTimestampRaw) {\n if (dateCreatedTimestampRaw && dateCreatedTimestampRaw !== dateUpdatedTimestampRaw) {\n httpData.date_updated = convertTimestamp(httpData.date_updated);\n } else {\n httpData.date_updated = ''; // Set to empty if equal to \"date_created\"\n }\n } else {\n httpData.date_updated = '';\n }\n\n // Handle \"due_date\"\n if (httpData.due_date) {\n httpData.due_date = convertTimestamp(httpData.due_date);\n } else {\n httpData.due_date = '';\n }\n\n // Handle \"date_deleted\" for deleted tasks\n if (eventData === 'taskDeleted') {\n httpData.date_deleted = new Date().toLocaleString('en-IN', {\n hour12: true\n }); // Set current date-time for \"date_deleted\"\n } else {\n httpData.date_deleted = '';\n }\n\n // Extract \"creator\" name\n if (httpData.creator && httpData.creator.username) {\n httpData.creator = httpData.creator.username;\n } else {\n httpData.creator = 'Unknown';\n }\n\n // Extract \"assignees\" names\n if (Array.isArray(httpData.assignees) && httpData.assignees.length > 0) {\n const assigneeNames = httpData.assignees.map(assignee => assignee.username).join(', ');\n httpData.assignees = assigneeNames;\n } else {\n httpData.assignees = 'None';\n }\n\n // Extract \"tags\" names\n if (Array.isArray(httpData.tags) && httpData.tags.length > 0) {\n const tagNames = httpData.tags.map(tag => tag.name).join(', ');\n httpData.tags = tagNames;\n } else {\n httpData.tags = 'None';\n }\n\n // Extract \"list\" name\n if (httpData.list && httpData.list.name) {\n httpData.list = httpData.list.name;\n } else {\n httpData.list = 'Unknown';\n }\n\n // Extract \"priority\" level\n if (httpData.priority && httpData.priority.priority) {\n httpData.priority = httpData.priority.priority;\n } else {\n httpData.priority = 'None';\n }\n\n // Extract \"folder\" name\n if (httpData.folder && httpData.folder.name) {\n httpData.folder = httpData.folder.name;\n } else {\n httpData.folder = 'Unknown';\n }\n\n // Extract \"space\" ID\n if (httpData.space && httpData.space.id) {\n httpData.space = httpData.space.id;\n } else {\n httpData.space = 'Unknown';\n }\n\n // Extract \"parent\" ID\n if (httpData.parent) {\n httpData.parent = httpData.parent;\n } else {\n httpData.parent = 'None';\n }\n\n // Add \"event\" field (taken from the Code1 node)\n httpData.event = eventData;\n\n // Keep only the needed fields and rename \"name\" to \"task_name\"\n const {\n id,\n name: task_name,\n description,\n status,\n date_created,\n date_updated,\n date_deleted,\n due_date,\n time_spent,\n creator,\n assignees,\n tags,\n priority,\n list,\n folder,\n space,\n parent,\n url,\n event\n } = httpData;\n\n return {\n json: {\n id,\n task_name,\n description,\n status,\n date_created,\n date_updated,\n date_deleted,\n due_date,\n time_spent,\n creator,\n assignees,\n tags,\n priority,\n list,\n folder,\n space,\n parent,\n url,\n event\n }\n };\n});\n"
},
"id": "ac406bd1-89bc-4923-8be1-2cdcb757b4f4",
"name": "Format Task Data for Google Sheets",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
420,
440
]
},
{
"parameters": {
"jsCode": "return items.map(item => {\n // Retain the task ID and event\n const id = item.json.id || 'Unknown';\n const event = item.json.event || 'Unknown';\n\n // Get the current date and time in the desired format\n const currentDate = new Date();\n const offsetMilliseconds = 5.5 * 60 * 60 * 1000; // Indian Standard Time (GMT +5:30)\n const adjustedDate = new Date(currentDate.getTime() + offsetMilliseconds);\n const formattedDate = adjustedDate.toLocaleString('en-IN', { hour12: true });\n\n // Return the formatted data for Google Sheets\n return {\n json: {\n id,\n event,\n date_deleted: formattedDate\n }\n };\n});\n"
},
"id": "0c283169-0b43-44df-9c8b-86d8270d77c8",
"name": "Format Deleted Task Data",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-120,
320
]
},
{
"parameters": {
"jsCode": "return items.map(item => {\n // Ensure event from the trigger is retained in output\n item.json.event = item.json.event || 'Unknown';\n\n // Ensure task_id is retained in output, renamed to id\n item.json.id = item.json.task_id || 'Unknown';\n\n // Return modified item\n return item;\n});"
},
"id": "90d92935-a1e8-4b96-8685-f6f9e61a65c6",
"name": "Extract Event and Task ID1",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-360,
620
]
},
{
"parameters": {
"mode": "combine",
"fieldsToMatchString": "id",
"options": {}
},
"id": "a805c199-6474-4807-916f-af41919b59fe",
"name": "Merge Task and Event Data1",
"type": "n8n-nodes-base.merge",
"typeVersion": 3,
"position": [
-100,
540
]
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": false,
"leftValue": "",
"typeValidation": "loose",
"version": 2
},
"conditions": [
{
"id": "9dcc5e4f-5c78-405f-8221-8e929f2ce6a5",
"leftValue": "={{ $json.task_deleted }}",
"rightValue": "true",
"operator": {
"type": "string",
"operation": "contains"
}
}
],
"combinator": "and"
},
"looseTypeValidation": true,
"options": {
"ignoreCase": true
}
},
"id": "27db6f8a-13ad-4df6-99d8-2a1ce20b9c41",
"name": "If",
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
-580,
340
]
},
{
"parameters": {
"jsCode": "return items.map(item => {\n // Extract the event value from the current item\n const eventValue = item.json.event;\n\n // Create two new properties to mark the true and false branches\n if (eventValue === \"taskDeleted\") {\n // Set a flag to indicate the true branch (task is deleted)\n item.json.task_deleted = true;\n } else {\n // Set a flag to indicate the false branch (task is not deleted)\n item.json.task_deleted = false;\n }\n\n // Log the event to verify\n console.log('Event value:', eventValue);\n\n // Return the item with new properties\n return item;\n});\n"
},
"id": "35d9c293-0361-4535-86eb-b710c94a3e7d",
"name": "Code1",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-740,
340
]
}
],
"connections": {
"ClickUp Trigger": {
"main": [
[
{
"node": "Code1",
"type": "main",
"index": 0
}
]
]
},
"Extract Event and Task ID": {
"main": [
[
{
"node": "Format Deleted Task Data",
"type": "main",
"index": 0
}
]
]
},
"HTTP Request-Fetch Task Details": {
"main": [
[
{
"node": "Merge Task and Event Data1",
"type": "main",
"index": 0
}
]
]
},
"Format Task Data for Google Sheets": {
"main": [
[
{
"node": "Update Task Log in Google Sheets",
"type": "main",
"index": 0
}
]
]
},
"Format Deleted Task Data": {
"main": [
[
{
"node": "Format Task Data for Google Sheets",
"type": "main",
"index": 0
}
]
]
},
"Extract Event and Task ID1": {
"main": [
[
{
"node": "Merge Task and Event Data1",
"type": "main",
"index": 1
}
]
]
},
"Merge Task and Event Data1": {
"main": [
[
{
"node": "Format Task Data for Google Sheets",
"type": "main",
"index": 0
}
]
]
},
"If": {
"main": [
[
{
"node": "Extract Event and Task ID",
"type": "main",
"index": 0
}
],
[
{
"node": "HTTP Request-Fetch Task Details",
"type": "main",
"index": 0
},
{
"node": "Extract Event and Task ID1",
"type": "main",
"index": 0
}
]
]
},
"Code1": {
"main": [
[
{
"node": "If",
"type": "main",
"index": 0
}
]
]
}
},
"pinData": {}
}`
## Share the output returned by the last node
<!-- If you need help with data transformations, please also share your expected output. -->
## Information on your n8n setup
- **n8n version:** 1.61.0
- **Database (default: SQLite):**SQLite
- **n8n EXECUTIONS_PROCESS setting (default: own, main):**default
- **Running n8n via (Docker, npm, n8n cloud, desktop app):** Docker
- **Operating system:**