Bienvenido a la Documentación de Google Drive API v3
¿Qué puedes hacer con esta API?
- ✅ Crear, leer, actualizar y eliminar archivos
- ✅ Gestionar permisos y compartir archivos
- ✅ Buscar archivos con consultas avanzadas
- ✅ Trabajar con carpetas y estructuras jerárquicas
- ✅ Sincronizar cambios en tiempo real
- ✅ Gestionar comentarios y revisiones
- ✅ Integrar con Shared Drives (Team Drives)
Características Principales
📤 Subir Archivos
Carga archivos de hasta 5TB con soporte para uploads resumibles
🔍 Búsqueda Avanzada
Encuentra archivos con consultas personalizadas y filtros
🔐 Control de Acceso
Gestiona permisos granulares para usuarios y grupos
🔄 Sincronización
Mantén tus aplicaciones actualizadas con webhooks
Base URL
https://www.googleapis.com/drive/v3/
⚡ Inicio Rápido
Pasos para Comenzar
- Crear un proyecto en Google Cloud Console
- Habilitar la API de Google Drive
- Crear credenciales OAuth 2.0
- Configurar el consentimiento de OAuth
- Hacer tu primera solicitud
Primer Ejemplo: Listar Archivos
// Listar los primeros 10 archivos
const accessToken = 'YOUR_ACCESS_TOKEN';
fetch('https://www.googleapis.com/drive/v3/files?pageSize=10', {
headers: {
'Authorization': `Bearer ${accessToken}`
}
})
.then(response => response.json())
.then(data => {
console.log('Archivos:', data.files);
data.files.forEach(file => {
console.log(`${file.name} (${file.id})`);
});
})
.catch(error => console.error('Error:', error));
from google.oauth2.credentials import Credentials
from googleapiclient.discovery import build
# Configurar credenciales
creds = Credentials(token='YOUR_ACCESS_TOKEN')
service = build('drive', 'v3', credentials=creds)
# Listar archivos
results = service.files().list(
pageSize=10,
fields="files(id, name, mimeType)"
).execute()
files = results.get('files', [])
for file in files:
print(f"{file['name']} ({file['id']})")
curl -X GET \
'https://www.googleapis.com/drive/v3/files?pageSize=10' \
-H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
-H 'Content-Type: application/json'
🔐 Autenticación OAuth 2.0
Scopes Disponibles
Los scopes definen los permisos que tu aplicación necesita. Solicita solo los scopes necesarios.
| Scope | Descripción |
|---|---|
https://www.googleapis.com/auth/drive |
Acceso completo a todos los archivos |
https://www.googleapis.com/auth/drive.file |
Solo archivos creados por la app |
https://www.googleapis.com/auth/drive.readonly |
Solo lectura de archivos |
https://www.googleapis.com/auth/drive.metadata |
Ver y modificar metadatos |
https://www.googleapis.com/auth/drive.metadata.readonly |
Solo lectura de metadatos |
https://www.googleapis.com/auth/drive.appdata |
Acceso a carpeta de datos de la app |
Flujo de Autenticación
// Ejemplo de autenticación con Google OAuth2
const CLIENT_ID = 'your-client-id.apps.googleusercontent.com';
const REDIRECT_URI = 'http://localhost:3000/callback';
const SCOPE = 'https://www.googleapis.com/auth/drive.file';
// Paso 1: Redirigir al usuario a la página de autorización
const authUrl = `https://accounts.google.com/o/oauth2/v2/auth?` +
`client_id=${CLIENT_ID}&` +
`redirect_uri=${REDIRECT_URI}&` +
`response_type=code&` +
`scope=${SCOPE}&` +
`access_type=offline`;
window.location.href = authUrl;
// Paso 2: Intercambiar el código por tokens (en tu backend)
const response = await fetch('https://oauth2.googleapis.com/token', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
code: authorizationCode,
client_id: CLIENT_ID,
client_secret: CLIENT_SECRET,
redirect_uri: REDIRECT_URI,
grant_type: 'authorization_code'
})
});
const { access_token, refresh_token } = await response.json();
📄 Files - Gestión de Archivos
GET files.list
Lista los archivos del usuario con opciones de filtrado y paginación.
Parámetros de Consulta
| Parámetro | Tipo | Descripción |
|---|---|---|
pageSize |
integer | Número máximo de archivos por página (1-1000, default: 100) |
pageToken |
string | Token para continuar con la siguiente página |
q |
string | Consulta de búsqueda (ej: "name contains 'invoice'") |
orderBy |
string | Ordenar por: createdTime, folder, modifiedTime, name, etc. |
spaces |
string | Espacios a consultar: 'drive', 'appDataFolder' |
// Buscar archivos PDF modificados recientemente
const query = "mimeType='application/pdf' and modifiedTime > '2024-01-01T00:00:00'";
const response = await fetch(
`https://www.googleapis.com/drive/v3/files?q=${encodeURIComponent(query)}&orderBy=modifiedTime desc&pageSize=20`,
{
headers: {
'Authorization': `Bearer ${accessToken}`
}
}
);
const data = await response.json();
console.log('Archivos encontrados:', data.files);
query = "mimeType='application/pdf' and modifiedTime > '2024-01-01T00:00:00'"
results = service.files().list(
q=query,
orderBy='modifiedTime desc',
pageSize=20,
fields='files(id, name, mimeType, modifiedTime)'
).execute()
files = results.get('files', [])
print(f'Encontrados {len(files)} archivos')
curl -X GET \
'https://www.googleapis.com/drive/v3/files?q=mimeType%3D%27application%2Fpdf%27&orderBy=modifiedTime%20desc&pageSize=20' \
-H 'Authorization: Bearer YOUR_ACCESS_TOKEN'
POST files.create
Crea un nuevo archivo o carpeta en Google Drive.
Crear una Carpeta
// Crear una nueva carpeta
const metadata = {
name: 'Mi Nueva Carpeta',
mimeType: 'application/vnd.google-apps.folder'
};
const response = await fetch('https://www.googleapis.com/drive/v3/files', {
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(metadata)
});
const folder = await response.json();
console.log('Carpeta creada:', folder.id);
folder_metadata = {
'name': 'Mi Nueva Carpeta',
'mimeType': 'application/vnd.google-apps.folder'
}
folder = service.files().create(
body=folder_metadata,
fields='id, name'
).execute()
print(f'Carpeta creada: {folder.get("id")}')
curl -X POST \
'https://www.googleapis.com/drive/v3/files' \
-H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"name": "Mi Nueva Carpeta",
"mimeType": "application/vnd.google-apps.folder"
}'
Subir un Archivo
// Subir un archivo con contenido
const fileContent = 'Contenido del archivo';
const metadata = {
name: 'documento.txt',
mimeType: 'text/plain'
};
const form = new FormData();
form.append('metadata', new Blob([JSON.stringify(metadata)], { type: 'application/json' }));
form.append('file', new Blob([fileContent], { type: 'text/plain' }));
const response = await fetch('https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart', {
method: 'POST',
headers: { 'Authorization': `Bearer ${accessToken}` },
body: form
});
const file = await response.json();
console.log('Archivo subido:', file.id);
from googleapiclient.http import MediaFileUpload
file_metadata = {'name': 'documento.txt'}
media = MediaFileUpload('local_file.txt', mimetype='text/plain')
file = service.files().create(
body=file_metadata,
media_body=media,
fields='id, name'
).execute()
print(f'Archivo subido: {file.get("id")}')
GET files.get
Obtiene los metadatos o el contenido de un archivo por su ID.
// Obtener metadatos de un archivo
const fileId = '1abc...xyz';
const fields = 'id,name,mimeType,createdTime,modifiedTime,size,owners';
const response = await fetch(
`https://www.googleapis.com/drive/v3/files/${fileId}?fields=${fields}`,
{ headers: { 'Authorization': `Bearer ${accessToken}` }}
);
const fileMetadata = await response.json();
console.log('Metadatos:', fileMetadata);
file_id = '1abc...xyz'
file = service.files().get(
fileId=file_id,
fields='id,name,mimeType,createdTime,modifiedTime,size,owners'
).execute()
print(f'Archivo: {file.get("name")}')
PATCH files.update
Actualiza los metadatos o el contenido de un archivo.
// Renombrar un archivo
const fileId = '1abc...xyz';
const newMetadata = { name: 'nuevo_nombre.txt' };
const response = await fetch(
`https://www.googleapis.com/drive/v3/files/${fileId}`,
{
method: 'PATCH',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(newMetadata)
}
);
const updated = await response.json();
console.log('Archivo actualizado:', updated.name);
DELETE files.delete
Elimina permanentemente un archivo (sin mover a la papelera).
files.update con trashed: true.
// Eliminar un archivo permanentemente
const fileId = '1abc...xyz';
await fetch(`https://www.googleapis.com/drive/v3/files/${fileId}`, {
method: 'DELETE',
headers: { 'Authorization': `Bearer ${accessToken}` }
});
console.log('Archivo eliminado');
👥 Permissions - Gestión de Permisos
Tipos de Permisos
| Rol | Descripción |
|---|---|
owner |
Propietario del archivo con control total |
organizer |
Organizador (solo para shared drives) |
fileOrganizer |
Organizador de archivos (solo para shared drives) |
writer |
Puede editar y comentar |
commenter |
Puede ver y comentar |
reader |
Solo puede ver |
POST permissions.create
Crea un permiso para compartir un archivo con un usuario, grupo o hacer público.
Compartir con un Usuario Específico
// Compartir archivo con un usuario
const fileId = '1abc...xyz';
const permission = {
type: 'user',
role: 'writer',
emailAddress: 'usuario@example.com'
};
const response = await fetch(
`https://www.googleapis.com/drive/v3/files/${fileId}/permissions`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(permission)
}
);
const perm = await response.json();
console.log('Permiso creado:', perm.id);
permission = {
'type': 'user',
'role': 'writer',
'emailAddress': 'usuario@example.com'
}
result = service.permissions().create(
fileId=file_id,
body=permission,
fields='id'
).execute()
print(f'Permiso creado: {result.get("id")}')
Hacer un Archivo Público
// Hacer un archivo público (cualquiera con el enlace puede ver)
const fileId = '1abc...xyz';
const publicPermission = {
type: 'anyone',
role: 'reader'
};
await fetch(
`https://www.googleapis.com/drive/v3/files/${fileId}/permissions`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(publicPermission)
}
);
console.log('Archivo ahora es público');
GET permissions.list
Lista todos los permisos de un archivo.
const fileId = '1abc...xyz';
const response = await fetch(
`https://www.googleapis.com/drive/v3/files/${fileId}/permissions`,
{ headers: { 'Authorization': `Bearer ${accessToken}` }}
);
const data = await response.json();
data.permissions.forEach(perm => {
console.log(`${perm.emailAddress}: ${perm.role}`);
});
DELETE permissions.delete
Elimina un permiso de un archivo.
const fileId = '1abc...xyz';
const permissionId = 'permission123';
await fetch(
`https://www.googleapis.com/drive/v3/files/${fileId}/permissions/${permissionId}`,
{
method: 'DELETE',
headers: { 'Authorization': `Bearer ${accessToken}` }
}
);
console.log('Permiso eliminado');
💬 Comments - Gestión de Comentarios
POST comments.create
Crea un comentario en un archivo.
const fileId = '1abc...xyz';
const comment = {
content: 'Este es un comentario de ejemplo'
};
const response = await fetch(
`https://www.googleapis.com/drive/v3/files/${fileId}/comments`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(comment)
}
);
const newComment = await response.json();
console.log('Comentario creado:', newComment.id);
GET comments.list
Lista todos los comentarios de un archivo.
const fileId = '1abc...xyz';
const response = await fetch(
`https://www.googleapis.com/drive/v3/files/${fileId}/comments`,
{ headers: { 'Authorization': `Bearer ${accessToken}` }}
);
const data = await response.json();
data.comments.forEach(comment => {
console.log(`${comment.author.displayName}: ${comment.content}`);
});
↩️ Replies - Respuestas a Comentarios
POST replies.create
Crea una respuesta a un comentario.
const fileId = '1abc...xyz';
const commentId = 'comment123';
const reply = {
content: 'Esta es una respuesta al comentario'
};
const response = await fetch(
`https://www.googleapis.com/drive/v3/files/${fileId}/comments/${commentId}/replies`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(reply)
}
);
const newReply = await response.json();
console.log('Respuesta creada:', newReply.id);
📋 Revisions - Historial de Versiones
GET revisions.list
Lista todas las revisiones de un archivo.
const fileId = '1abc...xyz';
const response = await fetch(
`https://www.googleapis.com/drive/v3/files/${fileId}/revisions`,
{ headers: { 'Authorization': `Bearer ${accessToken}` }}
);
const data = await response.json();
data.revisions.forEach(rev => {
console.log(`Revisión ${rev.id}: ${rev.modifiedTime}`);
});
GET revisions.get
Obtiene una revisión específica de un archivo.
const fileId = '1abc...xyz';
const revisionId = 'revision123';
const response = await fetch(
`https://www.googleapis.com/drive/v3/files/${fileId}/revisions/${revisionId}`,
{ headers: { 'Authorization': `Bearer ${accessToken}` }}
);
const revision = await response.json();
console.log('Revisión:', revision);
🗂️ Drives - Shared Drives (Team Drives)
GET drives.list
Lista los shared drives del usuario.
const response = await fetch(
'https://www.googleapis.com/drive/v3/drives',
{ headers: { 'Authorization': `Bearer ${accessToken}` }}
);
const data = await response.json();
data.drives.forEach(drive => {
console.log(`${drive.name} (${drive.id})`);
});
POST drives.create
Crea un nuevo shared drive.
const driveMetadata = {
name: 'Mi Equipo de Trabajo'
};
const requestId = crypto.randomUUID(); // ID único para idempotencia
const response = await fetch(
`https://www.googleapis.com/drive/v3/drives?requestId=${requestId}`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(driveMetadata)
}
);
const drive = await response.json();
console.log('Shared Drive creado:', drive.id);
🔄 Changes - Sincronización de Cambios
GET changes.getStartPageToken
Obtiene el token inicial para comenzar a monitorear cambios.
const response = await fetch(
'https://www.googleapis.com/drive/v3/changes/startPageToken',
{ headers: { 'Authorization': `Bearer ${accessToken}` }}
);
const data = await response.json();
const pageToken = data.startPageToken;
console.log('Start token:', pageToken);
GET changes.list
Lista los cambios ocurridos desde un pageToken específico.
const pageToken = 'your_page_token';
const response = await fetch(
`https://www.googleapis.com/drive/v3/changes?pageToken=${pageToken}`,
{ headers: { 'Authorization': `Bearer ${accessToken}` }}
);
const data = await response.json();
data.changes.forEach(change => {
console.log(`Cambio en archivo: ${change.fileId}`);
console.log(`Tipo: ${change.type}`);
});
// Guardar el nuevo pageToken para la próxima consulta
const newPageToken = data.newStartPageToken;
console.log('Nuevo token:', newPageToken);
ℹ️ About - Información del Usuario
GET about.get
Obtiene información sobre el usuario, su Drive y capacidades del sistema.
const response = await fetch(
'https://www.googleapis.com/drive/v3/about?fields=user,storageQuota,canCreateDrives',
{ headers: { 'Authorization': `Bearer ${accessToken}` }}
);
const data = await response.json();
console.log('Usuario:', data.user.displayName);
console.log('Espacio usado:', data.storageQuota.usage);
console.log('Límite:', data.storageQuota.limit);
🎯 Apps - Aplicaciones Instaladas
GET apps.list
Lista las aplicaciones instaladas por el usuario.
const response = await fetch(
'https://www.googleapis.com/drive/v3/apps',
{ headers: { 'Authorization': `Bearer ${accessToken}` }}
);
const data = await response.json();
data.items.forEach(app => {
console.log(`${app.name}: ${app.id}`);
});
📡 Channels - Notificaciones Push
POST files.watch
Suscríbete a cambios en un archivo específico.
const fileId = '1abc...xyz';
const channel = {
id: crypto.randomUUID(),
type: 'web_hook',
address: 'https://tu-servidor.com/webhook'
};
const response = await fetch(
`https://www.googleapis.com/drive/v3/files/${fileId}/watch`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(channel)
}
);
const watchChannel = await response.json();
console.log('Canal creado:', watchChannel.id);
POST channels.stop
Detiene un canal de notificaciones.
const channel = {
id: 'channel-id',
resourceId: 'resource-id'
};
await fetch('https://www.googleapis.com/drive/v3/channels/stop', {
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(channel)
});
console.log('Canal detenido');
🔓 Access Proposals - Solicitudes de Acceso
GET accessproposals.list
Lista las solicitudes de acceso pendientes para un archivo.
const fileId = '1abc...xyz';
const response = await fetch(
`https://www.googleapis.com/drive/v3/files/${fileId}/accessproposals`,
{ headers: { 'Authorization': `Bearer ${accessToken}` }}
);
const data = await response.json();
data.accessProposals.forEach(proposal => {
console.log(`Solicitud de: ${proposal.requester.emailAddress}`);
});
⚠️ Errores Comunes y Soluciones
Códigos de Error HTTP
| Código | Mensaje | Solución |
|---|---|---|
401 |
Unauthorized | El token de acceso no es válido o ha expirado. Renueva el token. |
403 |
Forbidden | No tienes permisos suficientes. Verifica los scopes y permisos del archivo. |
404 |
Not Found | El archivo no existe o no tienes acceso a él. |
429 |
Too Many Requests | Has excedido los límites de tasa. Implementa exponential backoff. |
500 |
Internal Server Error | Error del servidor de Google. Reintenta la solicitud después de un delay. |
Errores Comunes
1. "Invalid Credentials"
Solución: Asegúrate de que estás usando el token correcto y que no ha expirado. Usa el refresh token para obtener uno nuevo.
2. "Insufficient Permissions"
Solución: Solicita los scopes adecuados durante la autenticación. Por ejemplo, necesitas
drive.file o drive para crear archivos.
3. "File not found"
Solución: Verifica que el ID del archivo sea correcto y que el usuario tenga acceso.
4. "Rate Limit Exceeded"
Solución: Implementa exponential backoff con reintento.
// Implementación de Exponential Backoff
async function fetchWithRetry(url, options, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
const response = await fetch(url, options);
if (response.status === 429) {
const delay = Math.pow(2, i) * 1000; // 1s, 2s, 4s
console.log(`Rate limit. Esperando ${delay}ms...`);
await new Promise(resolve => setTimeout(resolve, delay));
continue;
}
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
return await response.json();
} catch (error) {
if (i === maxRetries - 1) throw error;
}
}
}
📊 Límites y Cuotas
Límites de Tasa
| Recurso | Límite |
|---|---|
| Solicitudes por usuario por 100 segundos | 1,000 solicitudes |
| Solicitudes por proyecto por 100 segundos | 10,000 solicitudes |
| Tamaño máximo de archivo (upload simple) | 5 MB |
| Tamaño máximo de archivo (upload resumible) | 5 TB |
| Archivos compartidos con un usuario | Ilimitado |
| Revisiones por archivo | 200 (kept forever) |
Cuotas de Almacenamiento
- Google Drive gratuito: 15 GB compartidos con Gmail y Google Photos
- Google One: De 100 GB a 2 TB
- Google Workspace: Variable según el plan (30 GB - ilimitado)
Mejores Prácticas
- ✅ Implementa exponential backoff para manejar errores 429
- ✅ Usa campos específicos con el parámetro
fieldspara reducir el tamaño de respuestas - ✅ Almacena en caché los resultados cuando sea posible
- ✅ Usa batch requests para múltiples operaciones
- ✅ Implementa paginación adecuada para listas grandes
- ✅ Usa uploads resumibles para archivos grandes
💡 Ejemplos Prácticos
Ejemplo 1: Sistema de Backup Automático
Crea una carpeta de backup y sube archivos automáticamente.
async function createBackupSystem(accessToken) {
// 1. Crear carpeta de backup
const folderMetadata = {
name: `Backup_${new Date().toISOString().split('T')[0]}`,
mimeType: 'application/vnd.google-apps.folder'
};
const folderResponse = await fetch('https://www.googleapis.com/drive/v3/files', {
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(folderMetadata)
});
const folder = await folderResponse.json();
console.log('Carpeta creada:', folder.id);
// 2. Subir archivos a la carpeta
async function uploadFile(fileName, fileContent) {
const metadata = {
name: fileName,
parents: [folder.id]
};
const form = new FormData();
form.append('metadata', new Blob([JSON.stringify(metadata)], { type: 'application/json' }));
form.append('file', new Blob([fileContent]));
const response = await fetch(
'https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart',
{
method: 'POST',
headers: { 'Authorization': `Bearer ${accessToken}` },
body: form
}
);
return await response.json();
}
// Subir archivos
const files = ['config.json', 'database.sql', 'logs.txt'];
for (const file of files) {
const result = await uploadFile(file, `Contenido de ${file}`);
console.log(`${file} subido: ${result.id}`);
}
return folder.id;
}
Ejemplo 2: Búsqueda Avanzada de Archivos
Busca archivos con múltiples criterios y filtros.
async function advancedSearch(accessToken, criteria) {
const queries = [];
// Filtro por nombre
if (criteria.name) {
queries.push(`name contains '${criteria.name}'`);
}
// Filtro por tipo MIME
if (criteria.mimeType) {
queries.push(`mimeType='${criteria.mimeType}'`);
}
// Filtro por fecha de modificación
if (criteria.modifiedAfter) {
queries.push(`modifiedTime > '${criteria.modifiedAfter}'`);
}
// Excluir archivos en papelera
queries.push('trashed=false');
const query = queries.join(' and ');
const response = await fetch(
`https://www.googleapis.com/drive/v3/files?q=${encodeURIComponent(query)}&orderBy=modifiedTime desc`,
{ headers: { 'Authorization': `Bearer ${accessToken}` }}
);
const data = await response.json();
return data.files;
}
// Uso
const results = await advancedSearch(accessToken, {
name: 'reporte',
mimeType: 'application/pdf',
modifiedAfter: '2024-01-01T00:00:00'
});
console.log(`Encontrados ${results.length} archivos`);
Ejemplo 3: Compartir Archivo con Múltiples Usuarios
Comparte un archivo con varios usuarios de una vez.
async function shareWithMultipleUsers(accessToken, fileId, users) {
const results = [];
for (const user of users) {
const permission = {
type: 'user',
role: user.role || 'reader',
emailAddress: user.email
};
try {
const response = await fetch(
`https://www.googleapis.com/drive/v3/files/${fileId}/permissions?sendNotificationEmail=true`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(permission)
}
);
const result = await response.json();
results.push({ email: user.email, success: true, permissionId: result.id });
} catch (error) {
results.push({ email: user.email, success: false, error: error.message });
}
}
return results;
}
// Uso
const users = [
{ email: 'usuario1@example.com', role: 'writer' },
{ email: 'usuario2@example.com', role: 'reader' },
{ email: 'usuario3@example.com', role: 'commenter' }
];
const shareResults = await shareWithMultipleUsers(accessToken, fileId, users);
shareResults.forEach(r => {
console.log(`${r.email}: ${r.success ? '✓ Compartido' : '✗ Error'}`);
});
Ejemplo 4: Monitorear Cambios en Tiempo Real
Detecta cambios en archivos usando el API de Changes.
class DriveChangeMonitor {
constructor(accessToken) {
this.accessToken = accessToken;
this.pageToken = null;
}
async initialize() {
const response = await fetch(
'https://www.googleapis.com/drive/v3/changes/startPageToken',
{ headers: { 'Authorization': `Bearer ${this.accessToken}` }}
);
const data = await response.json();
this.pageToken = data.startPageToken;
console.log('Monitor inicializado con token:', this.pageToken);
}
async checkForChanges() {
if (!this.pageToken) {
await this.initialize();
}
const response = await fetch(
`https://www.googleapis.com/drive/v3/changes?pageToken=${this.pageToken}&includeRemoved=true`,
{ headers: { 'Authorization': `Bearer ${this.accessToken}` }}
);
const data = await response.json();
if (data.changes && data.changes.length > 0) {
console.log(`Detectados ${data.changes.length} cambios:`);
data.changes.forEach(change => {
if (change.removed) {
console.log(`❌ Archivo eliminado: ${change.fileId}`);
} else if (change.file) {
console.log(`📝 Archivo modificado: ${change.file.name}`);
}
});
}
// Actualizar el token para la próxima verificación
this.pageToken = data.newStartPageToken || data.nextPageToken;
return data.changes || [];
}
async startMonitoring(intervalMs = 30000) {
console.log('Iniciando monitoreo de cambios...');
await this.initialize();
setInterval(async () => {
await this.checkForChanges();
}, intervalMs);
}
}
// Uso
const monitor = new DriveChangeMonitor(accessToken);
await monitor.startMonitoring(30000); // Verificar cada 30 segundos
Ejemplo 5: Gestión de Carpetas Jerarquicas
Crea una estructura de carpetas organizada.
async function createFolderStructure(accessToken, structure, parentId = null) {
const results = {};
for (const [folderName, subfolders] of Object.entries(structure)) {
// Crear carpeta
const metadata = {
name: folderName,
mimeType: 'application/vnd.google-apps.folder'
};
if (parentId) {
metadata.parents = [parentId];
}
const response = await fetch(
'https://www.googleapis.com/drive/v3/files',
{
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(metadata)
}
);
const folder = await response.json();
results[folderName] = folder.id;
console.log(`✓ Carpeta creada: ${folderName}`);
// Crear subcarpetas recursivamente
if (subfolders && typeof subfolders === 'object') {
const subResults = await createFolderStructure(accessToken, subfolders, folder.id);
results[folderName] = { id: folder.id, children: subResults };
}
}
return results;
}
// Uso: Crear estructura de proyecto
const projectStructure = {
'Mi Proyecto': {
'Documentación': {
'API': {},
'Guías': {}
},
'Código': {
'Frontend': {},
'Backend': {}
},
'Recursos': {
'Imágenes': {},
'Videos': {}
}
}
};
const folderIds = await createFolderStructure(accessToken, projectStructure);
console.log('Estructura creada:', folderIds);