2

Я написал сценарий Google Apps, который подключен к Виртуальному принтеру Google, чтобы автоматизировать печать. Сценарий будет автоматически запускаться с интервалом времени, искать соответствующие файлы, и если он будет найден, он отправит их на мой принтер. Мой код использовал OAuthConfig и работал нормально, но теперь этот класс устарел и после выходных дней пробной версии & ошибка и чистка межплатформенного I не может заставить его работать с OAuth2.OAuth2 с облачным принтом Google

Вот OAuthConfig код, который работал отлично:

function printDoc(docId, docTitle, myPrinterId) { 

    var scope = 'https://www.googleapis.com/auth/cloudprint'; 
    var url = 'https://www.google.com/cloudprint/submit'; 
    var payloadOfSubmit = { 
    "printerid" : myPrinterId, 
    "title" : docTitle, 
    "content" : docId, 
    "contentType" : "google.kix" 
    }; 

    var fetchArgs = googleOAuth_('google', scope, payloadOfSubmit); 
    fetchArgs.method = 'POST'; 
    var responseOfSubmit = UrlFetchApp.fetch(url, fetchArgs); 
    var jsonOfSubmit = JSON.parse(responseOfSubmit.getContentText()); 

    return jsonOfSubmit; 
} 

function googleOAuth_(name, scope, payloadData) { 
    var oAuthConfig = UrlFetchApp.addOAuthService(name); 
    oAuthConfig.setAuthorizationUrl("https://www.google.com/accounts/OAuthAuthorizeToken"); 
    oAuthConfig.setRequestTokenUrl("https://www.google.com/accounts/OAuthGetRequestToken?scope="+scope); 
    oAuthConfig.setAccessTokenUrl("https://www.google.com/accounts/OAuthGetAccessToken"); 
    oAuthConfig.setConsumerKey("anonymous"); 
    oAuthConfig.setConsumerSecret("anonymous"); 
    return { 
    oAuthServiceName:name, 
    oAuthUseToken:"always", 
    muteHttpExceptions:true, 
    payload:payloadData 
    }; 
} 

Я успешно подключен GitHub library for OAuth2. Однако, что отличается от инструкций, предоставленных там, и на многих других сайтах, заключается в том, что они предполагают, что код будет развернут как веб-служба, где пользователю предлагается вручную щелкнуть, чтобы авторизовать запрос. В моем случае код будет сохранен в файле сценария Google Apps, а облачный принтер - в той же учетной записи Google, поэтому мне не понадобилось это ручное вмешательство или обратно & вперед с моим оригинальным OAuthconfig.

Моей первой попытки адаптации инструкции была:

function printDoc2(docId, docTitle, myPrinterId) { 

    var url = 'https://www.google.com/cloudprint/submit'; 
    var scope = 'https://www.googleapis.com/auth/cloudprint'; 
    var payloadOfSubmit = { 
    "printerid" : myPrinterId, 
    "title" : docTitle, 
    "content" : docId, 
    "contentType" : "google.kix", 
    }; 

    var accessToken = googleOAuth_('google', scope).getAccessToken(); 

    var params = { 
    method:"POST", 
    headers: {"Authorization": "Bearer " + accessToken}, 
    muteHttpExceptions:true, 
    payload:payloadOfSubmit 
    }; 

    var responseOfSubmit = UrlFetchApp.fetch(url, params); 
    //Logger.log(responseOfSubmit); 
    var jsonOfSubmit = JSON.parse(responseOfSubmit.getContentText()); 

    return jsonOfSubmit; 
} 

function googleOAuth2_(name, scope) { 

    return OAuth2.createService(name) 
    .setAuthorizationBaseUrl('https://accounts.google.com/o/oauth2/auth') 
    .setTokenUrl('https://accounts.google.com/o/oauth2/token') 
    .setClientId("anonymous") 
    .setClientSecret("anonymous") 
    .setProjectKey(ScriptApp.getProjectKey()) 
    .setPropertyStore(PropertiesService.getUserProperties()) 
    .setScope(scope) 
    .setCallbackFunction('authCallback'); 
} 

function authCallback(request) { 
    var driveService = getDriveService(); 
    var isAuthorized = driveService.handleCallback(request); 
    if (isAuthorized) { 
    return HtmlService.createHtmlOutput('Success! You can close this tab.'); 
    } else { 
    return HtmlService.createHtmlOutput('Denied. You can close this tab'); 
    } 
} 

Но это дает мне ошибку «Доступ не предоставлен или истек», когда он пытается запустить линию:

var accessToken = googleOAuth_('google', scope).getAccessToken(); 

Я нашел приложение ScriptApp Method getOAuthToken, который, казалось, мог бы дать мне токен, который мне нужен. Я заменил эту строку с:

var accessToken = ScriptApp.getOAuthToken(); 

И код выполняется, но мой ответ от сервера «Ошибка 403 Учетные данные пользователя, необходимые».

Вот моя третья попытка на основе @ предложение Mogsdad в:

function sendPrintJob(docId,myPrinterId,docTitle) { 

    var payloadOfSubmit = { 
      "printerid" : myPrinterId, 
      "title" : docTitle, 
      "content" : docId, 
      "contentType" : "google.kix" , 
    }; 

    var request = { 
    "method": "POST", 
    "headers":{"Authorization": "Bearer "+ScriptApp.getOAuthToken()},  
    "muteHttpExceptions": true 
    }; 

    var responseOfSubmit = UrlFetchApp.fetch("https://www.google.com/cloudprint/submit", request); 
    Logger.log(responseOfSubmit); 
} 

Я попробовал несколько вариантов, в том числе создание Developer Project Console и с помощью идентификатора клиента при условии, но я продолжаю застрять в эти два вопроса (доступ не предоставляется или требуется учетные данные). Если кто-то может оказать какую-либо помощь, я бы очень признателен.

+0

Предложение: попробуйте 'ScriptApp.getOAuthToken()' вместо, инструкции в [этот ответ] (http://stackoverflow.com/questions/30586559/printing -spreadsheet к PDF-то экономящие-файл-в-ввинчивания с использованием-oauth2/30599940 # 30599940). – Mogsdad

+0

Спасибо за ваш ответ @Mogsdad. Я попробовал ваше предложение, но все еще получаю ошибку 403: требуемые учетные данные пользователя. Я просмотрел комментарии в ссылке, на которую вы ссылались, и кто-то заметил: «Поскольку вы используете DriveApp, ваш скрипт уже имеет авторизацию для доступа к вашим файлам из любого источника, включая UrlFetchApp». Возможно ли, что сценарию не разрешен доступ к Виртуальному принтеру Google (если я не уверен, как это разрешить)? – Colin

ответ

1

Вот шаги, которые позволили мне подключить Google Apps Script в Google Cloud Print, так что я мог тогда представить работу GCP (эти шаги все началось изнутри Google Apps Script):

  1. Добавить oauth2 библиотека (https://github.com/googlesamples/apps-script-oauth2) на ваш Google Apps Script, перейдя в: Ресурсы> Библиотеки> Поиск библиотека MswhXl8fVhTFUH_Q3UOJbXvxhMjh3Sh48> Выбрать
  2. Создание нового веб-приложения в Консоль разработчика Ресурсы> Project Console Developer> Нажмите на ссылку проект> APIs & Auth> Учетные записи> Добавить учетные данные> OAuth2.0 ID клиента> Web Application> Настройка авторизованных перенаправления URI, в формате
    https://script.google.com/macros/d/{PROJECT KEY}/usercallback где ключевой проект находится в стадии Файл> Свойства и проекта скопировать идентификатор клиента и секрет клиента
  3. Добавить идентификатор и Секрет «getCloudPrintService() "ниже (заменить client_id и client_secret)
  4. Перейдите в раздел« Выполнить »>« Показать »и разрешите сценарий.
  5. Откройте регистратор (Cmd + Enter), скопируйте URL-адрес и вставьте его на новую вкладку браузера, чтобы завершить авторизацию.
  6. Перейти к https://www.google.com/cloudprint/#printers, выберите принтер, нажмите детали, расширить дополнительные детали, и скопировать ваш Printer ID (он будет иметь формат 555aa555-5a55-5555-5555-55555a55a555)
  7. Добавить идентификатор принтера «printGoogleDocument()» ниже код (замените myPrinterId)

Этот ресурс был полезным в выяснении шагов из: http://ctrlq.org/code/20061-google-cloud-print-with-apps-script, и вы также можете найти эти ссылки полезны:

function showURL() { 
 
    var cpService = getCloudPrintService(); 
 
    if (!cpService.hasAccess()) { 
 
    Logger.log(cpService.getAuthorizationUrl()); 
 
    } else { 
 
    Logger.log("You already have access to this service."); 
 
    } 
 
} 
 
    
 
function getCloudPrintService() { 
 
    return OAuth2.createService('print') 
 
    .setAuthorizationBaseUrl('https://accounts.google.com/o/oauth2/auth') 
 
    .setTokenUrl('https://accounts.google.com/o/oauth2/token') 
 
    .setClientId(client_id) 
 
    .setClientSecret(client_secret) 
 
    .setCallbackFunction('authCallback') 
 
    .setPropertyStore(PropertiesService.getUserProperties()) 
 
    .setScope('https://www.googleapis.com/auth/cloudprint') 
 
    .setParam('login_hint', Session.getActiveUser().getEmail()) 
 
    .setParam('access_type', 'offline') 
 
    .setParam('approval_prompt', 'force'); 
 
} 
 
    
 
function authCallback(request) { 
 
    var isAuthorized = getCloudPrintService().handleCallback(request); 
 
    if (isAuthorized) { 
 
    return HtmlService.createHtmlOutput('You can now use Google Cloud Print from Apps Script.'); 
 
    } else { 
 
    return HtmlService.createHtmlOutput('Cloud Print Error: Access Denied'); 
 
    } 
 
} 
 

 
function getPrinterList() { 
 
    var response = UrlFetchApp.fetch('https://www.google.com/cloudprint/search', { 
 
    headers: { 
 
     Authorization: 'Bearer ' + getCloudPrintService().getAccessToken() 
 
    }, 
 
    muteHttpExceptions: true 
 
    }).getContentText(); 
 
    
 
    var printers = JSON.parse(response).printers; 
 
    
 
    for (var p in printers) { 
 
    Logger.log("%s %s %s", printers[p].id, printers[p].name, printers[p].description); 
 
    } 
 
} 
 

 
function printGoogleDocument(docId, docTitle) { 
 
    // For notes on ticket options see https://developers.google.com/cloud-print/docs/cdd?hl=en 
 
    var ticket = { 
 
    version: "1.0", 
 
    print: { 
 
     color: { 
 
     type: "STANDARD_COLOR" 
 
     }, 
 
     duplex: { 
 
     type: "NO_DUPLEX" 
 
     }, 
 
    } 
 
    }; 
 
    
 
    var payload = { 
 
    "printerid" : myPrinterId, 
 
    "content" : docId, 
 
    "title" : docTitle, 
 
    "contentType" : "google.kix", // allows you to print google docs 
 
    "ticket" : JSON.stringify(ticket), 
 
    }; 
 
    
 
    var response = UrlFetchApp.fetch('https://www.google.com/cloudprint/submit', { 
 
    method: "POST", 
 
    payload: payload, 
 
    headers: { 
 
     Authorization: 'Bearer ' + getCloudPrintService().getAccessToken() 
 
    }, 
 
    "muteHttpExceptions": true 
 
    }); 
 
    
 
    // If successful, should show a job here: https://www.google.com/cloudprint/#jobs 
 

 
    response = JSON.parse(response); 
 
    if (response.success) { 
 
    Logger.log("%s", response.message); 
 
    } else { 
 
    Logger.log("Error Code: %s %s", response.errorCode, response.message); 
 
    } 
 
    return response; 
 
}

Смежные вопросы