Как определить, что послужило причиной запуска моего скрипта? - PullRequest
0 голосов
/ 30 декабря 2018

Всякий раз, когда я пытаюсь отобразить диалоговое окно пользовательского интерфейса (например, msgBox или alert ), оно отлично работает, когда вызывается через пункт меню (например, из Google Sheets), но оно вешает мой скриптесли я попытаюсь вызвать его из редактора скриптов Google Apps (например, через функцию «Выполнить»> «Выполнить»).

enter image description here

Мое предположениеэто потому, что редактор скриптов Google Apps не может отображать никакой пользовательский интерфейс.Чтобы решить эту проблему, я хотел бы создать функцию-обертку, которая проверяет, как выполнялся сценарий, и не отображать пользовательский интерфейс в зависимости от источника.

На экране «Выполнения» есть понятие «Тип» (редактор, автономный), Триггер):

enter image description here

Это заставляет меня думать, что есть способ получить этот тип в коде.

Psuedo-код того, как может выглядеть функция:

function showMessage(message) {
  var scriptSource = ???;
  if (scriptSource === "Standalone") {
    Browser.msgBox(message);
  } else {
    console.log(message);
  }
}

Как мне получить scriptSource?

Ближайшая вещь, которую я могу найти - TriggerSource , но в нем отсутствуют значения перечисления «Редактор» и «Триггер».Кроме того, это свойство доступно только для Trigger .Я не знаю, как получить доступ к текущему триггеру.Насколько я понимаю, это доступно только через объект события (например, через triggerUid) для функций, действующих как триггеры.Этот метод, который я запускаю в редакторе сценариев приложений, не имеет доступа к объекту события.

Ответы [ 3 ]

0 голосов
/ 30 декабря 2018

Не лучшее решение, но мой текущий обходной путь - создать 3 версии каждой функции и добавить способ ее вызова к имени.

Например, если была функция «Hello World»:

function onOpen() {
  var menu = [
    {name: 'Hello World', functionName: 'helloWorldViaMenu_'},
  ];
  SpreadsheetApp.getActive().addMenu('Custom', menu);
}

function helloWorldViaMenu_() {
  helloWorld_(false);
}

function helloWorldViaEditor() {
  helloWorld_(true);
}

function helloWorld_(invokedFromEditor) {
  if (invokedFromEditor) {
    Logger.log("Hello world");
  } else {
    Browser.msgBox("Hello world");
  }
}

helloWorldViaEditor - единственное, у которого нет _ в конце, поэтому оно может бытьвыбирается с помощью раскрывающегося интерфейса редактора «Выбор функции».

0 голосов
/ 30 декабря 2018

Создание диалогов

Вы можете запустить их из меню или редактора сценариев.Они работают одинаково.

function makeAmenu(){
  SpreadsheetApp.getUi().createMenu('A Menu')
  .addItem('Run my Dialogs', 'showMyDialogs')
  .addToUi();
}

function showMyDialogs(){
  var ui=SpreadsheetApp.getUi();
  ui.alert('This is an alert');
  ui.prompt('This is a prompt');
  var html=HtmlService.createHtmlOutput('<p>This is a modeless dialog</p><input type="button" value="Close" onClick="google.script.host.close();" />');
  ui.showModelessDialog(html, 'Dialog');
}

Если вы запустите скрипт отсюда:

enter image description here

Вы должны перейти сюда, чтобыувидеть это:

enter image description here

0 голосов
/ 30 декабря 2018
  • Вы хотите знать, является ли текущий проект типом сценария с привязкой к контейнеру или типом автономного сценария.
  • Вы хотите использовать Browser.msgBox().

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

  1. Получите родительский идентификатор проекта, используя метод projects.get в Apps Script API.Родительский идентификатор означает, что идентификатор файла Google Docs.
    • Когда возвращается родительский идентификатор, обнаруживается, что проект относится к типу сценария, привязанного к контейнеру.
    • Когда родительский идентификатор НЕ возвращается, обнаруживается, что проект является автономнымтип сценария.
  2. Если mimeType родительского идентификатора - Google Form, Browser.msgBox() использовать нельзя.Поэтому для этого используется оператор if.

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

Это пример сценария.В этом примере сценария используется идентификатор сценария текущего проекта.Конечно, вы также можете вручную указать идентификатор сценария.

var id = ScriptApp.getScriptId(); // Retrieve scriptId of current project.
var url = "https://script.googleapis.com/v1/projects/" + id + "?fields=parentId";
var res = UrlFetchApp.fetch(url, {headers: {Authorization: "Bearer " + ScriptApp.getOAuthToken()}});
res = JSON.parse(res.getContentText());
if ("parentId" in res) {
  Logger.log("Container-bound script type.")
  var mimeType = DriveApp.getFileById(res.parentId).getMimeType();
  if (mimeType === MimeType.GOOGLE_FORMS) {
    Logger.log("Browser.msgBox() cannot be used at Google Form.");
  } else {
    Browser.msgBox("Hello world");
  }
} else {
  Logger.log("Standalone script type.")
  Logger.log("Hello world");
}

Примечание:

  • При использовании этого сценария выполните следующий поток действий.
    1. Включить API скриптов приложений на консоли API.
    2. По крайней мере, добавьте следующие области в манифесты.
  • Если в вашем сценарии,другие области должны быть добавлены, пожалуйста, добавьте их.И если вы хотите использовать автоматический установщик областей с редактором сценариев, вы можете добиться этого с помощью библиотеки.Подробную информацию можно посмотреть по адресу здесь .

Ссылки:

Если я неправильно понимаю ваш вопрос, извините.

Редактировать:

  • Вы хотите подтвердить, вызывается ли функция из редактора сценариев или из пользовательского меню.

Если мое понимание верно, как насчет этого примера сценария?Это пример сценария.Список процессов можно получить, указав идентификатор сценария и имя функции.В этом примере сценария, используя «ProcessType» process.listScriptProcesses в Apps Script API, он подтверждает, вызывается ли функция из редактора сценариев или из пользовательского меню.

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

Это пример сценария.Список процессов можно получить, указав идентификатор сценария и имя функции.

При использовании этого сценария включите API сценариев приложений на консоли API и добавьте область действия https://www.googleapis.com/auth/script.processes в манифесты.

Как использовать этот скрипт следующим образом.

  1. Выполнить addCustomMenu().
  2. Выполнить sampleFunction в пользовательском меню.
    • При этом в журнале отображается Call from custom menu.
  3. Запустите sampleFunction в редакторе сценариев.
    • При этом в журнале отображается Call from script editor.
Сценарий:
function addCustomMenu() {
  SpreadsheetApp.getUi().createMenu('sampleCustomMenu').addItem('sample', 'sampleFunction').addToUi();
}

function sampleFunction() {
  var scriptId = ScriptApp.getScriptId();
  var functionName = "sampleFunction";
  var url = "https://script.googleapis.com/v1/processes:listScriptProcesses?scriptId=" + scriptId + "&scriptProcessFilter.functionName=" + functionName;
  var res = UrlFetchApp.fetch(url, {headers: {Authorization: "Bearer " + ScriptApp.getOAuthToken()}, muteHttpExceptions: true});
  res = JSON.parse(res);
  if (!("processType" in res.processes[0])) {
    Logger.log("Call from custom menu")
  } else if (res.processes[0].processType == "EDITOR") {
    Logger.log("Call from script editor")
  }
}

Ссылки:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...