Как настроить создание прав доступа к файлу Google Sheets через Google Drive API v3 в 1С и исправить ошибку 400 Unsupported content?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Интеграция систем 1С с облачными сервисами Google (такими как Google Диск и Google Таблицы) — востребованная задача при автоматизации совместной работы, выгрузки отчетов и обмена данными. Однако при работе с REST API сторонних сервисов разработчики часто сталкиваются с неочевидными техническими нюансами. Одной из распространенных проблем является ошибка "HTTP 400 Bad Request" с пояснением "Unsupported content with type: application/octet-stream" при попытке создать новые права доступа (метод permissions.create).

В этой статье мы подробно разберем, почему возникает данная ошибка, как правильно составить HTTP-запрос в 1С, а также рассмотрим важные скрытые параметры Google Drive API v3, без которых интеграция может работать некорректно или вызывать сбои в бизнес-процессах.

Выясняем причину ошибки 400 Unsupported content

Давайте проанализируем ситуацию. При отправке POST-запроса к Google API для создания прав доступа мы передаем структурированные данные (тип прав, роль получателя, его e-mail) в формате JSON. В коде 1С для этого используется объект ЗаписьJSON, после чего сформированная строка помещается в тело запроса методом УстановитьТелоИзСтроки().

Однако по умолчанию платформа 1С при отправке запроса через объект HTTPСоединение не добавляет информацию о типе передаваемого контента. Веб-сервер Google, принимая этот запрос, не может автоматически определить формат данных и интерпретирует их как бинарный поток — application/octet-stream. Поскольку метод API ожидает строго JSON, сервер возвращает ошибку 400 Bad Request.

Для решения этой проблемы необходимо явно указать тип контента в заголовках HTTP-запроса. Для этого мы вставляем заголовок Content-Type со значением application/json в наше соответствие заголовков перед отправкой запроса:


Заголовки = Новый Соответствие;
Заголовки.Вставить("Authorization", "Bearer " + inAccessToken);
Заголовки.Вставить("Content-Type", "application/json"); // Явное указание формата данных

После добавления этого заголовка Google API успешно распознает тело запроса, и права доступа создаются. Однако это далеко не единственная сложность, с которой вы можете столкнуться. Ниже мы разберем еще 5 важнейших нюансов интеграции, которые уберегут вас от скрытых багов.

Важные нюансы настройки запроса к Google Drive API v3

Давайте рассмотрим по шагам неочевидные параметры и настройки, которые критически важны для стабильной работы обмена.

1. Исправление опечатки в параметре URL (fields вместо field)

В стандартном коде разработчики часто совершают опечатку, указывая в адресе запроса параметр получения ответа в единственном числе:

/drive/v3/files/<FileID>/permissions?field=*

В чем проблема: В спецификации Google API этот параметр называется во множественном числе — fields. Если написать его с ошибкой (field), Google проигнорирует некорректный параметр и вернет сокращенный стандартный ответ (содержащий только id, type и role). Если вашей системе в дальнейшем понадобятся другие возвращаемые данные (например, имя пользователя или адрес почты), вы их не получите.

Решение: Всегда указывайте fields=* для получения полной информации о созданных правах или перечисляйте конкретные поля через запятую (например, fields=id,emailAddress,role) для оптимизации трафика.

2. Отключение нежелательных email-уведомлений

По умолчанию при успешном предоставлении прав на файл Google Диск автоматически отправляет на почту получателя письмо-уведомление. Если ваша обработка в 1С пачками раздает права пользователям в фоновом режиме, это приведет к массовому спаму на почтовые ящики сотрудников или клиентов.

Решение: Используйте специальный query-параметр sendNotificationEmail=false в строке URL-запроса. Обратите внимание, что его нужно передавать именно в URL, а не в теле JSON-документа:

/drive/v3/files/<FileID>/permissions?sendNotificationEmail=false&fields=*

3. Поддержка Общих дисков (Shared Drives / Team Drives)

Если целевой файл Google Sheets создан не на вашем личном диске, а находится в общем корпоративном пространстве (Shared Drive), обычный запрос вернет ошибку 404 Not Found, даже если ID файла указан абсолютно верно.

Решение: Для обеспечения совместимости с общими дисками организации обязательно добавляйте в строку запроса параметр supportsAllDrives=true. Полный URL-путь запроса примет следующий вид:

/drive/v3/files/<FileID>/permissions?supportsAllDrives=true&sendNotificationEmail=false&fields=*

4. Настройка авторизации OAuth 2.0 (Scopes)

Для того чтобы метод создания прав успешно отрабатывал, ваш действующий access_token должен обладать достаточными правами доступа. Области доступа (scopes), ограничивающиеся только чтением или работой непосредственно с таблицами (например, https://www.googleapis.com/auth/spreadsheets), не подойдут. Google вернет ошибку доступа 403 Forbidden.

Убедитесь, что при генерации токена авторизации вы запрашиваете одну из следующих областей видимости:

5. Исключение проблем с кодировкой кириллицы

При получении ответа от сервера с помощью метода ПолучитьТелоКакСтроку() без явного указания кодировки русские символы (например, имена и фамилии пользователей в структуре ответа) могут отобразиться в виде нечитаемых символов ("кракозябр").

Решение: Всегда принудительно задавайте кодировку UTF-8 при чтении ответа сервера:

СтрокаОтвет = HTTPОтвет.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8);

Готовый шаблон функции на языке 1С

Объединим все вышеперечисленные исправления и лучшие практики в один готовый, универсальный и отказоустойчивый программный код, который вы можете использовать в своих обработках:


Функция ПредоставитьДоступКФайлуGoogle(Знач ТокенАвторизации, Знач ИДФайла, Знач EmailПолучателя, Знач РольДоступа = "reader", Знач ТипПолучателя = "user") Экспорт

    // 1. Настройка параметров подключения к API
    СерверГугл = "www.googleapis.com";
    SslПараметр = Новый ЗащищенноеСоединениеOpenSSL(Неопределено, Неопределено);
    Соединение = Новый HTTPСоединение(СерверГугл, , , , , 15, SslПараметр);
    
    // 2. Формирование заголовков запроса
    Заголовки = Новый Соответствие;
    Заголовки.Вставить("Authorization", "Bearer " + ТокенАвторизации);
    Заголовки.Вставить("Content-Type", "application/json"); // Исправление ошибки 400
    
    // 3. Формирование параметров запроса в URL
    // Отключаем email-уведомления, включаем поддержку общих дисков и запрашиваем полный ответ fields
    ПараметрыЗапроса = "sendNotificationEmail=false&supportsAllDrives=true&fields=*";
    ПутьЗапроса = "/drive/v3/files/" + ИДФайла + "/permissions?" + ПараметрыЗапроса;
    
    HTTPЗапрос = Новый HTTPЗапрос(ПутьЗапроса, Заголовки);
    
    // 4. Формирование JSON-тела запроса
    ТелоЗапроса = Новый Структура;
    ТелоЗапроса.Вставить("kind", "drive#permission");
    ТелоЗапроса.Вставить("type", ТипПолучателя);
    ТелоЗапроса.Вставить("role", РольДоступа);
    ТелоЗапроса.Вставить("emailAddress", EmailПолучателя);
    
    НастройкиСериализации = Новый НастройкиСериализацииJSON;
    НастройкиСериализации.ВариантЗаписиДаты = ВариантЗаписиДатыJSON.ЛокальнаяДатаСоСмещением;
    НастройкиСериализации.ФорматСериализацииДаты = ФорматДатыJSON.ISO;
    
    ЗаписьJSON = Новый ЗаписьJSON;
    ЗаписьJSON.УстановитьСтроку();
    ЗаписатьJSON(ЗаписьJSON, ТелоЗапроса, НастройкиСериализации);
    СтрJSON = ЗаписьJSON.Закрыть();
    
    HTTPЗапрос.УстановитьТелоИзСтроки(СтрJSON, КодировкаТекста.UTF8);
    
    // 5. Выполнение запроса и обработка результата
    Попытка
        HTTPОтвет = Соединение.ВызватьHTTPМетод("POST", HTTPЗапрос);
        СтрокаОтвет = HTTPОтвет.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8); // Защита от кракозябр
        
        Если HTTPОтвет.КодСостояния > 299 Тогда
            ВызватьИсключение "Ошибка API Google (Код " + HTTPОтвет.КодСостояния + "): " + СтрокаОтвет;
        КонецЕсли;
        
        Возврат СтрокаОтвет; // Возвращаем JSON-ответ с описанием созданных прав
        
    Исключение
        ЗаписьЖурналаРегистрации("Интеграция.GoogleDriveAPI",
            УровеньЖурналаРегистрации.Ошибка, , ,
            "Ошибка при предоставлении прав к файлу " + ИДФайла + ": " + ОписаниеОшибки());
            
        ВызватьИсключение;
    КонецПопытки;

КонецФункции

Используя данный шаблон, вы полностью застрахованы от ошибок форматирования контента, проблем с кодировками кириллицы в именах пользователей, спама на почтовые ящики клиентов и некорректной обработки файлов, находящихся на общих дисках вашей организации.

← На главную