{ "name": "Resumo Semanal GLPI - SQL Slack", "nodes": [ { "parameters": {}, "id": "manual-trigger-sql", "name": "Manual Trigger", "type": "n8n-nodes-base.manualTrigger", "typeVersion": 1, "position": [ 180, 300 ] }, { "parameters": { "assignments": { "assignments": [ { "id": "slack-webhook-url", "name": "slack_webhook_url", "type": "string", "value": "https://hooks.slack.com/services/SEU/WEBHOOK/AQUI" }, { "id": "openai-api-key", "name": "openai_api_key", "type": "string", "value": "COLE_SUA_OPENAI_API_KEY_AQUI" }, { "id": "openai-model", "name": "openai_model", "type": "string", "value": "gpt-5.5" } ] }, "options": {} }, "id": "config-sql-slack", "name": "Config - Slack e OpenAI", "type": "n8n-nodes-base.set", "typeVersion": 3.4, "position": [ 420, 300 ] }, { "parameters": { "operation": "executeQuery", "query": "SELECT\n CONCAT(SUBSTR(DATE_FORMAT(NOW(), '%x%v'), 1, 4), '/', SUBSTR(DATE_FORMAT(NOW(), '%x%v'), 5, 2)) AS anomes,\n COALESCE(fechados_por_semana.fechados, 0) - COALESCE(abertos_por_semana.abertos, 0) AS saldo,\n COALESCE(abertos_por_semana.abertos, 0) AS abertos,\n COALESCE(fechados_por_semana.fechados, 0) AS fechados\nFROM (\n SELECT COUNT(*) AS abertos\n FROM glpi_tickets\n WHERE is_deleted = false\n AND DATE_FORMAT(date, '%x%v') = DATE_FORMAT(NOW(), '%x%v')\n AND itilcategories_id IN (\n SELECT id\n FROM glpi_itilcategories\n WHERE JSON_CONTAINS(ancestors_cache, '{\"7\":7}', '$') OR id = 7\n OR JSON_CONTAINS(ancestors_cache, '{\"16\":16}', '$') OR id = 16\n OR JSON_CONTAINS(ancestors_cache, '{\"17\":17}', '$') OR id = 17\n OR JSON_CONTAINS(ancestors_cache, '{\"18\":18}', '$') OR id = 18\n )\n) AS abertos_por_semana\nCROSS JOIN (\n SELECT COUNT(*) AS fechados\n FROM glpi_tickets\n WHERE closedate IS NOT NULL\n AND is_deleted = false\n AND DATE_FORMAT(closedate, '%x%v') = DATE_FORMAT(NOW(), '%x%v')\n AND itilcategories_id IN (\n SELECT id\n FROM glpi_itilcategories\n WHERE JSON_CONTAINS(ancestors_cache, '{\"7\":7}', '$') OR id = 7\n OR JSON_CONTAINS(ancestors_cache, '{\"16\":16}', '$') OR id = 16\n OR JSON_CONTAINS(ancestors_cache, '{\"17\":17}', '$') OR id = 17\n OR JSON_CONTAINS(ancestors_cache, '{\"18\":18}', '$') OR id = 18\n )\n) AS fechados_por_semana;", "options": {} }, "id": "mysql-indicadores-semana", "name": "MySQL - Indicadores semana GLPI", "type": "n8n-nodes-base.mySql", "typeVersion": 2.4, "position": [ 680, 300 ], "credentials": { "mySql": { "id": "", "name": "MySQL GLPI" } } }, { "parameters": { "jsCode": "const row = $input.first().json;\n\nconst textoBase = [\n '*Resumo semanal do suporte GLPI*',\n '',\n `Semana: ${row.anomes}`,\n '',\n '*Indicadores*',\n `- Chamados abertos na semana: ${row.abertos}`,\n `- Chamados fechados na semana: ${row.fechados}`,\n `- Saldo fechados - abertos: ${row.saldo}`,\n '',\n '*Observação*',\n '- Chamados fechados podem ter sido abertos em semanas anteriores.',\n '- Os números seguem o filtro de categorias da query SQL: árvores 7, 16, 17 e 18.'\n].join('\\n');\n\nreturn [{ json: { ...row, texto_base: textoBase } }];" }, "id": "code-preparar-indicadores", "name": "Code - Preparar indicadores", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 940, 300 ] }, { "parameters": { "method": "POST", "url": "https://api.openai.com/v1/chat/completions", "sendHeaders": true, "headerParameters": { "parameters": [ { "name": "Content-Type", "value": "application/json" }, { "name": "Authorization", "value": "={{ 'Bearer ' + $('Config - Slack e OpenAI').first().json.openai_api_key }}" } ] }, "sendBody": true, "contentType": "json", "specifyBody": "json", "jsonBody": "={{ { model: $('Config - Slack e OpenAI').first().json.openai_model || 'gpt-5.5', temperature: 0.2, max_tokens: 500, messages: [ { role: 'system', content: 'Você é um analista de suporte. Gere um resumo executivo curto em português do Brasil para Slack. Use somente os números fornecidos.' }, { role: 'user', content: 'Dados da semana GLPI:\\n' + JSON.stringify($json) + '\\n\\nExplique que fechados podem ter sido abertos em semanas anteriores. Seja objetivo.' } ] } }}", "options": {} }, "id": "openai-resumo-sql", "name": "OpenAI - Gerar resumo", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [ 1200, 300 ], "continueOnFail": true, "retryOnFail": true, "maxTries": 3, "waitBetweenTries": 30000 }, { "parameters": { "jsCode": "const data = $input.first().json;\nconst textoIa = data.choices?.[0]?.message?.content;\nconst fallback = $('Code - Preparar indicadores').first().json.texto_base;\n\nreturn [{ json: { text: textoIa || fallback } }];" }, "id": "code-preparar-slack-sql", "name": "Code - Preparar mensagem Slack", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 1460, 300 ] }, { "parameters": { "method": "POST", "url": "={{ $('Config - Slack e OpenAI').first().json.slack_webhook_url }}", "sendBody": true, "contentType": "json", "specifyBody": "keypair", "bodyParameters": { "parameters": [ { "name": "text", "value": "={{ $json.text }}" } ] }, "options": {} }, "id": "http-slack-sql", "name": "HTTP - Slack enviar mensagem", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [ 1720, 300 ] } ], "pinData": {}, "connections": { "Manual Trigger": { "main": [[{"node": "Config - Slack e OpenAI", "type": "main", "index": 0}]] }, "Config - Slack e OpenAI": { "main": [[{"node": "MySQL - Indicadores semana GLPI", "type": "main", "index": 0}]] }, "MySQL - Indicadores semana GLPI": { "main": [[{"node": "Code - Preparar indicadores", "type": "main", "index": 0}]] }, "Code - Preparar indicadores": { "main": [[{"node": "OpenAI - Gerar resumo", "type": "main", "index": 0}]] }, "OpenAI - Gerar resumo": { "main": [[{"node": "Code - Preparar mensagem Slack", "type": "main", "index": 0}]] }, "Code - Preparar mensagem Slack": { "main": [[{"node": "HTTP - Slack enviar mensagem", "type": "main", "index": 0}]] } }, "active": false, "settings": { "executionOrder": "v1" }, "versionId": "", "meta": { "templateCredsSetupCompleted": false }, "tags": [] }