Workflow n8n

Automatisation Google Sheets avec n8n : gestion quotidienne des tickets

Ce workflow n8n a pour objectif d'automatiser la gestion des tickets de votre équipe en les extrayant quotidiennement et en les enregistrant dans Google Sheets. En utilisant cette automatisation n8n, les équipes peuvent gagner un temps précieux en évitant les tâches manuelles répétitives. Le workflow commence par un déclencheur programmé qui s'active chaque jour à 06:00. Ensuite, il interroge l'API GraphQL pour récupérer tous les tickets de l'équipe. Les tickets sont ensuite traités et organisés à l'aide de plusieurs nœuds, notamment des notes autocollantes pour visualiser les informations clés. Un nœud conditionnel vérifie s'il y a une page suivante de tickets à traiter, permettant ainsi une gestion efficace des données. Si des tickets supplémentaires sont disponibles, le workflow les récupère et les traite également. Enfin, les tickets sont écrits dans une feuille Google Sheets, ce qui permet un suivi et une gestion simplifiés. Grâce à cette automatisation, les équipes peuvent se concentrer sur des tâches à plus forte valeur ajoutée, tout en ayant une vue d'ensemble claire de leurs tickets. Tags clés : automatisation, Google Sheets, workflow.

Catégorie: Scheduled · Tags: automatisation, Google Sheets, workflow, tickets, n8n0

Vue d'ensemble du workflow n8n

Schéma des nœuds et connexions de ce workflow n8n, généré à partir du JSON n8n.

Détail des nœuds du workflow n8n

  • Every day at 06:00

    Déclenche le workflow tous les jours à 06:00.

  • Get all your team's tickets

    Récupère tous les tickets de l'équipe via une requête GraphQL.

  • Sticky Note1

    Crée une note autocollante avec des paramètres de couleur, taille et contenu.

  • if has next page

    Évalue une condition pour déterminer si une page suivante est disponible.

  • Get end cursor

    Récupère le curseur de fin pour la pagination.

  • Get next page

    Récupère la page suivante de tickets via une requête GraphQL.

  • Sticky Note

    Crée une note autocollante avec des paramètres de couleur, taille et contenu.

  • Split out the tickets

    Sépare les tickets en fonction d'un champ spécifié.

  • Sticky Note2

    Crée une note autocollante avec des paramètres de couleur, taille et contenu.

  • Set custom fields

    Définit des champs personnalisés avec des options spécifiées.

  • Sticky Note3

    Crée une note autocollante avec des paramètres de couleur, taille et contenu.

  • Sticky Note4

    Crée une note autocollante avec des paramètres de couleur, taille et contenu.

  • Write tickets to Sheets

    Écrit les tickets récupérés dans une feuille Google Sheets.

  • Flatten object to have simple fields to filter by

    Aplatit un objet pour obtenir des champs simples à filtrer.

Inscris-toi pour voir l'intégralité du workflow

Inscription gratuite

S'inscrire gratuitementBesoin d'aide ?
{
  "nodes": [
    {
      "id": "58c69358-3d02-41c3-b50c-6e57452523a2",
      "name": "Every day at 06:00",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        960,
        600
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 9
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "0a388351-6aec-45c4-a142-e89b338be155",
      "name": "Get all your team's tickets",
      "type": "n8n-nodes-base.graphql",
      "position": [
        1200,
        600
      ],
      "parameters": {
        "query": "query ($filter: IssueFilter) {\n  issues(filter: $filter, first: 100) {\n    pageInfo {\n      hasNextPage\n      endCursor\n    }\n    nodes {\n      id\n      identifier\n      url\n      title\n      priorityLabel\n      createdAt\n      completedAt\n      state {\n        type\n        name\n      }\n      cycle {\n        number\n      }\n      estimate\n      labels { nodes { name } }\n    }\n  }\n}",
        "endpoint": "https://api.linear.app/graphql",
        "variables": "={\n  \"filter\": {\n    \"team\": {\n      \"name\":  {\n        \"eq\": \"Adore\"\n      }\n    }\n  }\n}",
        "requestFormat": "json",
        "authentication": "headerAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "id": "QNQL42DMISvQl50S",
          "name": "Linear api "
        }
      },
      "typeVersion": 1
    },
    {
      "id": "91f29056-f934-4c15-8e98-2a202753971d",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1200,
        460
      ],
      "parameters": {
        "color": 7,
        "width": 256.14371825927645,
        "height": 100,
        "content": "👇🏽 Set your team name here in the filter. \n(Our team's name is Adore)"
      },
      "typeVersion": 1
    },
    {
      "id": "8efeb08c-fbba-4c07-9ef8-e22afa39f328",
      "name": "if has next page",
      "type": "n8n-nodes-base.if",
      "position": [
        1400,
        780
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "f5ab21aa-b2e0-4885-9278-6756c2c544f9",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.data.issues.pageInfo.hasNextPage }}",
              "rightValue": 0
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "fdfba048-ae14-45fb-88be-e354d7003fdb",
      "name": "Get end cursor",
      "type": "n8n-nodes-base.set",
      "position": [
        1620,
        920
      ],
      "parameters": {
        "fields": {
          "values": [
            {
              "name": "after",
              "stringValue": "={{ $json.data.issues.pageInfo.endCursor }}"
            }
          ]
        },
        "include": "none",
        "options": {}
      },
      "typeVersion": 3.2
    },
    {
      "id": "db37b327-d939-4a8b-bd5c-ff99c2191a54",
      "name": "Get next page",
      "type": "n8n-nodes-base.graphql",
      "position": [
        1880,
        920
      ],
      "parameters": {
        "query": "=query ($filter: IssueFilter) {\n  issues(filter: $filter, first: 100, after: \"{{ $json.after }}\") {\n    nodes {\n      id\n      identifier\n      url\n      title\n      priorityLabel\n      createdAt\n      completedAt\n      state {\n        type\n        name\n      }\n      cycle {\n        number\n      }\n      estimate\n      labels { nodes { name } }\n    }\n    pageInfo {\n      hasNextPage\n      endCursor\n    }\n  }\n}",
        "endpoint": "https://api.linear.app/graphql",
        "variables": "={\n  \"filter\": {\n    \"team\": {\n      \"name\":  {\n        \"eq\": \"Adore\"\n      }\n    }\n  }\n}",
        "requestFormat": "json",
        "authentication": "headerAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "id": "QNQL42DMISvQl50S",
          "name": "Linear api "
        }
      },
      "typeVersion": 1
    },
    {
      "id": "f7857473-966e-433e-a7d7-9c4e4bdb670a",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2060,
        940
      ],
      "parameters": {
        "color": 7,
        "width": 256.14371825927645,
        "height": 100,
        "content": "👈🏽 Set your team name here in the filter. \n(Our team's name is Adore)"
      },
      "typeVersion": 1
    },
    {
      "id": "75365be8-d111-4bc8-9da8-77e8d3a1de6c",
      "name": "Split out the tickets",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        2020,
        600
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "data.issues.nodes"
      },
      "typeVersion": 1
    },
    {
      "id": "691a8299-9c96-4520-a56b-7edf3bee42b5",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2240,
        460
      ],
      "parameters": {
        "color": 7,
        "width": 256.14371825927645,
        "height": 100,
        "content": "👇🏽 Adjust any custom fields. Here we set labels and default estimate of 1"
      },
      "typeVersion": 1
    },
    {
      "id": "4ff13ada-6534-4171-8704-4917b247727d",
      "name": "Set custom fields",
      "type": "n8n-nodes-base.set",
      "position": [
        2240,
        600
      ],
      "parameters": {
        "fields": {
          "values": [
            {
              "name": "estimate",
              "type": "numberValue",
              "numberValue": "={{ $json.estimate ?? 1 }}"
            },
            {
              "name": "labels",
              "stringValue": "={{ $json.labels.nodes.map((label) => label.name).toString() }}"
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3.2
    },
    {
      "id": "02577d21-656e-425b-9924-37a34c822fe8",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        740,
        300
      ],
      "parameters": {
        "color": 5,
        "width": 403.45318928152614,
        "height": 280.9004675550071,
        "content": "### 👨‍🎤 Setup\n1. Add Linear API header key\n2. Add Google sheets creds\n3. Update which teams to get tickets from in Graphql Nodes\n4. Update which Google Sheets page to write all the tickets to. \n **You only need to add one column, id. Google Sheets node in automatic mapping mode will handle adding the rest of the columns.**\n5. Set any custom data on each ticket\n6. Activate workflow 🚀"
      },
      "typeVersion": 1
    },
    {
      "id": "6344a764-20f0-4f46-bdc8-1599c2f9ba95",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2700,
        780
      ],
      "parameters": {
        "color": 7,
        "width": 256.14371825927645,
        "height": 100,
        "content": "👆🏽 Update which Google sheet to write to"
      },
      "typeVersion": 1
    },
    {
      "id": "ba08e0c7-1607-4bcd-8b37-99a6145b0cba",
      "name": "Write tickets to Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2720,
        600
      ],
      "parameters": {
        "columns": {
          "value": {},
          "schema": [
            {
              "id": "id",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "id",
              "defaultMatch": true,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "autoMapInputData",
          "matchingColumns": [
            "id"
          ]
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 2072772685,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1pQxSIZ2dSoA8Fmr3B4EId9VOQXH1hVuOZgCHxcaKN7k/edit#gid=2072772685",
          "cachedResultName": "Sheet2"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1pQxSIZ2dSoA8Fmr3B4EId9VOQXH1hVuOZgCHxcaKN7k",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1pQxSIZ2dSoA8Fmr3B4EId9VOQXH1hVuOZgCHxcaKN7k/edit?usp=drivesdk",
          "cachedResultName": "Adore tickets"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "xNiEr671wxZVfjs6",
          "name": "Google Sheets account 3"
        }
      },
      "retryOnFail": true,
      "typeVersion": 4.2,
      "waitBetweenTries": 5000
    },
    {
      "id": "df3ae898-1f09-4be3-a96a-f1f9cba58730",
      "name": "Flatten object to have simple fields to filter by",
      "type": "n8n-nodes-base.code",
      "position": [
        2480,
        600
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "function flattenObject(ob) {\n    var toReturn = {};\n\n    for (var i in ob) {\n        if (!ob.hasOwnProperty(i)) continue;\n\n        if ((typeof ob[i]) == 'object' && ob[i] !== null) {\n            var flatObject = flattenObject(ob[i]);\n            for (var x in flatObject) {\n                if (!flatObject.hasOwnProperty(x)) continue;\n\n                toReturn[i + '.' + x] = flatObject[x];\n            }\n        } else {\n            toReturn[i] = ob[i];\n        }\n    }\n    return toReturn;\n}\n\nreturn flattenObject($input.item.json);"
      },
      "typeVersion": 2
    }
  ],
  "pinData": {},
  "connections": {
    "Get next page": {
      "main": [
        [
          {
            "node": "if has next page",
            "type": "main",
            "index": 0
          },
          {
            "node": "Split out the tickets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get end cursor": {
      "main": [
        [
          {
            "node": "Get next page",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "if has next page": {
      "main": [
        [
          {
            "node": "Get end cursor",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set custom fields": {
      "main": [
        [
          {
            "node": "Flatten object to have simple fields to filter by",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Every day at 06:00": {
      "main": [
        [
          {
            "node": "Get all your team's tickets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split out the tickets": {
      "main": [
        [
          {
            "node": "Set custom fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get all your team's tickets": {
      "main": [
        [
          {
            "node": "Split out the tickets",
            "type": "main",
            "index": 0
          },
          {
            "node": "if has next page",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Flatten object to have simple fields to filter by": {
      "main": [
        [
          {
            "node": "Write tickets to Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Pour qui est ce workflow ?

Ce workflow s'adresse aux équipes de support et de gestion de projet qui utilisent des tickets pour suivre les demandes et les tâches. Il est idéal pour les entreprises de taille moyenne à grande qui cherchent à automatiser leur processus de gestion des tickets tout en utilisant Google Sheets pour le reporting.

Problème résolu

Ce workflow résout le problème de la gestion manuelle des tickets, qui peut être chronophage et sujette à des erreurs. En automatisant la récupération et l'enregistrement des tickets, les utilisateurs éliminent les frustrations liées à la saisie manuelle et réduisent les risques d'oubli ou de perte d'informations. À la suite de la mise en place de ce workflow, les utilisateurs bénéficient d'une gestion des tickets plus fluide et d'une meilleure visibilité sur les tâches en cours.

Étapes du workflow

Étape 1 : Le workflow est déclenché chaque jour à 06:00. Étape 2 : Il interroge l'API GraphQL pour récupérer tous les tickets de l'équipe. Étape 3 : Les tickets sont traités et organisés, avec des notes autocollantes pour visualiser les informations importantes. Étape 4 : Une condition vérifie s'il y a une page suivante de tickets à traiter. Étape 5 : Si des tickets supplémentaires sont disponibles, ils sont récupérés et traités. Étape 6 : Tous les tickets sont ensuite écrits dans une feuille Google Sheets pour un suivi facile.

Guide de personnalisation du workflow n8n

Pour personnaliser ce workflow, vous pouvez ajuster l'heure de déclenchement dans le nœud de planification. Modifiez également la requête GraphQL pour cibler des tickets spécifiques selon vos besoins. Si vous souhaitez changer la feuille Google Sheets utilisée, mettez à jour l'ID du document et le nom de la feuille dans le nœud correspondant. Vous pouvez également ajouter d'autres nœuds pour intégrer des outils supplémentaires ou pour enrichir les données avant de les envoyer à Google Sheets. Assurez-vous que les autorisations d'accès à l'API sont correctement configurées pour éviter tout problème de connexion.