Automatisation Clockify avec n8n : sauvegarde et gestion des rapports
Ce workflow n8n a pour objectif d'automatiser la sauvegarde et la gestion des rapports mensuels à partir de Clockify. Dans un contexte où les entreprises doivent régulièrement analyser leurs données de temps, ce template permet d'extraire des informations précises, de les comparer et de les sauvegarder efficacement. Les cas d'usage incluent la gestion des heures travaillées, la création de rapports détaillés et la mise à jour automatique des fichiers sur GitHub.
- Étape 1 : le workflow commence par un déclencheur programmé qui active le processus à intervalles réguliers.
- Étape 2 : les données sont extraites d'un fichier, puis les ensembles de données sont comparés pour identifier les différences.
- Étape 3 : si des erreurs sont détectées, le workflow s'arrête et renvoie un message d'erreur.
- Étape 4 : les résultats sont ensuite filtrés pour ignorer les rapports vides, et les données pertinentes sont envoyées à GitHub pour mise à jour ou création de fichiers. Ce processus réduit considérablement le temps passé sur la gestion manuelle des rapports et minimise les risques d'erreurs humaines, offrant ainsi une solution efficace pour les équipes de gestion de projet.
Workflow n8n Clockify, GitHub, gestion des rapports : vue d'ensemble
Schéma des nœuds et connexions de ce workflow n8n, généré à partir du JSON n8n.
Workflow n8n Clockify, GitHub, gestion des rapports : détail des nœuds
Inscris-toi pour voir l'intégralité du workflow
Inscription gratuite
S'inscrire gratuitementBesoin d'aide ?{
"id": "k22TSNIZXHaQ9rGr",
"meta": {
"instanceId": "fb8bc2e315f7f03c97140b30aa454a27bc7883a19000fa1da6e6b571bf56ad6d",
"templateCredsSetupCompleted": true
},
"name": "Clockify Backup Template",
"tags": [
{
"id": "RKga6I6NviNI12bx",
"name": "template",
"createdAt": "2024-09-19T19:09:21.997Z",
"updatedAt": "2024-09-19T19:09:21.997Z"
}
],
"nodes": [
{
"id": "24115363-9a03-4f8a-aa6e-2a9d4247f035",
"name": "Extract from File",
"type": "n8n-nodes-base.extractFromFile",
"position": [
660,
400
],
"parameters": {
"options": {},
"operation": "fromJson"
},
"typeVersion": 1
},
{
"id": "11aa4b51-98f9-4df8-b2d2-6757fe686894",
"name": "Compare Datasets",
"type": "n8n-nodes-base.compareDatasets",
"position": [
880,
280
],
"parameters": {
"options": {},
"mergeByFields": {
"values": [
{
"field1": "data",
"field2": "data"
}
]
}
},
"typeVersion": 2.3
},
{
"id": "831ad368-6a46-4dd4-bb6c-8ea46200cdf0",
"name": "Stop and Error",
"type": "n8n-nodes-base.stopAndError",
"position": [
880,
700
],
"parameters": {
"errorMessage": "={{ $json.error }}"
},
"typeVersion": 1
},
{
"id": "2f838fc8-96bf-4111-aaba-743e0c88b688",
"name": "Globals",
"type": "n8n-nodes-base.set",
"position": [
-660,
480
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "6bd5904d-0218-4075-a767-d4b659def9b0",
"name": "workspace_id",
"type": "string",
"value": "={{ $json.id }}"
},
{
"id": "63fa6231-6c5b-414f-b813-18f7dd5c33e9",
"name": "github_repo.owner",
"type": "string",
"value": ""
},
{
"id": "be2530d7-b2b5-41c5-af19-ab8d27f18e2e",
"name": "github_repo.name",
"type": "string",
"value": ""
}
]
}
},
"typeVersion": 3.4
},
{
"id": "bea9590e-355e-410a-bc4b-ae777efb9f15",
"name": "Set month indexes",
"type": "n8n-nodes-base.set",
"position": [
-440,
480
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "ad278249-5320-4ffa-8d75-e47194c83e58",
"name": "monthIndex",
"type": "array",
"value": "=[0, 1, 2]"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "f541d535-80d9-439d-8543-9c3cb156a5ff",
"name": "Split Out indexes",
"type": "n8n-nodes-base.splitOut",
"position": [
-220,
480
],
"parameters": {
"options": {},
"fieldToSplitOut": "monthIndex"
},
"typeVersion": 1
},
{
"id": "76c74727-d338-4a61-9bf2-e97893721995",
"name": "Set intervals",
"type": "n8n-nodes-base.set",
"position": [
0,
480
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "7f5ff2ee-b93c-4121-b3dc-ce592513db88",
"name": "reportName",
"type": "string",
"value": "=detailed_report_{{ $now.minus($json.monthIndex, 'month').format('yyyy-MM') }}"
},
{
"id": "ea571bdb-8f51-4852-9fda-55ff1a929d1f",
"name": "startDate",
"type": "string",
"value": "={{ $now.minus($json.monthIndex, 'month').startOf('month').format('yyyy-MM-dd') }}"
},
{
"id": "e88726c4-1eb8-4f29-9805-7b0a5ee484a4",
"name": "endDate",
"type": "string",
"value": "={{ $now.minus($json.monthIndex, 'month').endOf('month').format('yyyy-MM-dd') }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "6d5e917e-68ac-4dbd-98be-4c8ad97fa54a",
"name": "Skip empty reports",
"type": "n8n-nodes-base.filter",
"position": [
880,
500
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "f6c69f9b-9e78-4a1e-af33-a1197f35e970",
"operator": {
"type": "array",
"operation": "notEmpty",
"singleValue": true
},
"leftValue": "={{ $json.timeentries }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "60c7a408-74d3-4c6c-ac78-1ed1071e873e",
"name": "Get first workspace",
"type": "n8n-nodes-base.clockify",
"position": [
-880,
480
],
"parameters": {
"limit": 1,
"resource": "workspace"
},
"credentials": {
"clockifyApi": {
"id": "CMJ0LAYOs143GAXw",
"name": "Clockify (octionictest)"
}
},
"typeVersion": 1
},
{
"id": "824bf2c6-9159-40ec-83f3-3f0b8d87c208",
"name": "Get detailed monthly report",
"type": "n8n-nodes-base.httpRequest",
"position": [
220,
480
],
"parameters": {
"url": "=https://reports.api.clockify.me/v1/workspaces/{{ $('Globals').item.json.workspace_id }}/reports/detailed",
"method": "POST",
"options": {},
"jsonBody": "={\n \"dateRangeStart\": \"{{ $json.startDate }}T00:00:00Z\",\n \"dateRangeEnd\": \"{{ $json.endDate }}T23:59:59.999Z\",\n \"detailedFilter\": {\n \"page\": 1,\n \"pageSize\": 50\n },\n \"exportType\": \"json\"\n}",
"sendBody": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "clockifyApi"
},
"credentials": {
"clockifyApi": {
"id": "CMJ0LAYOs143GAXw",
"name": "Clockify (octionictest)"
}
},
"typeVersion": 4.2
},
{
"id": "f9323c68-c70f-4f22-ae18-916d5fc1b264",
"name": "Check if file exists in GitHub",
"type": "n8n-nodes-base.github",
"onError": "continueErrorOutput",
"position": [
440,
480
],
"parameters": {
"owner": {
"__rl": true,
"mode": "name",
"value": "={{ $('Globals').first().json.github_repo.owner }}"
},
"filePath": "=reports/{{ $('Set intervals').item.json.reportName }}",
"resource": "file",
"operation": "get",
"repository": {
"__rl": true,
"mode": "name",
"value": "={{ $('Globals').first().json.github_repo.name }}"
},
"additionalParameters": {}
},
"credentials": {
"githubApi": {
"id": "Eb9yCfVJGJvXD05z",
"name": "GitHub (n8n-test-01)"
}
},
"retryOnFail": false,
"typeVersion": 1
},
{
"id": "41877a6a-ba5b-43bd-8ca3-f8402793685f",
"name": "Point to new data",
"type": "n8n-nodes-base.set",
"position": [
660,
200
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "00d2885f-451e-436e-8852-b9ad086d231b",
"name": "data",
"type": "array",
"value": "={{ $('Get detailed monthly report').item.json.timeentries }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "9f448921-5b9d-4937-a7d9-00a62b1fba99",
"name": "Check for 404 error message",
"type": "n8n-nodes-base.if",
"position": [
660,
600
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "6b34c09d-0136-433c-856d-b29a0c3aac34",
"operator": {
"type": "string",
"operation": "contains"
},
"leftValue": "={{ $json.error }}",
"rightValue": "could not be found"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "900905ed-cff6-4ebb-b0da-67db9f02b301",
"name": "Update file in GitHub",
"type": "n8n-nodes-base.github",
"position": [
1100,
180
],
"parameters": {
"owner": {
"__rl": true,
"mode": "name",
"value": "={{ $('Globals').first().json.github_repo.owner }}"
},
"filePath": "=reports/{{ $('Set intervals').item.json.reportName }}",
"resource": "file",
"operation": "edit",
"repository": {
"__rl": true,
"mode": "name",
"value": "={{ $('Globals').first().json.github_repo.name }}"
},
"fileContent": "={{ JSON.stringify($json.data, null, 2) }}",
"commitMessage": "Update report"
},
"credentials": {
"githubApi": {
"id": "Eb9yCfVJGJvXD05z",
"name": "GitHub (n8n-test-01)"
}
},
"typeVersion": 1
},
{
"id": "b928cdb2-b21a-45ff-9bc6-9be483891c4c",
"name": "Create file in GitHub",
"type": "n8n-nodes-base.github",
"position": [
1100,
500
],
"parameters": {
"owner": {
"__rl": true,
"mode": "name",
"value": "={{ $('Globals').first().json.github_repo.owner }}"
},
"filePath": "=reports/{{ $('Set intervals').item.json.reportName }}",
"resource": "file",
"repository": {
"__rl": true,
"mode": "name",
"value": "={{ $('Globals').first().json.github_repo.name }}"
},
"fileContent": "={{ JSON.stringify($json.timeentries, null, 2) }}",
"commitMessage": "Create report"
},
"credentials": {
"githubApi": {
"id": "Eb9yCfVJGJvXD05z",
"name": "GitHub (n8n-test-01)"
}
},
"typeVersion": 1
},
{
"id": "04a5b42d-ea1f-4b32-98b5-953e22b26819",
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-1100,
480
],
"parameters": {
"rule": {
"interval": [
{
"triggerAtHour": 5
}
]
}
},
"typeVersion": 1.2
},
{
"id": "4728f389-df04-4f8d-a436-ac06508d28ba",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
-720,
260
],
"parameters": {
"width": 220,
"height": 380,
"content": "## Set Globals\n- Define the repository owner (username / organization) and repository name\n- By default the fist available Clockify workspace ID is set. This can be overridden here."
},
"typeVersion": 1
},
{
"id": "2e31df0a-1e67-4a9a-8dc1-42360b4da978",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1160,
360
],
"parameters": {
"width": 220,
"height": 280,
"content": "## Set trigger\nBy default this workflow runs once a day."
},
"typeVersion": 1
},
{
"id": "696721c6-25fc-48f9-b0f5-53d1b6462183",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-500,
300
],
"parameters": {
"width": 220,
"height": 340,
"content": "## Set Scope (optional)\nBy default the last three moths are being backed up.\n_0 = current month, 1 = last month, etc._"
},
"typeVersion": 1
},
{
"id": "a0ebb845-7472-40ec-b2b5-abc2f118b0e1",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
160,
360
],
"parameters": {
"color": 7,
"width": 220,
"height": 280,
"content": "A detailed report is being retrieved for every month across all entries in the workspace."
},
"typeVersion": 1
},
{
"id": "feb9f194-4c9d-41c8-9b46-3759dcdae9d5",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
380,
100
],
"parameters": {
"color": 7,
"width": 920,
"height": 780,
"content": "The reports are created or updated in GitHub.\n**It is essential to back up previous months as well, as values like tags may still change over time.**"
},
"typeVersion": 1
}
],
"active": false,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "34ab93f2-a965-42ac-bd44-478c19a0f7d6",
"connections": {
"Globals": {
"main": [
[
{
"node": "Set month indexes",
"type": "main",
"index": 0
}
]
]
},
"Set intervals": {
"main": [
[
{
"node": "Get detailed monthly report",
"type": "main",
"index": 0
}
]
]
},
"Compare Datasets": {
"main": [
[
{
"node": "Update file in GitHub",
"type": "main",
"index": 0
}
],
[],
[]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "Get first workspace",
"type": "main",
"index": 0
}
]
]
},
"Extract from File": {
"main": [
[
{
"node": "Compare Datasets",
"type": "main",
"index": 1
}
]
]
},
"Point to new data": {
"main": [
[
{
"node": "Compare Datasets",
"type": "main",
"index": 0
}
]
]
},
"Set month indexes": {
"main": [
[
{
"node": "Split Out indexes",
"type": "main",
"index": 0
}
]
]
},
"Split Out indexes": {
"main": [
[
{
"node": "Set intervals",
"type": "main",
"index": 0
}
]
]
},
"Skip empty reports": {
"main": [
[
{
"node": "Create file in GitHub",
"type": "main",
"index": 0
}
]
]
},
"Get first workspace": {
"main": [
[
{
"node": "Globals",
"type": "main",
"index": 0
}
]
]
},
"Check for 404 error message": {
"main": [
[
{
"node": "Skip empty reports",
"type": "main",
"index": 0
}
],
[
{
"node": "Stop and Error",
"type": "main",
"index": 0
}
]
]
},
"Get detailed monthly report": {
"main": [
[
{
"node": "Check if file exists in GitHub",
"type": "main",
"index": 0
}
]
]
},
"Check if file exists in GitHub": {
"main": [
[
{
"node": "Point to new data",
"type": "main",
"index": 0
},
{
"node": "Extract from File",
"type": "main",
"index": 0
}
],
[
{
"node": "Check for 404 error message",
"type": "main",
"index": 0
}
]
]
}
}
}Workflow n8n Clockify, GitHub, gestion des rapports : pour qui est ce workflow ?
Ce workflow s'adresse aux équipes de gestion de projet, aux responsables des ressources humaines et aux entreprises qui utilisent Clockify pour le suivi du temps. Il est conçu pour les utilisateurs ayant un niveau technique intermédiaire et souhaitant automatiser leurs processus de reporting.
Workflow n8n Clockify, GitHub, gestion des rapports : problème résolu
Ce workflow résout le problème de la gestion manuelle des rapports de temps, qui peut être chronophage et sujet à des erreurs. En automatisant l'extraction, la comparaison et la sauvegarde des données, les utilisateurs peuvent se concentrer sur des tâches à plus forte valeur ajoutée. Les résultats concrets incluent une réduction des erreurs, un gain de temps significatif et une meilleure visibilité sur les performances des équipes.
Workflow n8n Clockify, GitHub, gestion des rapports : étapes du workflow
Étape 1 : le workflow est déclenché selon un calendrier prédéfini.
- Étape 1 : extraction des données à partir d'un fichier.
- Étape 2 : comparaison des ensembles de données pour identifier les différences.
- Étape 3 : filtrage des rapports vides pour ne conserver que les données pertinentes.
- Étape 4 : envoi des résultats à GitHub pour mise à jour ou création de fichiers.
- Étape 5 : gestion des erreurs potentielles avec un message d'erreur approprié.
Workflow n8n Clockify, GitHub, gestion des rapports : guide de personnalisation
Pour personnaliser ce workflow, vous pouvez modifier l'URL du fichier à extraire, ajuster les critères de comparaison des ensembles de données et définir les paramètres de mise à jour sur GitHub. Il est également possible de changer la fréquence du déclencheur programmé selon vos besoins. Assurez-vous d'avoir les bonnes autorisations pour accéder à GitHub et de tester le workflow pour garantir son bon fonctionnement. Pensez à sécuriser vos données en utilisant des méthodes d'authentification appropriées.