Как создать веб-перехватчик из скрипта Google Apps, используя URL-адрес exec, а не URL-адрес разработчика. Exec возвращает ошибку 403

Была попытка настроить веб-перехватчик в Google Sheets Apps Script, который будет реагировать на изменения, внесенные в Trello. Для этого предлагается развернуть сценарий как веб-приложение (требующее функций doGet и doPost, возвращающих HTML), чтобы создать целевой URL-адрес для получения запросов post и get.

Веб-приложение создает два URL-адреса, один заканчивается на /dev и предназначен для целей разработки (не отвечает на post запросы), а другой заканчивается на /exec для обычного доступа.

Я развернул веб-приложение, оба URL-адреса доступны и реагируют в моем браузере (можно просматривать exec в инкогнито без входа в систему), приложение опубликовано для выполнения как «я» и будет доступно «любому, даже анонимному».

Мне удалось успешно использовать приведенный ниже код для создания веб-перехватчиков для URL /dev, но не для URL /exec.

function create() {
  var url = 'https://api.trello.com/1/tokens/ae6ebe60b45abcd2d4aa945c9ab4c4571bd6b6f7856b1df0cd387fbffc649579/webhooks/?key=a211f4aca7fb3e521d652730dd231cb6'

  var payload = { 
    "key": "xxxxxxxxxxx",
    "token" : "xxxxxxxxxxxxx",
    "callbackURL": "https://script.google.com/macros/s/AKfycbw51TYGWHe95hKdcAs4l7E2eg0AtBi8e48lf_iafKYI/dev",
    "idModel":"xxxxxxxx",
    "description": "GW Test"  
  }
  var options = {"method" : "post",
                 "payload" : payload,
                 "muteHttpExceptions": true
                 };

  var response = UrlFetchApp.fetch(url,options);
}

При использовании URL /dev я вижу, что в мой Trello добавлен новый веб-крючок, но URL /exec возвращает следующую ошибку:

{"message": "URL (https://script.google.com/macros/s/AKfycbxo90ucgXXz7MG6Z3wb2KD-PJn3akGKoelXLJ2mkg/exec) не вернул код состояния 200, получил 403 "," error ":" ERROR "}

Таким образом, Trello ожидал, что будет возвращен «код состояния 200», чтобы убедиться, что скрипт работает правильно, но вместо этого получил 403. Меня смущает то, почему этого не происходит при использовании /dev? Как я могу заставить его принять мой /exec URL?

Больше информации:

Я могу заставить свой код отвечать на запросы put и get, когда я использую ссылку или загружаю URL-адрес прямо в моем браузере. Он отвечает, заполняя первые шесть (6) ячеек в электронной таблице.

Я переиздал новую версию и подтвердил, что код все еще работает, но я все еще получаю сообщение об ошибке от Trello, в котором говорится, что они получили код 403, а не 200. И я получаю эту ошибку только при использовании /exec, а не /dev. А поскольку /dev не может получать post запросов, это бесполезно :(

Ниже приведен оставшийся пример:


function doSomething() {
  var values = [11,12];
  SpreadsheetApp.getActiveSheet().getRange("A1:B1").setValue(values);
}


function create() {
  var url = 'https://api.trello.com/1/tokens/ae6ebe60b45abcd2d4aa945c9ab4c4571bd6b6f7856b1df0cd387fbffc649579/webhooks/?key=a211f4aca7fb3e521d652730dd231cb6'  
  var payload = { 
    "key": "xxxxxxxxxxxxxxxxxx",
    "token" : "xxxxxxxxxxxxxxxxxxx": "https://script.google.com/macros/s/AKfycbw51TYGWHe95hKdcAs4l7E2eg0AtBi8e48lf_iafKYI/dev",
    "idModel":"xxxxxxxxxxxxxxxxxxxxxxxx",
    "description": "GW Test"  
  }
  var options = {"method" : "delete",
                 "payload" : payload,
              // "muteHttpExceptions": true
                 };

  var response = UrlFetchApp.fetch(url,options);           // creates webhook
}


// function that fires when the webapp receives a GET request
function doGet(e) {
  doSomething();
  var values = [21,22];
  SpreadsheetApp.getActiveSheet().getRange("A2:B2").setValue(values);
  return HtmlService.createHtmlOutput("something Get-ed");
}

function doPost(e) {
  doSomething();
  var values = [31,32];
  SpreadsheetApp.getActiveSheet().getRange("A3:B3").setValue(values);
  return ContentService.createTextOutput("something Posted");
  //var params = JSON.stringify(e);
}



person Chuck's Keg    schedule 09.08.2019    source источник
comment
В вашей ситуации работает конечная точка /dev. Но конечная точка /exec не работает. В такой ситуации я подумал, что последний скрипт может не отображаться в веб-приложениях. Так как насчет повторного развертывания веб-приложений в виде новой версии? По этому, пожалуйста, проверьте это еще раз. Если это не было прямым решением вашей проблемы, прошу прощения. Если это не сработало, можете ли вы предоставить сценарий веб-приложений?   -  person Tanaike    schedule 09.08.2019
comment
Я могу заставить свой код отвечать на put и get запросы, когда я использую ссылку или загружаю URL-адрес прямо в моем браузере. Он отвечает, заполняя первые шесть (6) ячеек в электронной таблице. Я переиздал новую версию и убедился, что код все еще работает, но я все еще получаю сообщение об ошибке от Trello, в котором говорится, что они получили код 403, а не 200. И я получаю эту ошибку только при использовании /exec, а не /dev. А поскольку /dev не может получать post запросов, это не поможет :(   -  person Chuck's Keg    schedule 09.08.2019
comment
Можете ли вы попробовать это в новом файле сценария? Это может быть параллельная проблема. Опубликовать новый скрипт для вызова trello api из нового скрипта в новом проекте для вызова старого опубликованного URL-адреса? т.е. сделать вызывающий проект и опубликованный проект разными. Также попробуйте JSON структурировать полезную нагрузку.   -  person TheMaster    schedule 09.08.2019
comment
Я предложил обходной путь в качестве ответа. Не могли бы вы это подтвердить? Если я неправильно понял ваш вопрос и это не решило вашу проблему, я прошу прощения.   -  person Tanaike    schedule 09.08.2019
comment
@ Chuck's Keg. Мой ответ показал вам результат, которого вы хотите? Не могли бы вы рассказать мне об этом? Мне тоже полезно учиться. Если это сработает, другие люди, у которых есть такая же проблема с вами, также могут основать ваш вопрос как вопрос, который можно решить. Если у вас еще есть проблемы с моим ответом, прошу прощения. В то время могу я спросить вас о вашей нынешней ситуации? Хочу учиться решать ваши вопросы.   -  person Tanaike    schedule 14.08.2019


Ответы (1)


Как насчет этого ответа?

Проблема:

Из вашего вопроса API возвращается следующая ошибка.

{"message": "URL (https://script.google.com/macros/s/AKfycbxo90ucgXXz7MG6Z3wb2KD-PJn3akGKoelXLJ2mkg/exec) не вернул код состояния 200, получил 403 "," error ":" ERROR "}

Что касается причины вышеуказанной ошибки, сначала я подумал, что последний скрипт может не отображаться в веб-приложениях. Но из вашего ответного комментария было обнаружено, что последний скрипт был отражен в веб-приложениях. В этой ситуации я попытался получить ошибку 403 из развернутых веб-приложений.

Подготовка:

В качестве подготовки были развернуты веб-приложения с параметрами «Выполнить приложение как» и «Кто имеет доступ к приложению» как Me и Anyone, even anonymous соответственно. Пример сценария для веб-приложений выглядит следующим образом.

function doGet(e) {return ContentService.createTextOutput("GET: Done.")}

Эксперимент:

С помощью скрипта Google Apps:

Сначала я проверил код состояния с помощью скрипта Google Apps, когда он запрашивает веб-приложения. Сценарий выглядит следующим образом.

function myFunction() {
  var url_exec = "https://script.google.com/macros/s/###/exec";
  var url_dev = "https://script.google.com/macros/s/###/dev";
  var res = UrlFetchApp.fetchAll([{url: url_exec}, {url: url_dev}]);
  res.forEach(function(e) {
    Logger.log(e.getResponseCode());
  });
}

В этом случае код состояния 200 был получен для обеих конечных точек exec и dev. С помощью скрипта Google Apps не удалось получить код состояния 403.

Использование Curl:

Чтобы получить код состояния с помощью curl, используется curl -s -o /dev/null -w "%{http_code}" http://www.example.org/. Это из этой ветки. Здесь код состояния был исследован с помощью команды curl. Поскольку curl может получить доступ с помощью 2 типов запросов с помощью параметров, как показано ниже.

  1. --include: включите в вывод заголовки ответа HTTP. Заголовки ответа HTTP могут включать в себя такие вещи, как имя сервера, файлы cookie, дату документа, версию HTTP и многое другое ...

  2. --head: (HTTP FTP-ФАЙЛ) Получить только заголовки! HTTP-серверы имеют команду HEAD, которая используется для получения ничего, кроме заголовка документа. При использовании с файлом FTP или FILE curl отображает только размер файла и время последнего изменения.

Используя указанные выше параметры, были исследованы следующие 4 модели.

  1. Request to the endpoint of exec using the option --include.
    • curl -sL --include -o /dev/null -w "%{http_code}" "https://script.google.com/macros/s/###/exec"
    • 200 был возвращен.
  2. Request to the endpoint of dev using the option --include.
    • curl -sL --include -o /dev/null -w "%{http_code}" "https://script.google.com/macros/s/###/dev"
    • 200 был возвращен.
  3. Request to the endpoint of exec using the option --head.
    • curl -sL --head -o /dev/null -w "%{http_code}" "https://script.google.com/macros/s/###/exec"
    • 403 был возвращен.
  4. Request to the endpoint of dev using the option --head.
    • curl -sL --head -o /dev/null -w "%{http_code}" "https://script.google.com/macros/s/###/dev"
    • 200 был возвращен.

В результате было обнаружено, что при запросе веб-приложений конечной точки exec с параметром --head был получен код состояния 403.

Результат и обсуждения:

Когда для команды curl из документа используется опция --head, это означает, что она запрашивает только заголовок и не запрашивает тело. Таким образом было обнаружено, что был возвращен код состояния 403.

Здесь, почему код состояния 200 был возвращен для обоих вариантов --include и --head при запросе к конечной точке dev? Считается, что причина этого в том, что был возвращен экран входа в систему. При доступе к конечной точке dev требуется использовать маркер доступа. Когда токен доступа не используется, возвращается экран входа в систему. В этом случае возвращается код состояния 200. В качестве тестового примера, когда токен доступа используется для конечной точки dev с помощью приведенной ниже команды curl,

curl -sL --head -H "Authorization: Bearer ###" -o /dev/null -w "%{http_code}" "https://script.google.com/macros/s/###/dev"

Был возвращен код состояния 403. Из этого результата были получены следующие результаты.

  • Когда извлекается только заголовок, под которым веб-приложения работают нормально, возвращается 403.
  • Когда возвращается экран входа в систему, возвращается 200.

В результате считается, что причина ошибки {"message":"URL (https://script.google.com/macros/s/AKfycbxo90ucgXXz7MG6Z3wb2KD-PJn3akGKoelXLJ2mkg/exec) did not return 200 status code, got 403","error":"ERROR"} связана с описанной выше ситуацией.

Обходной путь:

Из приведенных выше результатов, когда веб-приложения развертываются с параметрами «Выполнить приложение как» и «Кто имеет доступ к приложению» как Me и Only myself, соответственно, когда оно запрашивает конечную точку exec с использованием параметра --head, обнаруживается, что будет возвращен код состояния 200. Потому что в это время отображается экран входа в систему.

Используя эту ситуацию, как насчет следующего потока в качестве обходного пути?

  1. Когда конечная точка веб-приложений зарегистрирована в API, разверните веб-приложения с помощью «Выполнить приложение как» и «Кто имеет доступ к приложению» как Me и Only myself соответственно.

  2. После завершения регистрации разверните веб-приложения, указав «Запустить приложение как» и «Кто имеет доступ к приложению» как Me и Anyone, even anonymous соответственно.

    • By this, the Web Apps can be accessed.

Согласно приведенному выше потоку, только когда конечная точка зарегистрирована, возвращается код состояния 200. Но в этом обходном пути предполагается, что API, который вы хотите использовать, может проверить запрошенный заголовок. Если мое предположение было неверным, этот обходной путь использовать нельзя. В таком случае я должен извиниться.

Использованная литература:

Добавлен:

В моей среде я мог подтвердить, что конечную точку exec веб-приложений можно зарегистрировать с помощью trello API, используя описанный выше обходной путь. Я использовал следующий сценарий.

  • Before you run the script, please set the Web Apps as follows.
    • "Execute the app as" and "Who has access to the app" are Me and Only myself, respectively.
  • After the response of like {"id":"###","description":"sample","idModel":"###","callbackURL":"https://script.google.com/macros/s/###/exec","active":true} was retrieved, please set the Web Apps as follows.
    • "Execute the app as" and "Who has access to the app" are Me and Anyone, even anonymous, respectively.

Таким образом можно использовать перехватчик.

Пример сценария:

var url = 'https://api.trello.com/1/tokens/###/webhooks/?key=###'
var payload = { 
  "callbackURL": "https://script.google.com/macros/s/###/exec",
  "idModel":"###",
  "description": "sample"
}
var options = {method: "post", payload: payload};
var res = UrlFetchApp.fetch(url,options);
Logger.log(res.getContentText())
person Tanaike    schedule 09.08.2019
comment
Спасибо! У меня была такая же проблема, и это решение сработало для меня. (И я уверен, что избавил меня от многих часов разочарования!) - person Aaron Dunigan AtLee; 24.09.2020
comment
@Aaron Dunigan AtLee Спасибо за ваш комментарий. Я рад, что мой ответ был полезен в вашей ситуации. И тебе спасибо. - person Tanaike; 25.09.2020