Скрипт Google Apps для добавления псевдонима в Gmail

avatar
Jason Jurotich
7 апреля 2018 в 22:59
825
2
2

У меня есть скрипт Google Apps, который выдает ошибку "Делегирование отклонено для jasonjurotich@school.edu.mx" и не работает для добавления псевдонима (другого адреса электронной почты) к учетной записи в домене. Это может быть из-за заголовков токена или отсутствия какого-либо URL-адреса, который авторизует что-то, но я не могу найти достаточно документации, разъясняющей, как его добавить.

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

Все необходимые разрешения активированы (OAuth2, учетная запись службы Google с делегированием на уровне домена, активированы необходимые API и т. д.)

У меня есть следующий сценарий:

var JSON = {
  "private_key": "key",
  "client_email": "email",
  "client_id": "ID",
  "user_email": "teststudent@school.edu.mx"
};

function getOAuthService(user) {
  return OAuth2.createService('Service Account')
    .setAuthorizationBaseUrl('https://accounts.google.com/o/oauth2/auth')
    .setTokenUrl('https://accounts.google.com/o/oauth2/token')
    .setClientId('ID')
    .setPrivateKey(JSON.private_key)
    .setIssuer(JSON.client_email)
    .setSubject(JSON.user_email)
    .setPropertyStore(PropertiesService.getScriptProperties())
    .setParam('access_type', 'offline')
    .setParam('approval_prompt', 'force')
    .setScope('https://www.googleapis.com/auth/script.external_request https://www.googleapis.com/auth/gmail.settings.sharing');
}

function changeEmail() {
  var service = getOAuthService();
  service.reset();
  if (service.hasAccess()) {
    var userEmail = 'teststudent@school.edu.mx';   

    var alias = {
      sendAsEmail: 'aliastest1@school.edu.mx',
      displayName: 'TS',
      replyToAddress : 'aliastest1@school.edu.mx',
      treatAsAlias: true
    };

    Gmail.Users.Settings.SendAs.create(alias, userEmail);      
  }
}
Источник
tehhowch
9 апреля 2018 в 14:14
0

Я полагаю, вы говорите о delegation. Можешь подтвердить? Документация по делегированию решает вашу проблему?

Jason Jurotich
9 апреля 2018 в 17:35
0

Ошибок делегирования нет. На самом деле ошибок нет вообще, и именно это вызывает у меня недоумение.

Jason Jurotich
9 апреля 2018 в 18:02
0

В журналах он просто дает «неопределенное», когда я пытаюсь получить результат.

Anton Dementiev
9 апреля 2018 в 18:07
0

Обновил ответ ниже.

Ответы (2)

avatar
Jason Jurotich
11 апреля 2018 в 18:44
0

Мой коллега опубликовал что-то похожее на этот вопрос здесь: Создает пользовательский псевдоним «от» для отправки как с помощью GAS и API. Следующий модифицированный код — это то, что в итоге заработало с учетом того, что было здесь и что там.

var service_account = {
"private_key": "-----BEGIN PRIVATE KEY-----",
"client_email": "changealiastest4@project-id-[].iam.gserviceaccount.com",
"client_id": "ID",
"user_email": "teststudent@school.edu.mx"
};

function getOAuthService(user) {
  return OAuth2.createService('Service Account')
    .setAuthorizationBaseUrl('https://accounts.google.com/o/oauth2/auth')
    .setTokenUrl('https://accounts.google.com/o/oauth2/token')
    .setClientId('ID')
    .setPrivateKey(service_account.private_key)
    .setIssuer(service_account.client_email)
    .setSubject(service_account.user_email)
    .setPropertyStore(PropertiesService.getScriptProperties())
    .setParam('access_type', 'offline')
    .setParam('approval_prompt', 'force')
    .setScope('https://www.googleapis.com/auth/script.external_request https://www.googleapis.com/auth/gmail.settings.sharing https://www.googleapis.com/auth/gmail.settings.basic');
}

function changeEmail() {
  var userEmail = 'teststudent@school.edu.mx'; 
  var aliasEmail = 'aliastest1@school.edu.mx';
  var aliasName = 'TS';

  var service = getOAuthService();
    service.reset();
    if (service.hasAccess()) {

  var url = 'https://www.googleapis.com/gmail/v1/users/me/settings/sendAs'
    var headers ={
      "Authorization": 'Bearer ' + service.getAccessToken(),
      "Accept":"application/json", 
      "Content-Type":"application/json",
      };

  var resource ={
     sendAsEmail: aliasEmail,
     displayName: aliasName,
     replyToAddress : aliasEmail,
     treatAsAlias: true,
     verificationStatus: 'accepted'
   };  

  var options = {
  'headers': headers,
  'method': 'POST',
  'payload': JSON.stringify(resource),
  'muteHttpExceptions': true
  };

Logger.log(options);
var response = UrlFetchApp.fetch(url, options);
Logger.log(response.getContentText()); 

  }
}
avatar
Anton Dementiev
8 апреля 2018 в 18:12
0

Похоже, вы используете старую версию библиотеки OAuth2 для скрипта Google Apps. Пожалуйста, проверьте исходный код и убедитесь, что он не вызывает ScriptApp.getProjectKey(). Например, в приведенной ниже версии используется ScriptApp.getScriptId() вместо устаревшего метода:

.

https://github.com/gsuitedevs/apps-script-oauth2/blob/master/dist/OAuth2.gs

Попробуйте подключить новую версию к вашему проекту GAS в качестве библиотеки или вручную добавьте файлы в свой скрипт и посмотрите, исправит ли это ситуацию.

ОБНОВЛЕНИЕ

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

Service_.prototype.setScope = function(scope, optSeparator) {
  var separator = optSeparator || ' ';
  this.params_.scope = Array.isArray(scope) ? scope.join(separator) : scope;
  return this;
};

Вместо этого вы должны предоставить список областей действия и необязательный разделитель (по умолчанию используется пробел). В результате единственная область авторизации, которую в итоге использует ваш скрипт, — это https://www.googleapis.com/auth/gmail.settings.basic. Итог: вызовите 'setScope()' один раз, передав через пробел список требуемых областей. Вместо двух отдельных вызовов попробуйте следующее:

setScope('https://www.googleapis.com/auth/gmail.settings.basic https://www.googleapis.com/auth/gmail.settings.sharing');
Jason Jurotich
9 апреля 2018 в 17:36
0

Обновление OAuth2 только что избавило от ошибки устаревания, но скрипт по-прежнему не работает.

Jason Jurotich
9 апреля 2018 в 22:17
0

Антон Дементьев, к сожалению, ни здесь, ни в Stackoverflow, ни в интернете я не могу найти ничего, что бы приводило конкретные примеры того, как использовать или применять Service_.prototypes. Я не знаю, должен ли я открыть еще один вопрос об этом, но я не знаю, как добавить это в сценарий. Я считаю, что вы правы, хотя.

Anton Dementiev
9 апреля 2018 в 22:23
0

Не могли бы вы прояснить вопрос? Вы можете просто открыть исходный код используемой вами библиотеки OAuth2 и увидеть весь код в папке «dist». Он написан на языке Google Apps Script (JavaScript), так что вы даже можете переписать код по своему усмотрению, чтобы создать собственную библиотеку GAS. Прототипы являются функцией JavaScript и не являются уникальными для GAS developer.mozilla.org/en/docs/Web/JavaScript/…

Anton Dementiev
9 апреля 2018 в 22:27
0

Кроме того, ознакомьтесь со страницей документации по используемой вами библиотеке OAuth2. По сути, он говорит одно и то же, а именно, что вы должны вызывать setScope() только один раз github.com/gsuitedevs/apps-script-oauth2

Anton Dementiev
9 апреля 2018 в 22:33
0

Пробовали ли вы передавать список областей oauth, разделенных пробелами, вместо двойного вызова метода setScope()? См. пример выше

Jason Jurotich
9 апреля 2018 в 22:39
0

Я попробовал то, что вы сказали, и при отладке он говорит следующее: "({serviceName_:"Учетная запись службы", params_:{access_type:"offline", author_prompt:"force", scope:"googleapis.com/auth /gmail.settings.basic"}, tokenFormat_:"application/json", tokenHeade...", а затем говорит следующее: "({error:"unauthorized_client", error_description:"Клиент не авторизован для получения токенов доступа, используя этот method.", grant_time:1523313340})" Таким образом, я предполагаю, что единственный способ - это прототип службы, который я понятия не имею, как использовать. Я использую только скрипт Google Apps для его настройки.

Anton Dementiev
9 апреля 2018 в 22:43
0

Вы разместили вторую область действия (googleapis.com/auth/gmail.settings.sharing) после пробела, как показано в примере выше?

Jason Jurotich
9 апреля 2018 в 22:44
0

Я только что сделал это, и это вышло: "({serviceName_:"Учетная запись службы", params_:{access_type:"offline", author_prompt:"force", scope:"googleapis.com/auth/gmail.settings .basic googleapis.com/auth/gmail.settings..." с той же ошибкой, что и раньше.

Anton Dementiev
9 апреля 2018 в 22:51
0

Если вы погуглите эту ошибку, все указывает на делегирование полномочий на уровне домена учетной записи службы, поэтому вы можете дважды проверить это. Однако, поскольку вы говорите, что сделали это, я не уверен, что могу чем-то помочь вам coderhelper.com/questions/42784640/…

Jason Jurotich
9 апреля 2018 в 22:52
0

Позвольте мне следовать вашим указаниям и разместить результаты здесь позже.

Anton Dementiev
10 апреля 2018 в 09:54
0

Не могли бы вы попробовать добавить вызов setClientId() при создании объекта службы? К сожалению, я не могу проверить это, но описание ошибки указывает, что это может сработать.

Jason Jurotich
10 апреля 2018 в 17:42
0

Хорошо, только что прошел все с нуля. Добавил .setClientId() и снова просмотрел разрешения, но я определенно что-то упускаю. Я не думаю, что сейчас это области, потому что теперь появляется ошибка «Отказано в делегировании для jasonjurotich@school.edu.mx», поэтому что-то не так с разрешениями, но это связано с чем-то в скрипте, потому что я знаю, что дал ему все необходимые разрешения. Возможно, это связано с вызовом URL-адреса или некоторых заголовков токена, но я не знаю.

Anton Dementiev
10 апреля 2018 в 18:13
0

@JasonJurotich Конечно, вы запускаете скрипт под учетной записью администратора, а рассматриваемая учетная запись находится в вашем домене? Хорошо, у меня официально нет идей