UrlFetchApp: как имитировать HTTP-сообщение, у которого есть параметры с одинаковым именем несколько раз

В HTTP-запросе можно указать большинство параметров несколько раз, HTTP поддерживает это из коробки. Но как это сделать при использовании класса UrlFetchApp скрипта Google Apps?

Я пытаюсь отправить почту с помощью Mailgun API и хочу прикрепить несколько вложений. Вот что об этом говорит Mailgun API:

Обратите внимание, что вы можете указать большинство параметров несколько раз, HTTP поддерживает это из коробки. Это имеет смысл для таких параметров, как cc, to или attachment.

Вот еще несколько похожих вопросов, связанных с другими языками или платформами, но ни один из них не помогает:

Вот мой код, который работает с одним вложением. Обратите внимание, что функция mailgun () принимает те же аргументы, что и GmailApp.sendEmail () для единообразия:

function mailgun(recipient, subject, body, options){

var params = {
  "method":"POST",
  "headers": {
    "Authorization" : "Basic " + Utilities.base64Encode('api:key-goes-here')
  },
  "payload": {
    "to": recipient,
    "subject": subject,
    "text": body,
    "html": options.htmlBody
  },
  "muteHttpExceptions": true,
};

if(options.hasOwnProperty("bcc"))
  params.payload.bcc = options.bcc;

if(options.hasOwnProperty("cc"))
  params.payload.cc = options.cc;

if(options.hasOwnProperty("replyTo"))
  params.payload['h:Reply-To'] = options.replyTo;

if(options.hasOwnProperty("name")){
  params.payload.from = options.name + ' <' + options.from + '>';
} else {
  params.payload.from = options.from;
}

if(options.hasOwnProperty("attachments")){
  params.payload.attachment = options.attachments[0];
}

var response = UrlFetchApp.fetch('https://api.mailgun.net/v3/domain.com/messages', params);
var responseCode = response.getResponseCode();
var responseObj = JSON.parse(response.getContentText());

if(responseCode != 200) return 'Mailgun error: '+responseObj.message;  

return true;

}

Если я использую этот код, почта проходит, но без вложений:

if(options.hasOwnProperty("attachments")){
  params.payload.attachment = [options.attachments[0],
                               options.attachments[1]
                              ];
}

API Mailgun говорит: «Вы можете публиковать несколько значений вложений». Это немного вводит в заблуждение, поскольку по сути они означают, что «вы можете указать параметр вложения несколько раз» для отправки нескольких вложений.

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

Это запрос Curl, который работает. Необходимо подражать этому с помощью urlFetch:

curl -s --user 'api:key-goes-here' \
https://api.mailgun.net/v3/domain.com/messages \
-F from='Support <[email protected]>' \
-F [email protected] \
-F subject='Hello' \
-F text='Testing some Mailgun awesomness!' \
-F attachment='@image.png' \
-F attachment='@license.txt' \

person Akshay Raje    schedule 03.02.2017    source источник
comment
Добавьте свой код, показывающий успешную тестовую отправку с 1 вложением.   -  person Peter H    schedule 03.02.2017
comment
@PeterHerrmann Я отредактировал свой вопрос своим текущим кодом, который работает только для первого вложения   -  person Akshay Raje    schedule 03.02.2017
comment
Пример завитка идеален. Отредактируйте свой пример Urlfetch и замените его воспроизводимой жестко закодированной (упрощенной) версией, показывающей пройденный (1 вложение) и неудачный (2 вложения).   -  person Peter H    schedule 06.02.2017
comment
Я разместил более подробную версию этого вопроса здесь: stackoverflow.com/questions/42050972/, к сожалению, он признан дублирующимся. Вы можете перейти по ссылке для получения более подробной информации.   -  person Akshay Raje    schedule 06.02.2017
comment
@AkshayRaje, вы придумали решение для этого?   -  person Jack Brown    schedule 15.04.2020
comment
@JackBrown, теперь, когда я снова смотрю на это, вы можете использовать FormData (developers.google.com/apps-script/reference/url-fetch/) и передать ему массив (stackoverflow.com/questions/16104078/) . Надеюсь это поможет!   -  person Akshay Raje    schedule 15.04.2020
comment
@akshay_raje благодарит за ответ. К сожалению, я пробовал их, и только одно вложение проходит, когда я передаю два ключа с одинаковым именем, и ни одно не проходит, если я передаю массив файловых блобов во вложение ключа. Но если вы еще предложения, я все уши!   -  person Jack Brown    schedule 15.04.2020


Ответы (1)


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

function jsonToUrlencoded(obj) {
  var str = [];
  for (var key in obj) {
    if (obj.hasOwnProperty(key)) {
      if (Array.isArray(obj[key])) {
        for (var i=0;i<obj[key].length;i++) {
          str.push(encodeURIComponent(key) + "=" + encodeURIComponent(obj[key][i]));
        }
      } else {
        str.push(encodeURIComponent(key) + "=" + encodeURIComponent(obj[key]));
      }
    }
  }
  return str.join("&");
}
person Fabio Lucchini    schedule 19.10.2019