Google Apps Script: Как получить изображение с Google Диска?

Что такое Google Apps Script и его возможности

Google Apps Script (GAS) — это облачная платформа для разработки на JavaScript, которая позволяет расширять функциональность приложений Google Workspace (Документы, Таблицы, Диск, Gmail и др.) и автоматизировать рабочие процессы. Она предоставляет удобный способ взаимодействия между различными сервисами Google.

Обзор Google Drive API и его роли в управлении файлами

Google Drive API — это набор методов для программного взаимодействия с файлами и папками на Google Диске. Он позволяет создавать, читать, изменять, удалять файлы, управлять правами доступа и, что важно для нашей задачи, получать содержимое файлов, включая изображения.

Необходимость получения изображений с Google Диска через Apps Script

Часто возникает потребность динамически вставлять изображения из Google Диска в документы, таблицы, презентации или отображать их в веб-приложениях, созданных с помощью HTML Service. Apps Script в связке с Drive API предоставляет эффективный механизм для решения таких задач без необходимости ручного скачивания и загрузки.

Авторизация и настройка доступа к Google Диску

Включение Drive API в проекте Google Apps Script

Для взаимодействия с Google Диском через Apps Script необходимо явно включить Drive API (или Advanced Drive Service). Это делается в редакторе скриптов:

  1. Откройте проект Apps Script.
  2. Перейдите в раздел Сервисы.
  3. Найдите Drive API и нажмите Добавить.

Примечание: При первом запуске скрипта, использующего Drive API, потребуется авторизация пользователя.

Получение идентификатора файла изображения на Google Диске

Каждый файл на Google Диске имеет уникальный идентификатор (ID). Его можно найти в URL файла при открытии его в браузере. Например, в URL https://drive.google.com/file/d/1aBcDeFgHiJkLmNoPqRsTuVwXyZaBcDeF/view идентификатором является 1aBcDeFgHiJkLmNoPqRsTuVwXyZaBcDeF.

Этот ID используется для прямого доступа к файлу через скрипт.

Настройка прав доступа к файлу (если требуется)

Скрипт выполняется от имени пользователя, который его авторизовал. Поэтому для успешного получения файла скриптом у этого пользователя должны быть права на чтение файла изображения. Если скрипт предназначен для использования другими пользователями (например, как веб-приложение), убедитесь, что файл доступен им, или настройте соответствующие права доступа программно (используя File.setSharing() или методы Drive API).

Получение изображения с Google Диска с использованием Apps Script

Использование DriveApp для доступа к файлу

Базовый сервис DriveApp предоставляет простые методы для работы с файлами. Для получения файла по его ID используется метод DriveApp.getFileById(fileId).

/**
 * Получает объект файла с Google Диска по его идентификатору.
 *
 * @param {string} fileId Идентификатор файла на Google Диске.
 * @returns {GoogleAppsScript.Drive.File | null} Объект файла или null, если файл не найден.
 */
function getDriveFileById(fileId: string): GoogleAppsScript.Drive.File | null {
  try {
    const file: GoogleAppsScript.Drive.File = DriveApp.getFileById(fileId);
    return file;
  } catch (e) {
    Logger.log(`Ошибка получения файла ${fileId}: ${e}`);
    return null;
  }
}

Получение данных изображения (Blob) как объекта

После получения объекта File необходимо извлечь его содержимое в виде Blob (Binary Large Object). Это универсальный контейнер для данных файла.

/**
 * Получает Blob изображения из объекта файла Google Диска.
 *
 * @param {GoogleAppsScript.Drive.File} file Объект файла Google Диска.
 * @returns {GoogleAppsScript.Base.Blob | null} Blob изображения или null при ошибке.
 */
function getImageBlob(file: GoogleAppsScript.Drive.File): GoogleAppsScript.Base.Blob | null {
  try {
    // Проверяем MIME-тип, чтобы убедиться, что это изображение (опционально)
    const mimeType: string = file.getMimeType();
    if (mimeType && mimeType.startsWith('image/')) {
      const blob: GoogleAppsScript.Base.Blob = file.getBlob();
      return blob;
    }
    Logger.log(`Файл ${file.getId()} не является изображением (${mimeType}).`);
    return null;
  } catch (e) {
    Logger.log(`Ошибка получения Blob для файла ${file.getId()}: ${e}`);
    return null;
  }
}

Преобразование Blob в URL для вставки в документ или веб-страницу

Blob можно преобразовать в строку формата Base64 Data URL. Этот формат позволяет встраивать данные изображения непосредственно в HTML или другие документы.

/**
 * Преобразует Blob изображения в строку Base64 Data URL.
 *
 * @param {GoogleAppsScript.Base.Blob} imageBlob Blob изображения.
 * @returns {string | null} Строка Data URL (например, "data:image/png;base64,...") или null при ошибке.
 */
function convertBlobToDataUrl(imageBlob: GoogleAppsScript.Base.Blob): string | null {
  try {
    const contentType: string = imageBlob.getContentType();
    const base64Data: string = Utilities.base64Encode(imageBlob.getBytes());
    const dataUrl: string = `data:${contentType};base64,${base64Data}`;
    return dataUrl;
  } catch (e) {
    Logger.log(`Ошибка преобразования Blob в Data URL: ${e}`);
    return null;
  }
}

Примеры кода и практическое применение

Пример скрипта для получения изображения и вставки в Google Doc

/**
 * Вставляет изображение с Google Диска в активный Google Документ.
 *
 * @param {string} imageFileId Идентификатор файла изображения на Google Диске.
 */
function insertImageFromDriveToDoc(imageFileId: string): void {
  const doc: GoogleAppsScript.Document.Document = DocumentApp.getActiveDocument();
  const body: GoogleAppsScript.Document.Body = doc.getBody();

  const file: GoogleAppsScript.Drive.File | null = getDriveFileById(imageFileId);
  if (!file) {
    Logger.log(`Файл с ID ${imageFileId} не найден или доступ запрещен.`);
    DocumentApp.getUi().alert('Не удалось найти изображение.');
    return;
  }

  const imageBlob: GoogleAppsScript.Base.Blob | null = getImageBlob(file);
  if (!imageBlob) {
    Logger.log(`Не удалось получить Blob для файла ${imageFileId}.`);
    DocumentApp.getUi().alert('Не удалось обработать изображение.');
    return;
  }

  try {
    // Вставляем изображение в начало документа
    body.insertImage(0, imageBlob);
    Logger.log(`Изображение ${imageFileId} успешно вставлено в документ.`);
  } catch (e) {
    Logger.log(`Ошибка вставки изображения ${imageFileId} в документ: ${e}`);
    DocumentApp.getUi().alert(`Ошибка вставки изображения: ${e.message}`);
  }
}

// Пример вызова
function testInsertImage() {
  const MY_IMAGE_ID = 'YOUR_IMAGE_FILE_ID_HERE'; // Замените на реальный ID
  insertImageFromDriveToDoc(MY_IMAGE_ID);
}

// Функции getDriveFileById и getImageBlob должны быть определены в проекте
Реклама

Пример скрипта для отображения изображения на веб-странице (HTML Service)

Код Apps Script (Code.gs):

/**
 * Обслуживает GET-запросы, отображая HTML-страницу.
 *
 * @returns {GoogleAppsScript.HTML.HtmlOutput} HTML-вывод для отображения.
 */
function doGet(): GoogleAppsScript.HTML.HtmlOutput {
  return HtmlService.createTemplateFromFile('Index').evaluate()
    .setTitle('Изображение с Диска');
}

/**
 * Получает Data URL изображения для передачи в HTML-шаблон.
 *
 * @param {string} imageFileId Идентификатор файла изображения на Google Диске.
 * @returns {string | null} Строка Data URL или null при ошибке.
 */
function getImageDataUrl(imageFileId: string): string | null {
  const file: GoogleAppsScript.Drive.File | null = getDriveFileById(imageFileId);
  if (!file) {
    return null;
  }
  const imageBlob: GoogleAppsScript.Base.Blob | null = getImageBlob(file);
  if (!imageBlob) {
    return null;
  }
  return convertBlobToDataUrl(imageBlob);
}

// Функции getDriveFileById, getImageBlob, convertBlobToDataUrl должны быть определены

HTML-шаблон (Index.html):

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    <h1>Изображение с Google Диска</h1>
    <? var imageId = 'YOUR_IMAGE_FILE_ID_HERE'; // Замените на ID вашего изображения ?>
    <? var imageUrl = getImageDataUrl(imageId); ?>

    <? if (imageUrl) { ?>
      <img src="<?= imageUrl ?>" alt="Изображение с Диска" style="max-width: 100%; height: auto;" />
    <? } else { ?>
      <p>Не удалось загрузить изображение.</p>
    <? } ?>
  </body>
</html>

Обработка ошибок и исключений (например, файл не найден)

Крайне важно включать блоки try...catch для обработки потенциальных ошибок:

  • Файл не найден (неверный ID).
  • Отсутствие прав доступа у пользователя, выполняющего скрипт.
  • Превышение квот Google Apps Script (например, по времени выполнения или размеру данных).
  • Файл не является изображением.

Логирование ошибок (Logger.log) помогает при отладке, а уведомления пользователю (DocumentApp.getUi().alert() или вывод сообщений в HTML) улучшают пользовательский опыт.

Альтернативные методы и оптимизация

Использование Advanced Drive Service для расширенных возможностей

Advanced Drive Service (включается отдельно в Ресурсы > Дополнительные сервисы Google) предоставляет прямой доступ к Google Drive API v2 или v3. Это может быть полезно для более сложных операций, таких как получение метаданных файла, использование полей для частичного ответа (fields) или получение временных ссылок на скачивание (webContentLink), хотя последние менее надежны для встраивания.

/**
 * Получает файл с использованием Advanced Drive Service (v3).
 * Требует включения 'Drive API' в Дополнительных сервисах Google.
 *
 * @param {string} fileId Идентификатор файла.
 * @returns {object | null} Объект файла Drive API v3 или null при ошибке.
 */
function getFileWithAdvancedService(fileId: string): object | null {
  try {
    // Запрашиваем только ID и MIME-тип для примера
    const fileMetadata = Drive.Files.get(fileId, { fields: 'id, mimeType, name' });
    Logger.log('Метаданные файла: %s', JSON.stringify(fileMetadata));
    // Для получения контента используются другие методы или параметры
    return fileMetadata;
  } catch (e) {
    Logger.log(`Ошибка Advanced Drive Service при получении файла ${fileId}: ${e}`);
    return null;
  }
}

Кэширование изображений для повышения производительности

Если одно и то же изображение запрашивается часто, его Data URL можно кэшировать с помощью CacheService. Это снизит количество обращений к Drive API и ускорит работу скрипта.

/**
 * Получает Data URL изображения, используя кэш.
 *
 * @param {string} imageFileId Идентификатор файла изображения.
 * @param {number} expirationInSeconds Время жизни кэша в секундах (макс. 21600).
 * @returns {string | null} Data URL из кэша или полученный с Диска.
 */
function getCachedImageDataUrl(imageFileId: string, expirationInSeconds: number = 3600): string | null {
  const cache: GoogleAppsScript.Cache.Cache = CacheService.getScriptCache();
  const cacheKey: string = `imageDataUrl_${imageFileId}`;

  const cachedUrl: string | null = cache.get(cacheKey);
  if (cachedUrl) {
    Logger.log(`Data URL для ${imageFileId} взят из кэша.`);
    return cachedUrl;
  }

  const dataUrl: string | null = getImageDataUrl(imageFileId); // Используем ранее определенную функцию
  if (dataUrl) {
    cache.put(cacheKey, dataUrl, Math.min(expirationInSeconds, 21600)); // Ограничение GAS - 6 часов
    Logger.log(`Data URL для ${imageFileId} сохранен в кэш.`);
  }

  return dataUrl;
}

Оптимизация размера изображения перед получением (если необходимо)

Google Apps Script имеет ограничения на размер обрабатываемых данных и время выполнения. Если вы работаете с очень большими изображениями, а для отображения нужна уменьшенная копия, стандартные средства DriveApp или Drive API не предоставляют встроенных функций для изменения размера изображения перед его получением в виде Blob. Оптимизацию (изменение размера) придется выполнять либо:

  1. Вручную: Заранее подготовить на Диске версии изображений нужного размера.
  2. Сторонние сервисы/API: Передать изображение (или ссылку на него) внешнему сервису для обработки, что усложняет архитектуру.
  3. На клиенте (HTML Service): Загрузить полное изображение и масштабировать средствами CSS/JavaScript, что не экономит трафик и ресурсы сервера GAS.

Для большинства задач достаточно получения исходного Blob и его использования.


Добавить комментарий