使用Google云打印的OAuth2 [英] OAuth2 with Google Cloud Print

查看:198
本文介绍了使用Google云打印的OAuth2的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我编写了Google Apps脚本,连接到Google云打印以自动执行某些打印。脚本会自动运行一段时间,搜索相关文件,如果发现它会将它们发送到我的打印机。我的代码使用了 OAuthConfig并且工作正常,但现在该类已被弃用,经过一个周末的试用&错误和淘汰interwebs我无法使用OAuth2



以下是可正常使用的 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,$ b $contentType:google.kix
;

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

返回jsonOfSubmit;
}

函数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=+范围);
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 。但是,在那里以及其他许多网站上提供的说明有所不同,他们认为代码将作为Web服务进行部署,其中提示用户手动单击以授权请求。就我而言,代码将保存在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,$ b $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());

返回jsonOfSubmit;
}

函数googleOAuth2_(name,scope){

返回OAuth2.createService(名称)
.setAuthorizationBaseUrl('https:// accounts。 )
.setTokenUrl('https://accounts.google.com/o/oauth2/token')
.setClientId(anonymous)
.setClientSecret(anonymous)
.setProjectKey(ScriptApp.getProjectKey())
.setPropertyStore(PropertiesService.getUserProperties())
.setScope(scope)
.setCallbackFunction 'authCallback');
}

函数authCallback(request){
var driveService = getDriveService();
var isAuthorized = driveService.handleCallback(request);
if(isAuthorized){
return HtmlService.createHtmlOutput('Success!您可以关闭此标签。');
} else {
return HtmlService.createHtmlOutput('Denied。You can close this tab');






$ b

但是这给了我一个错误Access not granted or过期时,它会尝试运行该行:

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

所以我找到了一个应用程序ScriptApp Method getOAuthToken ,它似乎可能会给我我需要的令牌。我用上面的行代替了:

  var accessToken = ScriptApp.getOAuthToken(); 

执行代码,但是我的服务器响应是错误403用户凭证要求。



这是我根据@ Mogsdad的建议进行的第三次尝试:

 函数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 Console Project和使用在那里提供的客户端ID,但我一直陷在这两个问题(访问未授予,或所需的凭据)。如果任何人都可以提供任何帮助,我将非常感激。

解决方案

以下是允许我连接Google Apps脚本的步骤到Google云打印,然后我可以提交GCP作业(这些步骤都是从Google Apps脚本开始的):


  1. 添加OAuth2图书馆
    https://github.com/googlesamples/apps-script-oauth2 )到您的Google
    Apps脚本,方法是:资源>库>查找库
    MswhXl8fVhTFUH_Q3UOJbXvxhMjh3Sh48 >选择

  2. 在Developer Console资源>开发人员控制台项目中创建新的Web应用程序>单击项目链接> APIs& Auth>
    凭证>添加凭证> OAuth2.0客户端ID> Web
    应用程序>将授权重定向URI设置为格式

    https://脚本。 google.com/macros/d/{PROJECT KEY} / usercallback
    其中项目密钥位于文件>项目属性下并复制
    您的客户端ID和客户端密钥

  3. 将ID和Secret添加到下面的getCloudPrintService()代码中(替换 client_id client_secret

  4. 打开Logger(Cmd + Enter),复制URL并粘贴到一个新的浏览器选项卡来完成授权。

  5. 转到 https ://www.google.com/cloudprint/#printers ,选择您的打印机,点击详细信息,展开高级详细信息,然后复制您的打印机ID (它会格式为 555aa555-5a55-5555-5555-55555a55a555

  6. 添加prin (替换 myPrinterId



代码转换为printGoogleDocument此资源有助于确定步骤: http:// ctrlq.org/code/20061-google-cloud-print-with-apps-script ,您也可能会发现这些链接很有用:





  function showURL(){var cpService = getCloudPrintService(); if(!cpService.hasAccess()){Logger.log(cpService.getAuthorizationUrl()); }其他{Logger.log(您已经有权访问此服务。); }} 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/ ').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('您现在可以使用来自Apps Script的Google Cloud Print。'); } 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){//有关票证选项的说明,请参阅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,//允许您打印google文档ticket:JSON.stringify ,}; var response = UrlFetchApp.fetch('https://www.google.com/cloudprint/submit',{method:POST,payload:payload,headers:{Authorization:'Bearer'+ getCloudPrintService()。getAccessToken() },muteHttpExceptions:true}); //如果成功,应在此处显示一份工作:https://www.google.com/cloudprint/#jobs response = JSON.parse(response); if(response.success){Logger.log(%s,response.message); }其他{Logger.log(错误代码:%s%s,response.errorCode,response.message); } return response;}  


I had written a Google Apps Script that connected to Google Cloud Print to automate some printing. The script would auto-run on a time interval, search for relevant files, and if found it would sent them to my printer. My code used OAuthConfig and was working fine, but now that class has been deprecated and after a weekend of trial & error and scouring the interwebs I can't get it to work with OAuth2.

Here's the OAuthConfig code that was working fine:

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
  }; 
}  

I've successfully connected the github library for OAuth2. However, what's different about the instructions provided there, and on many other sites, is that they assume that the code will be deployed as a web service where a user is prompted to manually click to authorize the request. In my case the code will be saved on a Google Apps Script file, and the Cloud Printer is on the same Google account, so I never needed this manual intervention or back & forth with my original OAuthconfig.

My first attempt by adapting the instructions was:

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');
  }
}

But this gives me an error "Access not granted or expired" when it tries to run the line:

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

So I found a apps ScriptApp Method getOAuthToken which seemed like it might give me the token I need. I replaced the above line with:

var accessToken = ScriptApp.getOAuthToken();

And the code executes but my response from the server is "Error 403 User credentials required".

Here's my third attempt based on @Mogsdad's suggestion:

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);
}

I've tried a number of variations, including creating a Developer Console Project and using the Client ID provided there, but I keep getting stuck at these two issues (access not granted, or credentials required). If anyone can provide any help I'd really appreciate it.

解决方案

Here are the steps that allowed me to connect Google Apps Script to Google Cloud Print, so I could then submit GCP jobs (these steps are all started from within Google Apps Script):

  1. Add the OAuth2 library (https://github.com/googlesamples/apps-script-oauth2) to your Google Apps Script by going to: Resources > Libraries > Find Library MswhXl8fVhTFUH_Q3UOJbXvxhMjh3Sh48 > Select
  2. Create new web application in Developer Console Resources > Developer Console Project > Click the project link > APIs & Auth > Credentials > Add Credentials > OAuth2.0 Client ID > Web Application > Set Authorized redirect URIs to the format
    https://script.google.com/macros/d/{PROJECT KEY}/usercallback where project key is under File > Project Properties and copy your client ID and client secret
  3. Add the ID and Secret to "getCloudPrintService()" code below (replace client_id and client_secret)
  4. Go to Run > ShowURL and authorize the script.
  5. Open the Logger (Cmd + Enter), copy the URL and paste it in a new browser tab to complete the authorization.
  6. Go to https://www.google.com/cloudprint/#printers , select your printer, click details, expand advanced details, and copy your Printer ID (it will be of the format 555aa555-5a55-5555-5555-55555a55a555)
  7. Add the printer id to "printGoogleDocument()" code below (replace myPrinterId)

This resource was helpful in figuring the steps out: http://ctrlq.org/code/20061-google-cloud-print-with-apps-script, and you may also find these links helpful:

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;
}

这篇关于使用Google云打印的OAuth2的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆