UrlFetchApp загружает файл multipart / form-data в Google Apps Script

Мне нужно загрузить файлы в стороннюю службу. Файлы создаются на Google Диске, и я получаю для них blob-данные.

Я хочу создать составной запрос, который теперь выглядит так, когда я выполняю UrlFetchApp Post.

Это полезная нагрузка в виде строки. У меня есть код, который генерирует полезную нагрузку. Проблема не в том, чтобы его правильно отформатировать, а в том, каким он должен быть.

-----------------0.13accb4c42d338
Content-Disposition: form-data; name="source"; filename="Zzapps.jpg"
Content-Type: application/octet-stream

[[[IMAGE DATA HERE -- OMITTED FOR BREVITY]]]

-----------------0.13accb4c42d338
Content-Disposition: form-data; name="filename"

Zzapps.jpg
-----------------0.13accb4c42d338--

Это фрагмент кода, который выполняет команду UrlFetchApp.

var authHeaders = {
   Authorization: 'OAuth2 '+access_token
}
 var params = {
    accept: "application/json",
    method: 'POST',
    payload: payload,
    contentType: 'multipart/form-data; boundary='+boundaryKey,
    headers: authHeaders,
    ContentLength: payload.length,
    muteHttpExceptions: true
}

var resx = UrlFetchApp.fetch (URL, параметры);

Принимающая сторона выдает ошибку (источник отсутствует). Я не уверен, что моя multipart-публикация в порядке, я не нахожу никаких тестовых URL-адресов, чтобы проверить, правильно ли я выполняю загрузку.

Как правильно отправить blob-данные как составную загрузку? А теперь использую blob.getDataAsString () ‹- это правильно?


person Riël    schedule 21.06.2014    source источник
comment
В подобной ситуации я начинаю с простейшего жестко запрограммированного кода, который могу заставить работать, а затем перехожу к этому. Постарайтесь сначала заставить работать что-нибудь простое. Вы смотрели стенограмму казни в поисках подсказок? Вы используете Logger.log () для проверки значений? Ваш объект params анализируется как объект? Если вы используете Logger.log ('params:' + params); вы должны увидеть [object: Object] как значение для params.   -  person Alan Wells    schedule 26.06.2014
comment
да. Я пытаюсь отправить жестко запрограммированный код, который работает. Я не вижу, чтобы сделать то, что нужно. Я ожидаю, что составной код будет строкой в ​​параметре params.payload?   -  person Riël    schedule 03.07.2014
comment
Я знаю, что может быть слишком поздно, но в этой статье - ctrlq.org / code / 20096-upload-files-multipart-post - парень прибил.   -  person a-change    schedule 24.10.2016
comment
Эта информация полезна в вашей ситуации? github.com/tanaikech/FetchApp   -  person Tanaike    schedule 22.04.2019


Ответы (1)


Если вы сами создаете строку полезной нагрузки, вам нужно выполнить blob.getBytes (), а не blob.getDataAsString ().

Однако есть способ попроще. Вместо того, чтобы самостоятельно создавать строку полезной нагрузки, вы можете просто установить объект javascript в качестве полезной нагрузки, и UrlFetchApp автоматически сгенерирует соответствующую строку полезной нагрузки, выберет правильный тип содержимого, границу и большинство других параметров. Просто используйте атрибут «name» полей ввода HTML-формы в качестве ключей объекта. Для файлов используйте большие двоичные объекты в качестве значений ключа.

function sendReportToSteve() {
  var url = "https://example.com/stevedore.html";
  var form = {
    date : new Date(),
    subject : "Happy birthday!",
    comment : "quakehashprismkeepkick",
    attachment1 : DriveApp.getFileById("sH1proy0lradArgravha9ikE").getBlob(),
    attachment2 : DriveApp.getFileById("traCetRacErI3hplVnkFax").getBlob()
  };
  uploadFile(url,form);
}

function uploadFile(url,form) {
  var options = {
    method : "POST",
    payload : form
  };
  var request = UrlFetchApp.getRequest(url,options);   // (OPTIONAL) generate the request so you
  console.info("Request payload: " + request.payload); // can examine it (useful for debugging)
  var response = UrlFetchApp.fetch(url,options);
  console.info("Response body: " + response.getContentText());
}
person browly    schedule 22.01.2019
comment
В моем случае у меня нет полей ввода HTML-формы. Я пытаюсь опубликовать метаданные электронной почты и rawContent электронной почты в следующем формате. {meta: {id, subject, date}, content: rawContent }. Как я могу добиться этого с помощью вышеупомянутого подхода? - person V.i.K.i; 02.04.2019
comment
@ V.i.K.i Я думаю, что UrlFetchApp может делать только HTTP-запросы. Насколько я понимаю, электронная почта отправляется по протоколу SMTP, а не по протоколу HTTP. Вместо UrlFetchApp попробуйте MailApp - person browly; 02.04.2019
comment
Извините, я не понял в своем предыдущем комментарии. Я не пытаюсь отправить письмо. Я пытаюсь сделать HTTP-запрос POST к стороннему API с полезной нагрузкой в ​​вышеупомянутом формате. Я вижу, что тип содержимого не установлен для этого должным образом. Прямо сейчас мне нужно вернуться к подходу, определенному на странице ctrlq.org/code/ 20096-загрузка-файлы-multipart-сообщение. Я хотел бы знать, сможем ли мы избежать этого, используя ваш подход. - person V.i.K.i; 03.04.2019
comment
@ V.i.K.i Я думаю, что UrlFetchApp может обрабатывать только один уровень объектов. Для подобъектов вы захотите закодировать как строку, которую ожидает ваш API (JSON, XML и т. Д.). Например, вы можете попробовать var options = {method : "POST", payload : {meta : JSON.stringify({id : 5, subject : "foo", date : "2018-10-05"}), content : rawContent} }. Вероятно, вы захотите использовать blob для rawContent. UrlFetchApp не знает, что делать с произвольным массивом байтов. - person browly; 03.04.2019