Pular para conteúdo

GOOGLE SHEETS - Planilhas do Google

O que é este Node?

O GOOGLE SHEETS é o node responsável por integrar com o Google Planilhas permitindo ler, escrever, adicionar e limpar dados em planilhas do Google de forma programática.

Por que este Node existe?

Automatizar planilhas é essencial para produtividade. O GOOGLE SHEETS existe para:

  1. Centralizar dados: Armazenar informações coletadas em flows no Google Sheets
  2. Leitura de dados: Buscar informações de planilhas para usar em automações
  3. Relatórios automáticos: Gerar e atualizar relatórios sem intervenção manual
  4. Sincronização: Manter dados sincronizados entre WhatsApp e planilhas
  5. Colaboração: Permitir que equipes acessem dados atualizados em tempo real

Como funciona internamente?

Quando o GOOGLE SHEETS é executado, o sistema:

  1. Autentica usando OAuth2 com Google (access_token e refresh_token)
  2. Identifica a operação (read, write, append, clear)
  3. Conecta à API do Google Sheets v4
  4. Executa a operação especificada
  5. Retorna resultado com dados ou confirmação
  6. Se erro: Loga e lança exceção com detalhes

Código interno (productivity-executors.service.ts:18-94):

async executeGoogleSheets(data: any, variables: Record<string, any>): Promise<any> {
  try {
    this.logger.log('📊 [GOOGLE SHEETS] Executing operation');

    const oauth2Client = new OAuth2Client(
      process.env.GOOGLE_CLIENT_ID,
      process.env.GOOGLE_CLIENT_SECRET,
      process.env.GOOGLE_REDIRECT_URI
    );

    oauth2Client.setCredentials({
      access_token: data.accessToken,
      refresh_token: data.refreshToken,
    });

    const sheets = google.sheets({ version: 'v4', auth: oauth2Client });

    switch (data.operation) {
      case 'read':
        const readResult = await sheets.spreadsheets.values.get({
          spreadsheetId: data.spreadsheetId,
          range: data.range || 'Sheet1!A1:Z1000',
        });
        return {
          success: true,
          data: readResult.data.values,
          rowCount: readResult.data.values?.length || 0,
        };

      case 'write':
        const writeResult = await sheets.spreadsheets.values.update({
          spreadsheetId: data.spreadsheetId,
          range: data.range || 'Sheet1!A1',
          valueInputOption: 'USER_ENTERED',
          requestBody: {
            values: data.values,
          },
        });
        return {
          success: true,
          updatedCells: writeResult.data.updatedCells,
          updatedRows: writeResult.data.updatedRows,
        };

      case 'append':
        const appendResult = await sheets.spreadsheets.values.append({
          spreadsheetId: data.spreadsheetId,
          range: data.range || 'Sheet1!A1',
          valueInputOption: 'USER_ENTERED',
          requestBody: {
            values: data.values,
          },
        });
        return {
          success: true,
          updatedCells: appendResult.data.updates?.updatedCells,
          updatedRows: appendResult.data.updates?.updatedRows,
        };

      case 'clear':
        await sheets.spreadsheets.values.clear({
          spreadsheetId: data.spreadsheetId,
          range: data.range || 'Sheet1!A1:Z1000',
        });
        return {
          success: true,
          message: 'Range cleared successfully',
        };

      default:
        throw new Error(`Unknown Google Sheets operation: ${data.operation}`);
    }
  } catch (error) {
    this.logger.error('Google Sheets execution error:', error);
    throw error;
  }
}

Quando você DEVE usar este Node?

Use GOOGLE SHEETS quando precisar integrar planilhas com seus flows:

Casos de uso:

  1. Cadastro em planilha: Salvar dados de formulários em planilha
  2. Leitura de configurações: Buscar parâmetros armazenados em planilha
  3. Relatório de atendimentos: Registrar cada conversa automaticamente
  4. Lista de produtos: Consultar catálogo armazenado em planilha
  5. Dashboard de métricas: Alimentar planilha com dados para análise
  6. Sincronização de estoque: Atualizar disponibilidade de produtos

Quando NÃO usar GOOGLE SHEETS:

  • Dados sensíveis: Use banco de dados com criptografia
  • Alto volume: Planilhas têm limites de performance
  • Processamento complexo: Use CALCULATOR antes

Parâmetros Detalhados

operation (string, obrigatório)

O que é: Define qual operação será executada na planilha.

Valores possíveis: - read: Ler dados de um range - write: Sobrescrever dados em um range - append: Adicionar dados ao final - clear: Limpar um range

spreadsheetId (string, obrigatório)

O que é: ID único da planilha do Google Sheets.

Como obter: Na URL da planilha: https://docs.google.com/spreadsheets/d/[SPREADSHEET_ID]/edit

Flow completo para testar:

{
  "name": "Teste GOOGLE SHEETS - Ler Planilha",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "sheets_1",
      "type": "google_sheets",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Ler Planilha",
        "parameters": {
          "operation": "read",
          "spreadsheetId": "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms",
          "range": "Sheet1!A1:C10",
          "accessToken": "{{google_access_token}}",
          "refreshToken": "{{google_refresh_token}}"
        }
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Mostrar Dados",
        "parameters": {
          "message": "📊 Dados lidos: {{sheets_1.rowCount}} linhas"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 700, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "sheets_1" },
    { "source": "sheets_1", "target": "message_1" },
    { "source": "message_1", "target": "end_1" }
  ]
}

range (string, opcional)

O que é: Range de células no formato A1 notation (ex: "Sheet1!A1:C10").

Padrão: "Sheet1!A1:Z1000"

Flow completo para testar:

{
  "name": "Teste GOOGLE SHEETS - Range Específico",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "sheets_1",
      "type": "google_sheets",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Ler Apenas Cabeçalhos",
        "parameters": {
          "operation": "read",
          "spreadsheetId": "{{planilha_id}}",
          "range": "Sheet1!A1:E1",
          "accessToken": "{{google_access_token}}",
          "refreshToken": "{{google_refresh_token}}"
        }
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Mostrar Cabeçalhos",
        "parameters": {
          "message": "Cabeçalhos: {{sheets_1.data}}"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 700, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "sheets_1" },
    { "source": "sheets_1", "target": "message_1" },
    { "source": "message_1", "target": "end_1" }
  ]
}

values (array, requerido para write/append)

O que é: Array bidimensional com os valores a serem escritos.

Formato: [["linha1col1", "linha1col2"], ["linha2col1", "linha2col2"]]

Flow completo para testar:

{
  "name": "Teste GOOGLE SHEETS - Adicionar Dados",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "input_1",
      "type": "input",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Nome",
        "parameters": {
          "message": "Qual seu nome?",
          "variable": "nome"
        }
      }
    },
    {
      "id": "input_2",
      "type": "input",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Email",
        "parameters": {
          "message": "Qual seu email?",
          "variable": "email"
        }
      }
    },
    {
      "id": "sheets_1",
      "type": "google_sheets",
      "position": { "x": 700, "y": 100 },
      "data": {
        "label": "Salvar em Planilha",
        "parameters": {
          "operation": "append",
          "spreadsheetId": "{{planilha_id}}",
          "range": "Sheet1!A1",
          "values": [["{{nome}}", "{{email}}", "{{timestamp}}"]],
          "accessToken": "{{google_access_token}}",
          "refreshToken": "{{google_refresh_token}}"
        }
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 900, "y": 100 },
      "data": {
        "label": "Confirmar",
        "parameters": {
          "message": "✅ Dados salvos na planilha!"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 1100, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "input_1" },
    { "source": "input_1", "target": "input_2" },
    { "source": "input_2", "target": "sheets_1" },
    { "source": "sheets_1", "target": "message_1" },
    { "source": "message_1", "target": "end_1" }
  ]
}

accessToken (string, obrigatório)

O que é: Token de acesso OAuth2 do Google para autenticação.

Como obter: Configure OAuth2 no Google Cloud Console e obtenha através do fluxo de autenticação.

refreshToken (string, obrigatório)

O que é: Token de refresh OAuth2 para renovar o access token automaticamente.

Parâmetros

Campo Tipo Obrigatório Descrição
operation string Sim Operação: read, write, append, clear
spreadsheetId string Sim ID da planilha do Google Sheets
range string Não Range de células (padrão: Sheet1!A1:Z1000)
values array Sim* Dados para write/append (array 2D)
accessToken string Sim Token OAuth2 de acesso
refreshToken string Sim Token OAuth2 de refresh

*Obrigatório apenas para operações write e append

Exemplo 1: Cadastro de Leads em Planilha

Objetivo: Coletar dados de leads e salvar automaticamente em planilha.

JSON para Importar

{
  "name": "Cadastro de Leads - Google Sheets",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Boas-vindas",
        "parameters": {
          "message": "👋 Olá! Vamos fazer seu cadastro."
        }
      }
    },
    {
      "id": "input_1",
      "type": "input",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Nome",
        "parameters": {
          "message": "Qual é o seu nome completo?",
          "variable": "nome"
        }
      }
    },
    {
      "id": "email_1",
      "type": "email",
      "position": { "x": 700, "y": 100 },
      "data": {
        "label": "Email",
        "parameters": {
          "message": "Qual é o seu email?",
          "variable": "email"
        }
      }
    },
    {
      "id": "phone_1",
      "type": "phone",
      "position": { "x": 900, "y": 100 },
      "data": {
        "label": "Telefone",
        "parameters": {
          "message": "Qual é o seu telefone?",
          "variable": "telefone"
        }
      }
    },
    {
      "id": "sheets_1",
      "type": "google_sheets",
      "position": { "x": 1100, "y": 100 },
      "data": {
        "label": "Salvar em Planilha",
        "parameters": {
          "operation": "append",
          "spreadsheetId": "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms",
          "range": "Leads!A1",
          "values": [["{{nome}}", "{{email}}", "{{telefone}}", "{{timestamp}}", "WhatsApp"]],
          "accessToken": "{{google_access_token}}",
          "refreshToken": "{{google_refresh_token}}"
        }
      }
    },
    {
      "id": "message_2",
      "type": "message",
      "position": { "x": 1300, "y": 100 },
      "data": {
        "label": "Confirmação",
        "parameters": {
          "message": "✅ Cadastro realizado com sucesso!\n\n📋 Seus dados:\nNome: {{nome}}\nEmail: {{email}}\nTelefone: {{telefone}}"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 1500, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "message_1" },
    { "source": "message_1", "target": "input_1" },
    { "source": "input_1", "target": "email_1" },
    { "source": "email_1", "target": "phone_1" },
    { "source": "phone_1", "target": "sheets_1" },
    { "source": "sheets_1", "target": "message_2" },
    { "source": "message_2", "target": "end_1" }
  ]
}

Saída esperada:

Sistema: 👋 Olá! Vamos fazer seu cadastro.
Sistema: Qual é o seu nome completo?
Usuário: João Silva
Sistema: Qual é o seu email?
Usuário: joao@email.com
Sistema: Qual é o seu telefone?
Usuário: 11999887766
Sistema: ✅ Cadastro realizado com sucesso!

📋 Seus dados:
Nome: João Silva
Email: joao@email.com
Telefone: 11999887766

Exemplo 2: Consultar Catálogo de Produtos

Objetivo: Ler produtos de uma planilha e apresentar ao usuário.

JSON para Importar

{
  "name": "Catálogo de Produtos - Google Sheets",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "sheets_1",
      "type": "google_sheets",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Buscar Produtos",
        "parameters": {
          "operation": "read",
          "spreadsheetId": "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms",
          "range": "Produtos!A2:D100",
          "accessToken": "{{google_access_token}}",
          "refreshToken": "{{google_refresh_token}}"
        }
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Mostrar Catálogo",
        "parameters": {
          "message": "🛍️ CATÁLOGO DE PRODUTOS\n\nEncontramos {{sheets_1.rowCount}} produtos disponíveis!\n\nDigite o código do produto desejado."
        }
      }
    },
    {
      "id": "input_1",
      "type": "input",
      "position": { "x": 700, "y": 100 },
      "data": {
        "label": "Código",
        "parameters": {
          "message": "Digite o código do produto:",
          "variable": "codigo_produto"
        }
      }
    },
    {
      "id": "message_2",
      "type": "message",
      "position": { "x": 900, "y": 100 },
      "data": {
        "label": "Confirmar",
        "parameters": {
          "message": "✅ Produto selecionado: {{codigo_produto}}"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 1100, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "sheets_1" },
    { "source": "sheets_1", "target": "message_1" },
    { "source": "message_1", "target": "input_1" },
    { "source": "input_1", "target": "message_2" },
    { "source": "message_2", "target": "end_1" }
  ]
}

Saída esperada:

Sistema: 🛍️ CATÁLOGO DE PRODUTOS

Encontramos 15 produtos disponíveis!

Digite o código do produto desejado.
Sistema: Digite o código do produto:
Usuário: PROD001
Sistema: ✅ Produto selecionado: PROD001

Exemplo 3: Atualizar Status em Planilha

Objetivo: Atualizar status de um pedido específico na planilha.

JSON para Importar

{
  "name": "Atualizar Status - Google Sheets",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "input_1",
      "type": "input",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Número do Pedido",
        "parameters": {
          "message": "Digite o número do pedido:",
          "variable": "numero_pedido"
        }
      }
    },
    {
      "id": "sheets_1",
      "type": "google_sheets",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Atualizar Status",
        "parameters": {
          "operation": "write",
          "spreadsheetId": "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms",
          "range": "Pedidos!D2",
          "values": [["Entregue"]],
          "accessToken": "{{google_access_token}}",
          "refreshToken": "{{google_refresh_token}}"
        }
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 700, "y": 100 },
      "data": {
        "label": "Confirmar",
        "parameters": {
          "message": "✅ Status do pedido {{numero_pedido}} atualizado para: ENTREGUE"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 900, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "input_1" },
    { "source": "input_1", "target": "sheets_1" },
    { "source": "sheets_1", "target": "message_1" },
    { "source": "message_1", "target": "end_1" }
  ]
}

Saída esperada:

Sistema: Digite o número do pedido:
Usuário: #12345
Sistema: ✅ Status do pedido #12345 atualizado para: ENTREGUE

Resposta do Node

Operação READ:

{
  "success": true,
  "data": [
    ["Nome", "Email", "Telefone", "Data"],
    ["João Silva", "joao@email.com", "11999887766", "2025-01-15"],
    ["Maria Santos", "maria@email.com", "11988776655", "2025-01-15"]
  ],
  "rowCount": 3
}

Operação WRITE/APPEND:

{
  "success": true,
  "updatedCells": 3,
  "updatedRows": 1
}

Operação CLEAR:

{
  "success": true,
  "message": "Range cleared successfully"
}

Boas Práticas

SIM: - Use append para adicionar novos registros - Use write para atualizar células específicas - Especifique ranges precisos para melhor performance - Use variáveis para armazenar spreadsheetId - Implemente tratamento de erros com RETRY

NÃO: - Não faça operações muito frequentes (respeite rate limits) - Não exponha tokens em logs ou mensagens - Não use ranges muito grandes (limite a 1000 linhas) - Não esqueça de validar dados antes de escrever

Dicas

💡 Range notation: Use formato "Sheet1!A1:C10" para especificar exatamente onde operar

💡 Performance: Operações em lote (múltiplas linhas) são mais eficientes que uma por vez

💡 Autenticação: Configure OAuth2 uma vez e reutilize tokens com refresh automático

💡 Backup: Sempre mantenha backup da planilha antes de operações de clear ou write massivo

💡 Validação: Use nodes de validação (EMAIL, PHONE, NUMBER) antes de salvar em planilha

Próximo Node

GOOGLE DRIVE - Gerenciar arquivos no Google Drive → NOTION - Integração com Notion → TRELLO - Gerenciar cards no Trello