Principal Boas práticas na construção de Eddies Transforme seu Google Sheets em uma API

Transforme seu Google Sheets em uma API

Última atualização em Dec 18, 2025

Essa solução transforma sua planilha do Google Sheets em uma API web dinâmica, permitindo que você (ou seus clientes) leiam, criem, atualizem e deletem dados diretamente via requisições HTTP. É perfeito para gerenciar dados de vários clientes sem precisar de servidores complexos – tudo rodando no Google Apps Script de graça!

Vamos do básico ao avançado, com passos detalhados. Se você seguir à risca, em 5 minutos terá sua API no ar. Você pode adaptar para suas necessidades, como gerenciar integrações para diferentes clientes.


Com essa API, você ou seus sistemas podem:

  • Ler todos os dados

  • Buscar registros específicos

  • Adicionar novas linhas

  • Atualizar linhas existentes

  • Deletar linhas

Tudo via requisições HTTP simples (GET e POST).


1. O Código Completo da API (Copie e Cole)

Aqui está o script pronto que você vai colar no Google Apps Script. Ele já está testado e funcionando perfeitamente:

/**
 * API Planilha Google – Versão FINAL CORRIGIDA
 * Busca com igualdade exata (===)
 * Lógica de métodos corrigida
 */
const PLANILHA_ID = '[PLANILHA_ID]';
const SHEET_NAME = '[ABA_SHEET_NAME]';
const CACHE_TTL = 10 * 60 * 1000; // 10 minutos

let cache = { data: [], headers: [], lastUpdate: 0 };

// Entradas da Web App
function doGet(e) { return handleRequest(e, 'GET'); }
function doPost(e) { return handleRequest(e, 'POST'); }

function handleRequest(e, httpMethod) {
  let payload = {};

  // Lê o body JSON (apenas em POST)
  if (httpMethod === 'POST' && e.postData && e.postData.type === 'application/json') {
    try {
      payload = JSON.parse(e.postData.contents || '{}');
    } catch (err) {
      return jsonResponse({ status: 'error', message: 'JSON inválido no body' });
    }
  }

  // Atualiza cache se necessário
  if (Date.now() - cache.lastUpdate > CACHE_TTL) {
    refreshCache();
  }

  // Detecta método simulado (PATCH ou DELETE)
  const simulatedMethod = (payload._method || e.parameter.method || '').toUpperCase();

  // ==========================
  // GET → Lista tudo
  // ==========================
  if (httpMethod === 'GET') {
    return jsonResponse({
      status: 'success',
      total: cache.data.length,
      data: cache.data
    });
  }

  // ==========================
  // POST
  // ==========================
  if (httpMethod === 'POST') {
    // PATCH simulado
    if (simulatedMethod === 'PATCH') {
      if (!payload.filter || !payload.updates) {
        return jsonResponse({ status: 'error', message: 'PATCH precisa de "filter" e "updates"' });
      }
      return jsonResponse(updateRow(payload.filter.column, payload.filter.value, payload.updates));
    }

    // DELETE simulado
    if (simulatedMethod === 'DELETE') {
      if (!payload.filter) {
        return jsonResponse({ status: 'error', message: 'DELETE precisa de "filter"' });
      }
      return jsonResponse(deleteRow(payload.filter.column, payload.filter.value));
    }

    // Busca com filtro (igualdade exata)
    if (payload.filter && payload.filter.column && payload.filter.value !== undefined) {
      const col = payload.filter.column.trim();
      const val = payload.filter.value.toString();

      const resultados = cache.data.filter(row =>
        String(row[col] || '') === val
      );

      return jsonResponse({
        status: 'success',
        found: resultados.length > 0,
        total: resultados.length,
        data: resultados
      });
    }

    // Criação de nova linha (qualquer JSON sem filter nem _method)
    if (Object.keys(payload).length > 0) {
      return jsonResponse(createRow(payload));
    }

    return jsonResponse({ status: 'error', message: 'Body vazio ou inválido para POST' });
  }

  return jsonResponse({ status: 'error', message: 'Método HTTP não suportado' });
}

// Atualiza cache
function refreshCache() {
  const sheet = SpreadsheetApp.openById(PLANILHA_ID).getSheetByName(SHEET_NAME);
  const [header, ...rows] = sheet.getDataRange().getValues();

  const headers = header.map(h => String(h).trim());
  const data = rows.map(row => {
    const obj = {};
    headers.forEach((h, i) => obj[h] = row[i]);
    return obj;
  });

  cache = { data, headers, lastUpdate: Date.now() };
}

// Cria nova linha
function createRow(obj) {
  const sheet = SpreadsheetApp.openById(PLANILHA_ID).getSheetByName(SHEET_NAME);
  const headers = cache.headers;

  const invalidos = Object.keys(obj).filter(k => !headers.includes(k));
  if (invalidos.length > 0) {
    return { status: 'error', message: `Campos inválidos: ${invalidos.join(', ')}` };
  }

  const novaLinha = headers.map(h => obj[h] !== undefined ? obj[h] : '');
  sheet.appendRow(novaLinha);

  const novoObj = {};
  headers.forEach((h, i) => novoObj[h] = novaLinha[i]);
  cache.data.push(novoObj);

  return { status: 'success', message: 'Linha criada', data: novoObj };
}

// Atualiza linha (primeira ocorrência)
function updateRow(coluna, valor, updates) {
  const idx = cache.data.findIndex(row =>
    String(row[coluna] || '') === String(valor)
  );

  if (idx === -1) return { status: 'error', message: 'Linha não encontrada' };

  const sheet = SpreadsheetApp.openById(PLANILHA_ID).getSheetByName(SHEET_NAME);
  const headers = cache.headers;
  const linha = idx + 2;

  Object.keys(updates).forEach(chave => {
    if (headers.includes(chave)) {
      const col = headers.indexOf(chave) + 1;
      sheet.getRange(linha, col).setValue(updates[chave]);
      cache.data[idx][chave] = updates[chave];
    }
  });

  return { status: 'success', message: 'Linha atualizada', data: cache.data[idx] };
}

// Deleta linha
function deleteRow(coluna, valor) {
  const idx = cache.data.findIndex(row =>
    String(row[coluna] || '') === String(valor)
  );

  if (idx === -1) return { status: 'error', message: 'Linha não encontrada' };

  const sheet = SpreadsheetApp.openById(PLANILHA_ID).getSheetByName(SHEET_NAME);
  sheet.deleteRow(idx + 2);

  const deletado = cache.data.splice(idx, 1)[0];
  return { status: 'success', message: 'Linha deletada', deletedData: deletado };
}

// Resposta JSON
function jsonResponse(obj) {
  return ContentService
    .createTextOutput(JSON.stringify({ data: obj }, null, 2))
    .setMimeType(ContentService.MimeType.JSON);
}

2. Como Configurar as Informações da Sua Planilha no Código

Antes de colar o código, você precisa substituir duas partes:

  1. [PLANILHA_ID] → O ID único da sua planilha Google Sheets.

    • Abra sua planilha no navegador.

    • Olhe a URL: https://docs.google.com/spreadsheets/d/ABC123XYZ456/edit#gid=0

    • O ID é a parte entre /d/ e /edit: no exemplo, ABC123XYZ456.

    • Substitua [PLANILHA_ID] por esse valor (sem aspas extras).

  1. [ABA_SHEET_NAME] → O nome da aba (guia) da planilha que você quer usar.

    • Na parte inferior da planilha, veja o nome da aba (padrão é "Planilha1" ou "Sheet1").

    • Use exatamente o nome que aparece na aba (sensível a maiúsculas/minúsculas).

    • Nunca use nome de aba com acentos (` ´ ~ ^).

    • Exemplo: se a aba se chama "Clientes", coloque 'Clientes'

Depois de substituir esses dois valores, o código está pronto para uso!


3. Abrindo o Editor de Scripts e Colando o Código

  1. Na sua planilha aberta, clique no menu superior: Extensões > Apps Script.

  1. No editor que abrir, apague todo o código padrão (ex: function myFunction() {}):

  2. Cole o código completo da seção 1 (já com PLANILHA_ID e SHEET_NAME substituídos), clique em Salvar (disquete) e dê um nome ao projeto.:


4. Publicando como Web App (Tornando sua API pública)

  1. No editor do Apps Script, clique em Implantar > Nova implantação.

  2. Clique em Selecionar tipo > Aplicativo da web.

  3. Preencha:

    • Executar como: "Eu" (sua conta)

    • Quem tem acesso: "Qualquer pessoa".

  4. Clique em Implantar.

  5. Autorize as permissões (pode pedir confirmação – clique em "Avançado" > "Ir para o projeto" > "Permitir").

  6. Copie a URL do aplicativo web que aparece no final (ex: https://script.google.com/macros/s/.../exec). Essa é sua API!


5. Como Usar a API (Exemplos Práticos)

Agora que sua API está publicada, você pode usá-la de qualquer ferramenta que faz requisições HTTP, como curl (no terminal), Postman ou código em qualquer linguagem. Sempre substitua SUA_URL_AQUI pela URL que você copiou no passo 4.

Abaixo, explicamos cada método disponível separadamente. Para os métodos que usam POST, inclua sempre o header Content-Type: application/json.


Retornar Todas as Informações (GET)

Esse método retorna uma lista completa de todos os registros da planilha, como uma array de objetos JSON (cada objeto representa uma linha, com chaves baseadas nos cabeçalhos).

  • Como usar: Basta acessar a URL diretamente no navegador ou via GET, sem body ou parâmetros extras.

  • Exemplo com curl:

curl "SUA_URL_AQUI"
  • Body necessário: Nenhum (não envie body).

  • Resultado esperado: Um JSON com todos os dados. Exemplo (supondo 2 linhas na planilha):

{
  "data": {
    "status": "success",
    "total": 2,
    "data": [
      {
        "id": "1",
        "nome": "João Silva",
        "email": "[email protected]",
        "saldo": 1500
      },
      {
        "id": "2",
        "nome": "Maria Oliveira",
        "email": "[email protected]",
        "saldo": 3200
      }
    ]
  }
}

Retornar com Filtro (POST)

Esse método busca e retorna apenas as linhas que correspondem exatamente ao valor especificado em uma coluna (filtro exato, não parcial). Útil para consultar dados específicos de um cliente.

  • Como usar: Envie uma requisição POST com o body contendo o filtro (coluna e valor).

  • Exemplo com curl:

curl -X POST "SUA_URL_AQUI" \
  -H "Content-Type: application/json" \
  -d '{
    "filter": {
      "column": "id",
      "value": "1"
    }
  }'
  • Body necessário (formato espaçado):
{
  "filter": {
    "column": "id",
    "value": "1"
  }
}
  • Resultado esperado: Um JSON com as linhas filtradas (pode ser vazio se nada for encontrado). Exemplo:
{
  "data": {
    "status": "success",
    "found": true,
    "total": 1,
    "data": [
      {
        "id": "1",
        "nome": "João Silva",
        "email": "[email protected]",
        "saldo": 1500
      }
    ]
  }
}

Adicionar uma Nova Linha (POST)

Esse método adiciona uma nova linha à planilha com os valores fornecidos. As chaves do body devem corresponder exatamente aos cabeçalhos da planilha.

  • Como usar: Envie uma requisição POST com o body contendo os dados da nova linha (sem filtro ou _method).

  • Exemplo com curl:

curl -X POST "SUA_URL_AQUI" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "3",
    "nome": "Carlos Santos",
    "email": "[email protected]",
    "saldo": 5000
  }'
  • Body necessário (formato espaçado):
{
  "id": "3",
  "nome": "Carlos Santos",
  "email": "[email protected]",
  "saldo": 5000
}
  • Resultado esperado: Confirmação da criação com os dados adicionados. Exemplo:
{
  "data": {
    "status": "success",
    "message": "Linha criada",
    "data": {
      "id": "3",
      "nome": "Carlos Santos",
      "email": "[email protected]",
      "saldo": 5000
    }
  }
}

Atualizar uma Linha Existente (POST)

Esse método atualiza os valores de uma linha existente, usando um filtro para identificar qual linha alterar (atualiza a primeira que corresponde exatamente). Apenas os campos enviados em "updates" são modificados.

  • Como usar: Envie uma requisição POST com _method: "PATCH", filtro e os campos a atualizar.

  • Exemplo com curl:

curl -X POST "SUA_URL_AQUI" \
  -H "Content-Type: application/json" \
  -d '{
    "_method": "PATCH",
    "filter": {
      "column": "id",
      "value": "3"
    },
    "updates": {
      "nome": "Carlos Santos Atualizado",
      "saldo": 6000
    }
  }'
  • Body necessário (formato espaçado):
{
  "_method": "PATCH",
  "filter": {
    "column": "id",
    "value": "3"
  },
  "updates": {
    "nome": "Carlos Santos Atualizado",
    "saldo": 6000
  }
}
  • Resultado esperado: Confirmação da atualização com os dados da linha modificada. Exemplo:
{
  "data": {
    "status": "success",
    "message": "Linha atualizada",
    "data": {
      "id": "3",
      "nome": "Carlos Santos Atualizado",
      "email": "[email protected]",
      "saldo": 6000
    }
  }
}

Deletar uma Linha (POST)

Esse método deleta uma linha existente, usando um filtro para identificar qual remover (deleta a primeira que corresponde exatamente).

  • Como usar: Envie uma requisição POST com _method: "DELETE" e o filtro.

  • Exemplo com curl:

curl -X POST "SUA_URL_AQUI" \
  -H "Content-Type: application/json" \
  -d '{
    "_method": "DELETE",
    "filter": {
      "column": "id",
      "value": "3"
    }
  }'
  • Body necessário (formato espaçado):
{
  "_method": "DELETE",
  "filter": {
    "column": "id",
    "value": "3"
  }
}
  • Resultado esperado: Confirmação da deleção com os dados da linha removida. Exemplo:
{
  "data": {
    "status": "success",
    "message": "Linha deletada",
    "deletedData": {
      "id": "3",
      "nome": "Carlos Santos Atualizado",
      "email": "[email protected]",
      "saldo": 6000
    }
  }
}

Pronto! Agora você tem uma API profissional rodando.

Se precisar de ajuda, pode contar com o nosso time! Estamos aqui para acelerar suas integrações! 🚀