GOOGLE DRIVE - Armazenamento de Arquivos
O que é este Node?
O GOOGLE DRIVE é o node responsável por integrar com o Google Drive permitindo fazer upload, download, listar, deletar arquivos e criar pastas diretamente dos seus flows.
Por que este Node existe?
Gerenciar arquivos na nuvem programaticamente é essencial. O GOOGLE DRIVE existe para:
- Backup automático: Salvar arquivos recebidos no WhatsApp no Drive
- Compartilhamento: Gerar links de arquivos para enviar aos usuários
- Organização: Criar estrutura de pastas automaticamente
- Arquivo de conversas: Armazenar mídias de atendimentos
- Integração de documentos: Sincronizar arquivos entre sistemas
Como funciona internamente?
Quando o GOOGLE DRIVE é executado, o sistema:
- Autentica usando OAuth2 com Google (access_token e refresh_token)
- Identifica operação (upload, download, list, delete, createFolder)
- Conecta à API do Google Drive v3
- Executa operação com arquivos/pastas
- Retorna resultado com IDs, nomes e links
- Se erro: Loga e lança exceção
Código interno (productivity-executors.service.ts:447-541):
async executeGoogleDrive(data: any, variables: Record<string, any>): Promise<any> {
try {
this.logger.log('📁 [GOOGLE DRIVE] 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 drive = google.drive({ version: 'v3', auth: oauth2Client });
switch (data.operation) {
case 'upload':
const uploadResult = await drive.files.create({
requestBody: {
name: data.fileName,
parents: data.folderId ? [data.folderId] : undefined,
},
media: {
mimeType: data.mimeType,
body: Buffer.from(data.content, 'base64'),
},
fields: 'id,name,webViewLink,webContentLink',
});
return {
success: true,
fileId: uploadResult.data.id,
fileName: uploadResult.data.name,
webViewLink: uploadResult.data.webViewLink,
webContentLink: uploadResult.data.webContentLink,
};
case 'download':
const downloadResult = await drive.files.get({
fileId: data.fileId,
alt: 'media',
}, {
responseType: 'arraybuffer',
});
return {
success: true,
content: Buffer.from(downloadResult.data as ArrayBuffer).toString('base64'),
mimeType: downloadResult.headers['content-type'],
};
case 'list':
const listResult = await drive.files.list({
q: data.query || `'${data.folderId || 'root'}' in parents`,
fields: 'files(id, name, mimeType, size, modifiedTime, webViewLink)',
pageSize: data.pageSize || 100,
});
return {
success: true,
files: listResult.data.files,
};
case 'delete':
await drive.files.delete({
fileId: data.fileId,
});
return {
success: true,
message: 'File deleted successfully',
};
case 'createFolder':
const createFolderResult = await drive.files.create({
requestBody: {
name: data.folderName,
mimeType: 'application/vnd.google-apps.folder',
parents: data.parentFolderId ? [data.parentFolderId] : undefined,
},
fields: 'id,name,webViewLink',
});
return {
success: true,
folderId: createFolderResult.data.id,
folderName: createFolderResult.data.name,
webViewLink: createFolderResult.data.webViewLink,
};
default:
throw new Error(`Unknown Google Drive operation: ${data.operation}`);
}
} catch (error) {
this.logger.error('Google Drive execution error:', error);
throw error;
}
}
Quando você DEVE usar este Node?
Use GOOGLE DRIVE quando precisar gerenciar arquivos na nuvem:
Casos de uso:
- Backup de mídias: Salvar fotos/vídeos recebidos no WhatsApp
- Compartilhar documentos: Enviar link de arquivo armazenado
- Organizar por cliente: Criar pasta para cada cliente automaticamente
- Arquivo de propostas: Armazenar PDFs de propostas enviadas
- Catálogo de produtos: Manter imagens organizadas por categoria
- Documentos recebidos: Arquivar documentos enviados por clientes
Quando NÃO usar GOOGLE DRIVE:
- Dados estruturados: Use GOOGLE SHEETS para tabelas
- Pequenos textos: Use VARIABLE para dados temporários
- Arquivos Microsoft: Use ONEDRIVE para ecosistema Office
Parâmetros Detalhados
operation (string, obrigatório)
O que é: Define qual operação será executada no Google Drive.
Valores possíveis:
- upload: Fazer upload de arquivo
- download: Baixar arquivo
- list: Listar arquivos/pastas
- delete: Deletar arquivo/pasta
- createFolder: Criar nova pasta
accessToken (string, obrigatório)
O que é: Token de acesso OAuth2 do Google para autenticação.
Como obter: Configure OAuth2 no Google Cloud Console.
refreshToken (string, obrigatório)
O que é: Token de refresh OAuth2 para renovar access token.
fileName (string, obrigatório para upload)
O que é: Nome do arquivo a ser criado no Drive.
Flow completo para testar:
{
"name": "Teste GOOGLE DRIVE - Upload",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "media_1",
"type": "media",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Receber Imagem",
"parameters": {
"message": "Envie uma imagem:",
"variable": "imagem",
"mediaType": "image"
}
}
},
{
"id": "drive_1",
"type": "google_drive",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Upload no Drive",
"parameters": {
"operation": "upload",
"fileName": "imagem_{{timestamp}}.jpg",
"content": "{{imagem}}",
"mimeType": "image/jpeg",
"folderId": "pasta_imagens_id",
"accessToken": "{{google_access_token}}",
"refreshToken": "{{google_refresh_token}}"
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Confirmar",
"parameters": {
"message": "✅ Imagem salva no Drive!\n\n🔗 {{drive_1.webViewLink}}"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 900, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "media_1" },
{ "source": "media_1", "target": "drive_1" },
{ "source": "drive_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
content (string, obrigatório para upload)
O que é: Conteúdo do arquivo em base64.
mimeType (string, obrigatório para upload)
O que é: Tipo MIME do arquivo.
Exemplos comuns:
- image/jpeg - Imagens JPG
- image/png - Imagens PNG
- application/pdf - Documentos PDF
- video/mp4 - Vídeos MP4
- audio/mpeg - Áudios MP3
- text/plain - Arquivos de texto
folderId (string, opcional)
O que é: ID da pasta onde o arquivo será salvo (padrão: root).
Como obter: Na URL da pasta: https://drive.google.com/drive/folders/[FOLDER_ID]
fileId (string, obrigatório para download/delete)
O que é: ID único do arquivo no Google Drive.
Flow completo para testar:
{
"name": "Teste GOOGLE DRIVE - Download",
"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": "ID do Arquivo",
"parameters": {
"message": "Digite o ID do arquivo:",
"variable": "file_id"
}
}
},
{
"id": "drive_1",
"type": "google_drive",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Baixar Arquivo",
"parameters": {
"operation": "download",
"fileId": "{{file_id}}",
"accessToken": "{{google_access_token}}",
"refreshToken": "{{google_refresh_token}}"
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Confirmar",
"parameters": {
"message": "✅ Arquivo baixado!\n\nTipo: {{drive_1.mimeType}}"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 900, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "input_1" },
{ "source": "input_1", "target": "drive_1" },
{ "source": "drive_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
query (string, opcional para list)
O que é: Query de busca do Google Drive (formato: Drive API query).
Exemplos:
- "name contains 'relatorio'" - Arquivos com "relatorio" no nome
- "mimeType='image/jpeg'" - Apenas imagens JPG
- "modifiedTime > '2025-01-01T00:00:00'" - Modificados após data
pageSize (number, opcional)
O que é: Número máximo de resultados a retornar (padrão: 100, máximo: 1000).
Parâmetros
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| operation | string | Sim | upload, download, list, delete, createFolder |
| accessToken | string | Sim | Token OAuth2 de acesso |
| refreshToken | string | Sim | Token OAuth2 de refresh |
| fileName | string | Sim* | Nome do arquivo (para upload) |
| content | string | Sim* | Conteúdo em base64 (para upload) |
| mimeType | string | Sim* | Tipo MIME (para upload) |
| folderId | string | Não | ID da pasta (padrão: root) |
| fileId | string | Sim* | ID do arquivo (para download, delete) |
| query | string | Não | Query de busca (para list) |
| pageSize | number | Não | Limite de resultados (padrão: 100) |
| folderName | string | Sim* | Nome da pasta (para createFolder) |
| parentFolderId | string | Não | ID da pasta pai (para createFolder) |
*Obrigatório dependendo da operação
Exemplo 1: Backup de Documentos Recebidos
Objetivo: Salvar automaticamente documentos enviados por clientes no Drive.
JSON para Importar
{
"name": "Backup Automático - Google Drive",
"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": "Solicitar Documento",
"parameters": {
"message": "📄 Por favor, envie seu documento (PDF, imagem ou vídeo):"
}
}
},
{
"id": "media_1",
"type": "media",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Receber Mídia",
"parameters": {
"message": "Aguardando documento...",
"variable": "documento"
}
}
},
{
"id": "drive_1",
"type": "google_drive",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Salvar no Drive",
"parameters": {
"operation": "upload",
"fileName": "{{contact_name}}_{{timestamp}}",
"content": "{{documento}}",
"mimeType": "{{documento_mime_type}}",
"folderId": "documentos_clientes_folder_id",
"accessToken": "{{google_access_token}}",
"refreshToken": "{{google_refresh_token}}"
}
}
},
{
"id": "message_2",
"type": "message",
"position": { "x": 900, "y": 100 },
"data": {
"label": "Confirmar",
"parameters": {
"message": "✅ Documento recebido e arquivado!\n\n📁 ID: {{drive_1.fileId}}\n🔗 Link: {{drive_1.webViewLink}}\n\nObrigado!"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 1100, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "message_1" },
{ "source": "message_1", "target": "media_1" },
{ "source": "media_1", "target": "drive_1" },
{ "source": "drive_1", "target": "message_2" },
{ "source": "message_2", "target": "end_1" }
]
}
Saída esperada:
Sistema: 📄 Por favor, envie seu documento (PDF, imagem ou vídeo):
Sistema: Aguardando documento...
Usuário: [envia PDF]
Sistema: ✅ Documento recebido e arquivado!
📁 ID: 1abc2def3ghi
🔗 Link: https://drive.google.com/file/d/1abc2def3ghi/view
Obrigado!
Exemplo 2: Criar Estrutura de Pastas por Cliente
Objetivo: Criar pasta personalizada para cada novo cliente.
JSON para Importar
{
"name": "Criar Pasta Cliente - Google Drive",
"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 do Cliente",
"parameters": {
"message": "Nome do novo cliente:",
"variable": "cliente_nome"
}
}
},
{
"id": "drive_1",
"type": "google_drive",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Criar Pasta Principal",
"parameters": {
"operation": "createFolder",
"folderName": "Cliente - {{cliente_nome}}",
"parentFolderId": "clientes_root_folder_id",
"accessToken": "{{google_access_token}}",
"refreshToken": "{{google_refresh_token}}"
}
}
},
{
"id": "drive_2",
"type": "google_drive",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Subpasta Contratos",
"parameters": {
"operation": "createFolder",
"folderName": "Contratos",
"parentFolderId": "{{drive_1.folderId}}",
"accessToken": "{{google_access_token}}",
"refreshToken": "{{google_refresh_token}}"
}
}
},
{
"id": "drive_3",
"type": "google_drive",
"position": { "x": 900, "y": 100 },
"data": {
"label": "Subpasta Documentos",
"parameters": {
"operation": "createFolder",
"folderName": "Documentos",
"parentFolderId": "{{drive_1.folderId}}",
"accessToken": "{{google_access_token}}",
"refreshToken": "{{google_refresh_token}}"
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 1100, "y": 100 },
"data": {
"label": "Confirmar",
"parameters": {
"message": "✅ Estrutura criada para {{cliente_nome}}!\n\n📁 Pasta principal: {{drive_1.webViewLink}}\n📂 Contratos: {{drive_2.folderId}}\n📂 Documentos: {{drive_3.folderId}}"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 1300, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "input_1" },
{ "source": "input_1", "target": "drive_1" },
{ "source": "drive_1", "target": "drive_2" },
{ "source": "drive_2", "target": "drive_3" },
{ "source": "drive_3", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
Saída esperada:
Sistema: Nome do novo cliente:
Usuário: Tech Solutions LTDA
Sistema: ✅ Estrutura criada para Tech Solutions LTDA!
📁 Pasta principal: https://drive.google.com/drive/folders/abc123
📂 Contratos: def456
📂 Documentos: ghi789
Exemplo 3: Listar Arquivos e Compartilhar
Objetivo: Listar arquivos de uma pasta e enviar links ao usuário.
JSON para Importar
{
"name": "Catálogo de Arquivos - Google Drive",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "drive_1",
"type": "google_drive",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Listar PDFs",
"parameters": {
"operation": "list",
"folderId": "catalogo_folder_id",
"query": "mimeType='application/pdf'",
"pageSize": 10,
"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 DOCUMENTOS\n\nEncontramos {{drive_1.files.length}} arquivos disponíveis.\n\nDigite o número do arquivo desejado."
}
}
},
{
"id": "input_1",
"type": "input",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Escolher Arquivo",
"parameters": {
"message": "Número do arquivo:",
"variable": "arquivo_numero"
}
}
},
{
"id": "message_2",
"type": "message",
"position": { "x": 900, "y": 100 },
"data": {
"label": "Enviar Link",
"parameters": {
"message": "✅ Aqui está o link do arquivo {{arquivo_numero}}:\n\n🔗 [Link será gerado dinamicamente]"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 1100, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "drive_1" },
{ "source": "drive_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 DOCUMENTOS
Encontramos 8 arquivos disponíveis.
Digite o número do arquivo desejado.
Sistema: Número do arquivo:
Usuário: 3
Sistema: ✅ Aqui está o link do arquivo 3:
🔗 [Link será gerado dinamicamente]
Resposta do Node
Operação UPLOAD:
{
"success": true,
"fileId": "1abc2def3ghi4jkl5mno",
"fileName": "documento.pdf",
"webViewLink": "https://drive.google.com/file/d/1abc2def3ghi4jkl5mno/view",
"webContentLink": "https://drive.google.com/uc?id=1abc2def3ghi4jkl5mno&export=download"
}
Operação DOWNLOAD:
{
"success": true,
"content": "base64_encoded_content_here...",
"mimeType": "application/pdf"
}
Operação LIST:
{
"success": true,
"files": [
{
"id": "1abc2def",
"name": "relatorio.pdf",
"mimeType": "application/pdf",
"size": "1048576",
"modifiedTime": "2025-01-15T10:30:00.000Z",
"webViewLink": "https://drive.google.com/file/d/1abc2def/view"
}
]
}
Operação CREATE_FOLDER:
{
"success": true,
"folderId": "1xyz2abc3def",
"folderName": "Nova Pasta",
"webViewLink": "https://drive.google.com/drive/folders/1xyz2abc3def"
}
Boas Práticas
✅ SIM: - Use nomes descritivos para arquivos e pastas - Organize em estrutura de pastas lógica - Valide mimeType antes de upload - Implemente tratamento de erros - Use query específica para listar (melhor performance)
❌ NÃO: - Não faça upload de arquivos muito grandes (> 10MB) sem validação - Não exponha tokens em logs ou mensagens - Não delete arquivos sem confirmação - Não abuse de listagens sem filtro
Dicas
💡 Permissões: Configure compartilhamento adequado nas pastas do Drive
💡 Quota: Google Drive tem limites de armazenamento e API, monitore uso
💡 Backup: Mantenha backups importantes em múltiplos locais
💡 Organização: Use convenções de nomenclatura consistentes (cliente_data_tipo.ext)
💡 Integração: Combine com GOOGLE SHEETS para indexar arquivos enviados
Próximo Node
→ ONEDRIVE - Alternativa Microsoft para armazenamento → GOOGLE SHEETS - Planilhas do Google → MEDIA - Receber mídias do WhatsApp