SHEETS_WRITE - Escrever Dados no Google Sheets
O que é este Node?
O SHEETS_WRITE é o node responsável por escrever ou substituir dados em células específicas do Google Sheets com autenticação OAuth2. Atualiza valores em um range definido, sobrescrevendo o conteúdo existente.
Por que este Node existe?
Muitas automações precisam atualizar planilhas com novos dados ou modificar informações existentes. O SHEETS_WRITE existe para:
- Atualização de Registros: Modificar dados de clientes, produtos ou vendas em tempo real
- Sincronização de Dados: Manter planilhas atualizadas com informações de outros sistemas
- Registro de Operações: Gravar resultados de processos automatizados
- Controle de Status: Atualizar campos como "Status do Pedido", "Data de Processamento"
Como funciona internamente?
Quando o SHEETS_WRITE é executado, o sistema:
- Valida autenticação: Verifica tokens OAuth2 válidos
- Conecta ao Google Sheets API: Autentica com OAuth2Client
- Identifica o destino: Extrai spreadsheetId e valida o range
- Prepara os dados: Converte values em formato array de arrays
- Executa escrita: Chama spreadsheets.values.update() com valueInputOption='USER_ENTERED'
- Retorna resultado: Informa quantas células/linhas foram atualizadas
- Se erro: Lança exceção com detalhes do problema
Código interno (google-executors.service.ts:768-782):
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,
};
Quando você DEVE usar este Node?
Use SHEETS_WRITE sempre que precisar atualizar ou substituir dados em células específicas:
Casos de uso
- Atualizar Status: "Marcar pedido como 'Enviado' na planilha de vendas"
- Registrar Atendimento: "Gravar data/hora do último contato com cliente"
- Sincronizar Estoque: "Atualizar quantidade disponível após venda"
- Dashboard Manual: "Escrever KPIs calculados em células específicas para visualização"
- Controle de Qualidade: "Atualizar campo 'Revisado' após verificação"
Quando NÃO usar SHEETS_WRITE
- Adicionar novas linhas: Use NODE SHEETS_APPEND para inserir ao final
- Limpar dados: Use NODE SHEETS_CLEAR para apagar conteúdo
- Múltiplas operações: Use NODE SHEETS_BATCH_UPDATE para eficiência
Parâmetros Detalhados
spreadsheetId (string, obrigatório)
O que é: ID único da planilha Google Sheets a ser modificada.
Como obter: Extraia da URL: https://docs.google.com/spreadsheets/d/SPREADSHEET_ID/edit
Flow completo para testar:
{
"name": "Teste Sheets Write - SpreadsheetId",
"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": "Escrever Dados",
"parameters": {
"operation": "write",
"spreadsheetId": "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms",
"range": "Sheet1!A1",
"values": [["Hello", "World"]],
"accessToken": "{{google_access_token}}",
"refreshToken": "{{google_refresh_token}}"
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Confirmar",
"parameters": {
"message": "✅ Atualizado {{sheets_1.updatedCells}} células"
}
}
},
{
"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" }
]
}
Teste: Configure os tokens OAuth2. O sistema deve escrever "Hello" em A1 e "World" em B1.
range (string, opcional)
O que é: Range inicial onde começar a escrita em notação A1. Define o ponto de partida.
Padrão: "Sheet1!A1"
Comportamento: Os dados em values são escritos a partir deste ponto, expandindo para direita e para baixo conforme necessário.
Exemplos:
- A1 - Escreve a partir da célula A1
- Vendas!D5 - Escreve a partir de D5 na aba Vendas
- B2:D4 - Escreve no range B2 até D4 (deve corresponder ao tamanho de values)
Flow completo para testar:
{
"name": "Teste Sheets Write - Range",
"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": "Escrever em B2",
"parameters": {
"operation": "write",
"spreadsheetId": "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms",
"range": "Sheet1!B2",
"values": [
["Produto", "Preço"],
["Notebook", "2500"],
["Mouse", "50"]
],
"accessToken": "{{google_access_token}}",
"refreshToken": "{{google_refresh_token}}"
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Resultado",
"parameters": {
"message": "Escritas {{sheets_1.updatedRows}} linhas a partir de B2"
}
}
},
{
"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" }
]
}
Teste: O sistema deve escrever a tabela começando em B2 (ocupará B2:C4).
values (array, obrigatório)
O que é: Array de arrays contendo os dados a serem escritos. Cada sub-array representa uma linha.
Formato:
[
["Célula A1", "Célula B1", "Célula C1"], // Linha 1
["Célula A2", "Célula B2", "Célula C2"], // Linha 2
["Célula A3", "Célula B3", "Célula C3"] // Linha 3
]
Tipos suportados: Strings, números, booleanos, fórmulas (começando com =)
Flow completo para testar:
{
"name": "Teste Sheets Write - Values",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "variable_1",
"type": "variable",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Preparar Dados",
"parameters": {
"variableName": "dados_tabela",
"value": [
["Nome", "Email", "Status"],
["José", "jose@email.com", "Ativo"],
["Maria", "maria@email.com", "Ativo"]
]
}
}
},
{
"id": "sheets_1",
"type": "google_sheets",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Escrever Tabela",
"parameters": {
"operation": "write",
"spreadsheetId": "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms",
"range": "Clientes!A1",
"values": "{{dados_tabela}}",
"accessToken": "{{google_access_token}}",
"refreshToken": "{{google_refresh_token}}"
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Confirmar",
"parameters": {
"message": "✅ Tabela escrita: {{sheets_1.updatedRows}} linhas, {{sheets_1.updatedCells}} células"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 900, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "variable_1" },
{ "source": "variable_1", "target": "sheets_1" },
{ "source": "sheets_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
Teste: O sistema deve escrever 3 linhas com 3 colunas cada, totalizando 9 células.
accessToken (string, obrigatório)
O que é: Token de acesso OAuth2 do Google para autenticação da operação de escrita.
Permissões necessárias: Escopo https://www.googleapis.com/auth/spreadsheets
Flow completo para testar:
{
"name": "Teste Sheets Write - AccessToken",
"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": "Escrever Timestamp",
"parameters": {
"operation": "write",
"spreadsheetId": "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms",
"range": "Log!A1",
"values": [["Última atualização:", "2025-01-15 10:30:00"]],
"accessToken": "{{google_access_token}}",
"refreshToken": "{{google_refresh_token}}"
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Confirmar",
"parameters": {
"message": "Timestamp registrado com sucesso!"
}
}
},
{
"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" }
]
}
Teste: Com token válido, o sistema deve gravar a data/hora na célula especificada.
refreshToken (string, obrigatório)
O que é: Token OAuth2 de longa duração para renovar accessToken quando expirar.
Validade: Geralmente válido indefinidamente (até revogação manual)
Flow completo para testar:
{
"name": "Teste Sheets Write - RefreshToken",
"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": "Atualizar Status",
"parameters": {
"operation": "write",
"spreadsheetId": "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms",
"range": "Status!A1",
"values": [["Sistema", "Operacional"]],
"accessToken": "{{google_access_token}}",
"refreshToken": "{{google_refresh_token}}"
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Confirmar",
"parameters": {
"message": "Status atualizado"
}
}
},
{
"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" }
]
}
Teste: O refreshToken garante operação contínua mesmo com accessToken expirado.
Parâmetros
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| operation | string | Sim | Deve ser "write" para escrita |
| spreadsheetId | string | Sim | ID da planilha Google Sheets |
| range | string | Não | Range inicial em notação A1 (padrão: Sheet1!A1) |
| values | array | Sim | Array de arrays com dados a escrever |
| accessToken | string | Sim | Token OAuth2 de acesso |
| refreshToken | string | Sim | Token OAuth2 de atualização |
Exemplo 1: Atualizar Status de Pedido
Objetivo: Marcar pedido como processado na planilha de controle
JSON para Importar
{
"name": "E-commerce - Atualizar Status Pedido",
"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": {
"prompt": "Digite o número do pedido:",
"variableName": "numero_pedido"
}
}
},
{
"id": "variable_1",
"type": "variable",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Preparar Atualização",
"parameters": {
"variableName": "dados_atualizacao",
"value": [
["Processado", "2025-01-15", "Sistema Automático"]
]
}
}
},
{
"id": "sheets_1",
"type": "google_sheets",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Gravar Status",
"parameters": {
"operation": "write",
"spreadsheetId": "1ABC_Pedidos_XYZ",
"range": "Pedidos!D{{numero_pedido}}",
"values": "{{dados_atualizacao}}",
"accessToken": "{{google_access_token}}",
"refreshToken": "{{google_refresh_token}}"
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 900, "y": 100 },
"data": {
"label": "Confirmar",
"parameters": {
"message": "✅ Pedido {{numero_pedido}} atualizado para 'Processado'"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 1100, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "input_1" },
{ "source": "input_1", "target": "variable_1" },
{ "source": "variable_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: 1234
Sistema: ✅ Pedido 1234 atualizado para 'Processado'
Exemplo 2: Registrar Atendimento de Cliente
Objetivo: Gravar data/hora e notas do atendimento na planilha CRM
JSON para Importar
{
"name": "CRM - Registrar Atendimento",
"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 Cliente",
"parameters": {
"prompt": "Nome do cliente:",
"variableName": "nome_cliente"
}
}
},
{
"id": "input_2",
"type": "input",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Notas",
"parameters": {
"prompt": "Resumo do atendimento:",
"variableName": "notas"
}
}
},
{
"id": "variable_1",
"type": "variable",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Timestamp",
"parameters": {
"variableName": "data_hora",
"value": "{{NOW}}"
}
}
},
{
"id": "sheets_1",
"type": "google_sheets",
"position": { "x": 900, "y": 100 },
"data": {
"label": "Gravar Atendimento",
"parameters": {
"operation": "write",
"spreadsheetId": "1CRM_Database_XYZ",
"range": "Atendimentos!A2",
"values": [
["{{data_hora}}", "{{nome_cliente}}", "{{notas}}", "WhatsApp"]
],
"accessToken": "{{google_access_token}}",
"refreshToken": "{{google_refresh_token}}"
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 1100, "y": 100 },
"data": {
"label": "Confirmar",
"parameters": {
"message": "✅ Atendimento de {{nome_cliente}} registrado com sucesso!"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 1300, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "input_1" },
{ "source": "input_1", "target": "input_2" },
{ "source": "input_2", "target": "variable_1" },
{ "source": "variable_1", "target": "sheets_1" },
{ "source": "sheets_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
Saída esperada:
Sistema: Nome do cliente:
Usuário: José Silva
Sistema: Resumo do atendimento:
Usuário: Cliente solicitou orçamento de 10 unidades
Sistema: ✅ Atendimento de José Silva registrado com sucesso!
Exemplo 3: Atualizar Dashboard de KPIs
Objetivo: Escrever métricas calculadas em células específicas de dashboard
JSON para Importar
{
"name": "Dashboard - Atualizar KPIs",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "variable_1",
"type": "variable",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Calcular Métricas",
"parameters": {
"variableName": "kpis",
"value": [
["Vendas Hoje", "45", "Meta: 50"],
["Clientes Ativos", "320", "+15 hoje"],
["Taxa Conversão", "23%", "+2%"]
]
}
}
},
{
"id": "sheets_1",
"type": "google_sheets",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Atualizar Dashboard",
"parameters": {
"operation": "write",
"spreadsheetId": "1Dashboard_KPI_XYZ",
"range": "Dashboard!B2:D4",
"values": "{{kpis}}",
"accessToken": "{{google_access_token}}",
"refreshToken": "{{google_refresh_token}}"
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Confirmar",
"parameters": {
"message": "📊 Dashboard atualizado! {{sheets_1.updatedCells}} células modificadas"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 900, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "variable_1" },
{ "source": "variable_1", "target": "sheets_1" },
{ "source": "sheets_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
Saída esperada:
Sistema: 📊 Dashboard atualizado! 9 células modificadas
Resposta do Node
{
"success": true,
"updatedCells": 6,
"updatedRows": 2
}
Boas Práticas
✅ SIM:
- Use valueInputOption='USER_ENTERED' para que fórmulas sejam interpretadas
- Valide estrutura de dados antes de escrever (arrays consistentes)
- Use range específico que corresponda ao tamanho dos dados
- Faça backup antes de operações de escrita em massa
- Verifique permissões de edição na planilha antes
- Use fórmulas começando com = para cálculos automáticos
❌ NÃO:
- Não escreva em ranges muito grandes desnecessariamente
- Não sobrescreva dados sem confirmar primeiro
- Não esqueça que write SUBSTITUI conteúdo existente
- Não misture tipos de dados inconsistentes nas colunas
- Não use write quando deveria usar append (adicionar ao final)
- Não exponha tokens em logs ou mensagens
Dicas
💡 Dica 1 - ValueInputOption: O sistema usa 'USER_ENTERED', o que significa: - Números são interpretados como números, não strings - Fórmulas começando com = são calculadas - Datas são reconhecidas automaticamente - Strings permanecem como texto
💡 Dica 2 - Write vs Append: - WRITE: Substitui dados em posição específica - APPEND: Adiciona ao final da tabela existente - Use write quando souber a posição exata - Use append para novos registros em sequência
💡 Dica 3 - Fórmulas: Você pode escrever fórmulas:
values: [
["Item", "Preço", "IVA", "Total"],
["Produto A", 100, 0.23, "=B2*C2"],
["Produto B", 200, 0.23, "=B3*C3"]
]
💡 Dica 4 - Performance: - Uma operação write com múltiplas linhas é mais eficiente que várias operações separadas - Agrupe atualizações quando possível - Para múltiplas áreas, considere SHEETS_BATCH_UPDATE
💡 Dica 5 - Permissões: A conta Google precisa ter permissão de "Editor" ou superior na planilha. "Visualizar" não é suficiente para write.
Próximo Node
→ SHEETS_APPEND - Adicionar linhas ao final → SHEETS_UPDATE - Atualizar células específicas → SHEETS_CLEAR - Limpar conteúdo