Предоставьте ключ API, чтобы избежать ошибки Hit Limit от службы карт в скрипте приложений

avatar
John Cappelletti
5 июня 2018 в 15:07
1710
1
2

У меня есть таблица Google, в которой мы получаем расстояние между двумя точками широты и долготы через службу карт. Приведенная ниже функция работает, но матрица состоит из 4500 ячеек, поэтому я получаю сообщение об ошибке "Предел количества попаданий".

Как я могу указать здесь ключ API моей платной учетной записи?

Пользовательская функция

function drivingMeters(origin, destination) {
  if (origin=='' || destination==''){return ''}
  var directions = Maps.newDirectionFinder()
  .setOrigin(origin)
  .setDestination(destination)
  .getDirections();
  return directions.routes[0].legs[0].distance.value ;
}

Пример использования:

A1: =drivingMeters($E10,G$9)

Where E10 = 42.771328,-91.902281
  and G9  = 42.490390,-91.1626620
Источник
John Cappelletti
5 июня 2018 в 15:13
0

@tehhowch вызывается как пользовательская функция.

tehhowch
5 июня 2018 в 15:23
0

developers.google.com/apps-script/reference/maps/…

Ответы (1)

avatar
tehhowch
5 июня 2018 в 15:53
4

Согласно документации, вы должны инициализировать сервис Карт с вашими данными аутентификации перед вызовом других методов:

Идентификатор клиента и ключ подписи можно получить на портале поддержки Google Enterprise. Установите эти значения на null, чтобы вернуться к использованию квот по умолчанию.

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

Кроме того, я рекомендую переписать вашу пользовательскую функцию так, чтобы она принимала входные данные массива и возвращала соответствующий вывод массива — это поможет ускорить ее выполнение. Google предоставляет пример этого на странице пользовательских функций: https://developers.google.com/apps-script/guides/sheets/functions#optimization

.

Пример с использованием props/cache: example props

function authenticateMaps_() {
  // Try to get values from cache:
  const cache = CacheService.getScriptCache();
  var props = cache.getAll(['mapsClientId', 'mapsSigningKey']);
  // If it wasn't there, read it from PropertiesService.
  if (!props || !props.mapsClientId || !props.mapsSigningKey) {
    const allProps = PropertiesService.getScriptProperties().getProperties();
    props = {
      'mapsClientId': allProps.mapsClientId,
      'mapsSigningKey': allProps.mapsSigningKey
    };
    // Cache these values for faster access (max 6hrs)
    cache.putAll(props, 21600);
  }
  // Apply these keys to the Maps Service. If they don't exist, this is the
  // same as being a default user (i.e. no paid quota).
  Maps.setAuthentication(props.mapsClientId, props.mapsSigningKey);
}
function deauthMaps_() {
  Maps.setAuthentication(null, null);
}

// Your called custom function. First tries without authentication,
// and then if an error occurs, assumes it was a quota limit error
// and retries. Other errors do exist (like no directions, etc)...
function DRIVINGMETERS(origin, dest) {
  if (!origin || !destination)
    return;
  try {
    return drivingMeters_(origin, dest);
  } catch (e) {
    console.error({
      message: "Error when computing directions: " + e.message,
      error: e
    });
    // One of the possible errors is a quota limit, so authenticate and retry:
    // (Business code should handle other errors instead of simply assuming this :) )
    authenticateMaps_();
    var result = drivingMeters_(origin, dest);
    deauthMaps_();
    return result;
  }
}

// Your implementation function.
function drivingMeters_(origin, dest) {
  var directions = Maps.newDirectionFinder()
  ...
}
John Cappelletti
5 июня 2018 в 15:58
0

Спасибо за подробный ответ!

tehhowch
5 июня 2018 в 16:05
0

@JohnCappelletti добавил к этому немного больше O :)

John Cappelletti
8 июня 2018 в 12:33
0

Никогда не понимал, почему я не могу создать награду с 1-го дня

russellkt
21 августа 2018 в 19:42
0

Отличный ответ, но это кажется применимым только для клиентов Google Enterprise, поскольку ключи API или учетные данные oauth не работают, если API и биллинг включены в облачной консоли. Для меня кажется, что единственный способ — использовать приложение для получения URL-адресов, где вы можете указать ключ API.

TheMaster
15 октября 2018 в 09:59
1

Безопасно ли помещать ключи в Cache (тоже ScriptCache)? Я бы рекомендовал против этого из соображений безопасности. Я рекомендую хранить его только в свойствах пользователя. Дыры безопасности будут огромными, если лист будет общим. Пользовательские функции, вероятно, не могут получить доступ к пользовательским свойствам. Но последствия обходного пути для безопасности должны быть упомянуты в ответе, ИМО.

tehhowch
15 октября 2018 в 11:16
0

@ i'-'i мое понимание ситуации с ОП заключалось в том, что таблица была предоставлена ​​​​лицам в одной организации. В этом случае все они, вероятно, должны использовать один и тот же проект выставления счетов и вместо того, чтобы требовать от каждого редактора вручную вводить эти учетные данные в свои пользовательские свойства (увеличивая осведомленность о том, что эти учетные данные вообще существуют), пусть один разработчик вводит их в службу свойств для script и другие редакторы могут копировать их, если оба знают, что эти кредиты существуют (не гарантируется), и они намереваются их скопировать, что кажется меньшей поверхностью. Я открыт для ваших правок, хотя.

TheMaster
15 октября 2018 в 11:44
0

@tehhowch Даже пользователи домена делятся листом за пределами домена. Я не думаю, что пользовательские функции подходят для этой проблемы. Однако в свете вашего объяснения я думаю, что моего предыдущего комментария достаточно, а не редактирования.