Google Apps Script (GAS) представляет собой мощную платформу для автоматизации задач в экосистеме Google Workspace, включая Google Диск. Загрузка файлов — одна из частых операций, которую можно эффективно автоматизировать с помощью скриптов.
Что такое Google Apps Script и его преимущества для автоматизации Google Диска
Google Apps Script — это облачная скриптовая платформа на базе JavaScript, позволяющая расширять функциональность приложений Google Workspace (Диск, Таблицы, Документы, Gmail и др.). Ключевые преимущества для работы с Google Диском:
Автоматизация рутинных задач: Загрузка отчетов, резервное копирование данных, организация файлов.
Интеграция с другими сервисами Google: Возможность получать данные из Таблиц, Почты или Календаря и сохранять их на Диске.
Работа по расписанию: Использование триггеров для запуска скриптов в определенное время или при наступлении событий.
Кастомизация: Создание собственных рабочих процессов для управления файлами и папками.
Необходимые условия: доступ к Google Диску и знание JavaScript
Для работы со скриптами загрузки файлов вам потребуется:
Аккаунт Google: С доступом к Google Диску.
Базовые знания JavaScript: Понимание синтаксиса, переменных, функций, объектов и желательно асинхронных операций.
Редактор скриптов Google Apps Script: Доступен из любого приложения Google Workspace (например, через Инструменты -> Редактор скриптов в Google Таблицах) или напрямую по адресу script.google.com.
Обзор основных объектов Google Apps Script для работы с Google Диском (DriveApp, Blob)
Для взаимодействия с Google Диском через GAS используются встроенные сервисы и объекты:
DriveApp: Основной сервис для работы с файлами и папками на Google Диске. Предоставляет методы для получения доступа к файлам/папкам, создания, перемещения, удаления и управления правами доступа.
Blob (Binary Large Object): Объект, представляющий собой набор двоичных данных. Файлы в GAS часто представляются или преобразуются в объекты Blob перед загрузкой или обработкой. Blob содержит сами данные, их тип (MIME type) и имя.
Простой скрипт для загрузки файла на Google Диск
Рассмотрим базовый сценарий: создание текстового файла с определенным содержимым в корневой папке Диска.
Получение доступа к Google Диску с помощью DriveApp.getRootFolder()
Метод DriveApp.getRootFolder() возвращает объект Folder, представляющий корневую папку Диска текущего пользователя. Это отправная точка для навигации по структуре папок или для создания файлов/папок верхнего уровня.
Создание Blob (Binary Large Object) из файла (например, из Google Sheets)
Объект Blob можно создать из различных источников. Один из распространенных способов — из строки. Например, если мы хотим сохранить данные отчета из скрипта в текстовый файл.
/**
* Создает Blob из строки текста.
* @param {string} content Текстовое содержимое для Blob.
* @param {string} fileName Имя будущего файла.
* @returns {GoogleAppsScript.Base.Blob} Созданный Blob.
*/
function createTextBlob(content: string, fileName: string): GoogleAppsScript.Base.Blob {
// Utilities.newBlob() создает Blob из строки, указывая тип контента и имя
const textBlob: GoogleAppsScript.Base.Blob = Utilities.newBlob(content, MimeType.PLAIN_TEXT, fileName);
// MimeType.PLAIN_TEXT - это 'text/plain'
return textBlob;
}Загрузка Blob на Google Диск с помощью DriveApp.createFile(blob)
Метод createFile(blob) объекта Folder (полученного, например, через getRootFolder() или getFolderById()) принимает Blob и создает на его основе новый файл в этой папке.
/**
* Загружает текстовый файл в корневую папку Google Диска.
* @param {string} fileName Имя файла.
* @param {string} fileContent Содержимое файла.
* @returns {GoogleAppsScript.Drive.File | null} Объект созданного файла или null при ошибке.
*/
function uploadTextFileToRoot(fileName: string, fileContent: string): GoogleAppsScript.Drive.File | null {
try {
// Получаем корневую папку
const rootFolder: GoogleAppsScript.Drive.Folder = DriveApp.getRootFolder();
// Создаем Blob из содержимого
const reportBlob: GoogleAppsScript.Base.Blob = Utilities.newBlob(fileContent, MimeType.PLAIN_TEXT, fileName);
// Создаем файл в корневой папке
const file: GoogleAppsScript.Drive.File = rootFolder.createFile(reportBlob);
Logger.log(`Файл '${file.getName()}' (ID: ${file.getId()}) успешно загружен в корневую папку.`);
return file;
} catch (error) {
// Логируем ошибку
Logger.log(`Ошибка при загрузке файла '${fileName}': ${error}`);
return null;
}
}
// Пример вызова функции
function runSimpleUpload() {
const reportData: string = "Данные по кликам за Q3:\nИсточник,Клики\nGoogle Ads,1500\nDirect,800";
uploadTextFileToRoot("marketing_report_q3.txt", reportData);
}Обработка ошибок и логирование загрузки
Как видно из примера выше, использование блока try...catch является обязательным для обработки потенциальных проблем (например, отсутствие прав доступа, ошибки сети, превышение квот). Logger.log() или console.log() используются для записи информации о ходе выполнения скрипта и возможных ошибках, что критически важно для отладки.
Загрузка файлов из других источников (URL, локальный файл)
GAS позволяет загружать файлы не только из сгенерированных данных, но и из внешних источников.
Загрузка файла по URL с помощью UrlFetchApp.fetch()
Сервис UrlFetchApp позволяет скриптам получать доступ к ресурсам в Интернете. Метод fetch(url) отправляет запрос по указанному URL.
Преобразование содержимого URL в Blob
Результат UrlFetchApp.fetch() — это объект HTTPResponse. У него есть метод getBlob(), который напрямую возвращает содержимое ответа в виде Blob, готового к загрузке на Диск.
Загрузка файла на Google Диск и назначение имени файла
Полученный Blob можно сразу использовать с folder.createFile(blob). Имя файла можно установить для Blob с помощью метода setName(filename) перед созданием файла на Диске.
/**
* Загружает файл по URL в указанную папку Google Диска.
* @param {string} fileUrl URL файла для загрузки (например, изображение или CSV).
* @param {string} destinationFolderId ID папки назначения на Google Диске.
* @param {string} newFileName Желаемое имя для сохраняемого файла.
* @returns {GoogleAppsScript.Drive.File | null} Загруженный файл или null в случае ошибки.
*/
function uploadFileFromUrlToFolder(fileUrl: string, destinationFolderId: string, newFileName: string): GoogleAppsScript.Drive.File | null {
try {
const folder: GoogleAppsScript.Drive.Folder = DriveApp.getFolderById(destinationFolderId);
if (!folder) {
Logger.log(`Папка с ID '${destinationFolderId}' не найдена.`);
return null;
}
// Получаем содержимое по URL
const response: GoogleAppsScript.URL_Fetch.HTTPResponse = UrlFetchApp.fetch(fileUrl);
const fileBlob: GoogleAppsScript.Base.Blob = response.getBlob();
// Устанавливаем имя файла для Blob
fileBlob.setName(newFileName);
// Создаем файл в указанной папке
const file: GoogleAppsScript.Drive.File = folder.createFile(fileBlob);
Logger.log(`Файл '${file.getName()}' (ID: ${file.getId()}) успешно загружен из URL в папку '${folder.getName()}'.`);
return file;
} catch (error) {
// Обработка ошибок сети или доступа к папке
Logger.log(`Ошибка при загрузке файла из URL '${fileUrl}' в папку ID '${destinationFolderId}': ${error}`);
return null;
}
}
// Пример вызова: загрузка логотипа Google в папку
function runUrlUpload() {
const imageUrl: string = "https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png";
const targetFolderId: string = "YOUR_FOLDER_ID_HERE"; // Замените на реальный ID папки
if (targetFolderId === "YOUR_FOLDER_ID_HERE") {
Logger.log("Пожалуйста, укажите ID папки назначения в функции runUrlUpload.");
return;
}
uploadFileFromUrlToFolder(imageUrl, targetFolderId, "google_logo.png");
}Особенности загрузки локальных файлов: использование HTML-формы и doGet/doPost
Прямая загрузка локальных файлов с компьютера пользователя невозможна из серверного скрипта GAS по соображениям безопасности. Этот процесс требует создания веб-приложения с помощью HTML Service:
doGet(e): Функция, которая вызывается при GET-запросе к веб-приложению и обычно отображает HTML-форму (<input type="file">).
HTML/JavaScript (Клиентская сторона): Пользователь выбирает файл. JavaScript на стороне клиента читает файл (часто как Base64 строку) и отправляет его на сервер с помощью google.script.run.
doPost(e) или пользовательская функция: Функция на стороне GAS (сервер), которая получает данные файла (например, Base64 строку и MIME-тип), декодирует их, создает Blob (Utilities.newBlob(Utilities.base64Decode(data), mimeType, fileName)) и загружает на Диск с помощью DriveApp.createFile().
Этот механизм значительно сложнее прямых серверных загрузок и выходит за рамки простого примера.
Расширенные возможности: папки, метаданные, права доступа
Загрузка файлов в определенную папку (DriveApp.getFolderById())
Вместо DriveApp.getRootFolder() используйте DriveApp.getFolderById(folderId) для получения объекта конкретной папки по её уникальному идентификатору (ID можно найти в URL папки на Google Диске). Затем используйте метод createFile() этого объекта папки.
/**
* Загружает Blob в папку с указанным ID.
* @param {GoogleAppsScript.Base.Blob} blob Blob для загрузки.
* @param {string} folderId ID папки назначения.
* @returns {GoogleAppsScript.Drive.File | null} Загруженный файл или null при ошибке.
*/
function uploadBlobToFolder(blob: GoogleAppsScript.Base.Blob, folderId: string): GoogleAppsScript.Drive.File | null {
try {
const folder: GoogleAppsScript.Drive.Folder = DriveApp.getFolderById(folderId);
const file: GoogleAppsScript.Drive.File = folder.createFile(blob);
Logger.log(`Файл '${blob.getName()}' загружен в папку '${folder.getName()}'.`);
return file;
} catch (error) {
Logger.log(`Ошибка загрузки в папку ID '${folderId}': ${error}`);
return null;
}
}Установка метаданных файла (описание, теги)
После создания файла (File) можно установить его метаданные. Наиболее часто используется setDescription(description).
/**
* Загружает файл и устанавливает ему описание.
* @param {GoogleAppsScript.Base.Blob} blob Blob файла.
* @param {string} folderId ID папки назначения.
* @param {string} description Описание файла.
* @returns {GoogleAppsScript.Drive.File | null} Файл с установленным описанием или null.
*/
function uploadFileWithDescription(
blob: GoogleAppsScript.Base.Blob,
folderId: string,
description: string
): GoogleAppsScript.Drive.File | null {
const file = uploadBlobToFolder(blob, folderId);
if (file) {
try {
file.setDescription(description);
Logger.log(`Описание для файла '${file.getName()}' установлено.`);
return file;
} catch (error) {
Logger.log(`Не удалось установить описание для файла '${file.getName()}': ${error}`);
// Возвращаем файл, даже если описание не установилось
return file;
}
}
return null;
}Прямой поддержки тегов (labels), как в Gmail, в Drive API и DriveApp нет. Организацию можно реализовать через структуру папок или добавляя информацию в описание или имя файла.
Управление правами доступа к загруженным файлам (setSharing, setViewers, setEditors)
Объект File имеет методы для управления доступом:
addViewer(emailAddress) / addViewers(emailAddresses): Предоставить доступ на просмотр.
addEditor(emailAddress) / addEditors(emailAddresses): Предоставить доступ на редактирование.
removeViewer(emailAddress) / removeEditor(emailAddress): Отозвать доступ.
setSharing(accessType, permissionType): Установить общие настройки доступа (например, доступ по ссылке).
DriveApp.Access.ANYONE_WITH_LINK: Доступен всем, у кого есть ссылка.
DriveApp.Access.DOMAIN_WITH_LINK: Доступен пользователям домена, у кого есть ссылка.
DriveApp.Permission.VIEW: Только просмотр.
DriveApp.Permission.EDIT: Редактирование.
/**
* Загружает файл и предоставляет доступ указанным пользователям.
* @param {GoogleAppsScript.Base.Blob} blob Blob файла.
* @param {string} folderId ID папки назначения.
* @param {string[]} viewerEmails Массив email адресов для доступа на чтение.
* @param {string[]} editorEmails Массив email адресов для доступа на редактирование.
*/
function uploadAndShareFile(
blob: GoogleAppsScript.Base.Blob,
folderId: string,
viewerEmails: string[],
editorEmails: string[]
): void {
const file = uploadBlobToFolder(blob, folderId);
if (file) {
try {
if (viewerEmails && viewerEmails.length > 0) {
file.addViewers(viewerEmails);
Logger.log(`Доступ на чтение предоставлен: ${viewerEmails.join(', ')}`);
}
if (editorEmails && editorEmails.length > 0) {
file.addEditors(editorEmails);
Logger.log(`Доступ на редактирование предоставлен: ${editorEmails.join(', ')}`);
}
// Пример установки доступа по ссылке для домена (если применимо)
// file.setSharing(DriveApp.Access.DOMAIN_WITH_LINK, DriveApp.Permission.VIEW);
} catch (error) {
Logger.log(`Ошибка при установке прав доступа для файла '${file.getName()}': ${error}`);
}
}
}Примеры использования и решения типичных проблем
Автоматическая загрузка данных из Google Sheets на Google Диск по расписанию (триггеры)
Частый кейс: ежедневное или еженедельное сохранение данных из Google Таблицы в CSV файл на Диске.
Напишите функцию, которая читает данные из листа (SpreadsheetApp.getActiveSpreadsheet().getSheetByName(...)), форматирует их как CSV строку и использует uploadBlobToFolder для сохранения.
В редакторе скриптов перейдите в раздел "Триггеры" (значок будильника).
Создайте новый триггер:
Выберите функцию для запуска (вашу функцию сохранения).
Выберите источник события: Время.
Настройте тип триггера (например, Таймер по дням) и время срабатывания.
Загрузка нескольких файлов одновременно: оптимизация скрипта
Если нужно загрузить много файлов (например, из массива данных), избегайте вызова DriveApp методов в цикле без необходимости. Сгруппируйте данные, если возможно. Если файлы независимы, последовательная загрузка в цикле является стандартным подходом. Убедитесь, что общее время выполнения не превысит лимиты GAS.
Обработка больших файлов: chunked upload и лимиты Google Apps Script
Google Apps Script имеет ограничения:
Максимальный размер Blob: 50 МБ.
Максимальное время выполнения скрипта: 6 минут для обычных аккаунтов, 30 минут для Google Workspace.
Для файлов больше 50 МБ DriveApp не подходит. Необходимо использовать Advanced Drive API (требует включения в редакторе скриптов: Сервисы -> Drive API). Он позволяет выполнять так называемую "resumable upload" (возобновляемую загрузку), которая разбивает файл на части (chunks) и загружает их последовательно. Это более сложный процесс, требующий прямого взаимодействия с Google Drive REST API через UrlFetchApp с соответствующими заголовками и обработкой сессий загрузки.
Решение распространенных ошибок при загрузке файлов и советы по отладке
Exception: Access denied: DriveApp.: Скрипту не хватает прав. Убедитесь, что при авторизации скрипта вы предоставили разрешение на доступ к Google Диску. Иногда требуется явно добавить нужные области (scopes) в манифест (appsscript.json).
Exception: File not found или Folder not found: Неверный ID файла или папки. Перепроверьте ID.
Limit Exceeded: Drive: Превышены суточные квоты на операции с Drive API (количество вызовов, объем данных). Оптимизируйте скрипт, добавьте паузы (Utilities.sleep()) или используйте Advanced Drive API, который имеет более высокие лимиты.
Тайм-аут выполнения: Скрипт работает дольше 6/30 минут. Оптимизируйте код, разбейте задачу на части, используйте триггеры для продолжения работы или пересмотрите архитектуру (например, для больших файлов -> Advanced Drive API).
Отладка:
Используйте Logger.log() или console.log() обильно для отслеживания значений переменных и шагов выполнения.
Запускайте функции по частям из редактора для проверки.
Используйте встроенный отладчик (значок жука) для пошагового выполнения и проверки переменных.
Проверяйте логи выполнения в разделе "Выполнения" редактора скриптов.