“Google幻灯片API尚未用于项目...之前或已禁用”的403错误消息 [英] 403 error with message "Google Slides API has not been used in project ... before or it is disabled"

查看:132
本文介绍了“Google幻灯片API尚未用于项目...之前或已禁用”的403错误消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图从Google表格生成Google幻灯片;已经使用Sheets脚本没有问题,但是当我尝试包含Google幻灯片时,在验证并获得Oauth权限提示后,我收到此错误,我找不到任何参考;我已确保在开发者控制台中启用Google幻灯片API和云端硬盘API。



https://slides.googleapis.com/v1/presentations/ ...返回代码403.截断的服务器响应:{error:{code :403,message:Google幻灯片API尚未用于project-id -...之前,或者disab ...(使用muteHttpExceptions选项检查完整响应)(第93行,文件Code )



代码失败如下,失败的函数是从。客户端ID和秘密被定义,只是为了安全而被省略

  //来自https://mashe.hawksey.info/2015/10/setting-up-oauth2-access-with-google-apps-script-blogger-api-example / 

函数getService(){
// C以给定的名称创建一个新的服务。该名称将在
//持久授权令牌时使用,因此请确保它在属性存储区的
//范围内是唯一的。
返回OAuth2.createService('slidesOauth')

//设置所有Google服务的端点URL。
.setAuthorizationBaseUrl('https://accounts.google.com/o/oauth2/auth')
.setTokenUrl('https://accounts.google.com/o/oauth2/token')


//从Google Developers Console设置客户端ID和密码。
.setClientId(CLIENT_ID)
.setClientSecret(CLIENT_SECRET)

//在脚本中设置回调函数的名称,引用
//应该被调用完成OAuth流程。
.setCallbackFunction('authCallback')

//设置应该保留授权令牌的属性存储区。
.setPropertyStore(PropertiesService.getUserProperties())

//将范围设置为请求(用于Google服务的空格分隔)。
//这是博客只读的写入权限范围是:
// https://www.googleapis.com/auth/blogger
.setScope('https:// www。 googleapis.com/auth/blogger.readonly')

//以下是Google特定的OAuth2参数。

//设置登录提示,这将阻止帐户选择器屏幕
//显示给使用多个帐户登录的用户。
.setParam('login_hint',Session.getActiveUser()。getEmail())

//请求脱机访问。
.setParam('access_type','offline')

//每次强制批准提示。这对于测试
//很有用,但在生产应用程序中不可取。
.setParam('approval_prompt','force');
}

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

//从https://stackoverflow.com/questions/31662455/how-to-download-google-slides-as-images/40678925#40678925

function downloadPresentation(id){
var slideIds = getSlideIds(id); $ i
$ b(var i = 0,slideId; slideId = slideIds [i]; i ++){
downloadSlide('Slide'+(i + 1),id,slideId);
}
}
函数downloadSlide(name,presentationId,slideId){
var url ='https://docs.google.com/presentation/d/'+ presentationId +
'/ export / png?id ='+ presentationId +'& pageid ='+ slideId;
var options = {
headers:{
授权:'Bearer'+ getService()。getAccessToken()
}
};
var response = UrlFetchApp.fetch(url,options); //这是失败的行93
var image = response.getAs(MimeType.PNG);
image.setName(name);
DriveApp.createFile(image);
}


编辑:
我得到了这个代码片段的工作:

  var CLIENT_ID ='...'; 
var CLIENT_SECRET ='...';
var PRESENTATION_ID ='...';

//来自https://mashe.hawksey.info/2015/10/setting-up-oauth2-access-with-google-apps-script-blogger-api-example/

函数getService(){
//使用给定名称创建一个新服务。该名称将在
//持久授权令牌时使用,因此请确保它在属性存储区的
//范围内是唯一的。
返回OAuth2.createService('slidesOauth')

//设置所有Google服务的端点URL。
.setAuthorizationBaseUrl('https://accounts.google.com/o/oauth2/auth')
.setTokenUrl('https://accounts.google.com/o/oauth2/token')


//从Google Developers Console设置客户端ID和密码。
.setClientId(CLIENT_ID)
.setClientSecret(CLIENT_SECRET)

//在脚本中设置回调函数的名称,引用
//应该被调用完成OAuth流程。
.setCallbackFunction('authCallback')

//设置应该保留授权令牌的属性存储区。
.setPropertyStore(PropertiesService.getUserProperties())

//将范围设置为请求(用于Google服务的空格分隔)。
.setScope('https://www.googleapis.com/auth/drive')

//以下是Google特定的OAuth2参数。

//设置登录提示,这将阻止帐户选择器屏幕
//显示给使用多个帐户登录的用户。
.setParam('login_hint',Session.getActiveUser()。getEmail())

//请求脱机访问。
.setParam('access_type','offline')

//每次强制批准提示。这对于测试
//很有用,但在生产应用程序中不可取。
.setParam('approval_prompt','force');
}

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

function getSlideIds(presentationId){
var url ='https://slides.googleapis.com/v1/presentations/'+ presentationId;
var options = {
headers:{
授权:'Bearer'+ getService()。getAccessToken()
}
};
var response = UrlFetchApp.fetch(url,options);

var slideData = JSON.parse(response);
return slideData.slides.map(function(slide){
return slide.objectId;
});
}


//从http://stackoverflow.com/questions/31662455/how-to-download-google-slides-as-images/40678925#40678925

function downloadPresentation(id){
var slideIds = getSlideIds(id); $ i
$ b(var i = 0,slideId; slideId = slideIds [i]; i ++){
downloadSlide('Slide'+(i + 1),id,slideId);



函数downloadSlide(name,presentationId,slideId){
var url ='https://docs.google.com/presentation/d/ '+ presentationId +
'/ export / png?id ='+ presentationId +'& pageid ='+ slideId;
var options = {
headers:{
授权:'Bearer'+ getService()。getAccessToken()
}
};
var response = UrlFetchApp.fetch(url,options); //这是失败的行93
var image = response.getAs(MimeType.PNG);
image.setName(name);
DriveApp.createFile(image);


函数start(){
var service = getService();
var authorizationUrl = service.getAuthorizationUrl();
Logger.log('打开以下URL并重新运行脚本:%s',
authorizationUrl);

if(service.hasAccess()){
downloadPresentation(PRESENTATION_ID);
}
}

我猜客户端ID和秘密来自你认为他们来自的项目。您可以访问项目的凭证页面并查看是否存在匹配的客户端ID列在'OAuth 2.0客户端ID'下。包含该客户ID的项目需要启用Slides API。



另请注意:您使用的/ export / png端点isnt一个记录/支持的Google API,因此它可能会在未来重新命名或中断。如果您对通过幻灯片API获取幻灯片PNG的官方API感兴趣,请按照以下跟踪器上的问题




以前的内容:

您的代码与您要复制的代码段略有不同。它使用 ScriptApp.getOAuthToken()来获取授权头的值,但是您调用了另一个 getService()。getAccessToken()函数。看起来您正在使用 apps-script-oauth2 库来生成您的OAuth令牌。如果是这种情况,请确认在开发者控制台项目上启用了Slides API,该项目生成了您传递给 OAuth2.createService 的clientId和客户端密钥,因为它不是必须与您的脚本相同的项目。如果切换到 ScriptApp.getOAuthToken()是您的一个选项,那也可以。

不解决你的问题,提供更多的代码?您粘贴的代码段看起来与错误消息不匹配,因为您的代码似乎是向docs.google.com发出请求,而不是错误中提到的slides.googleapis.com。

I am trying to generate Google Slides from Google Sheets; have used Sheets script with no issues, but when I try to include Google Slides, after authenticating and getting Oauth permissions prompt, I am getting this error that I cannot find any reference for; I have made sure Google Slides API and Drive API are enabled in the Developers Console.

"Request failed for https://slides.googleapis.com/v1/presentations/... returned code 403. Truncated server response: { "error": { "code": 403, "message": "Google Slides API has not been used in project project-id-... before or it is disab... (use muteHttpExceptions option to examine full response) (line 93, file "Code")"

The code failing is as follows, the function that is failing was copied from How to download Google Slides as images?. Client ID and secret are defined, ommitted just for security

// from https://mashe.hawksey.info/2015/10/setting-up-oauth2-access-with-google-apps-script-blogger-api-example/

function getService() {
  // Create a new service with the given name. The name will be used when
  // persisting the authorized token, so ensure it is unique within the
  // scope of the property store.
  return OAuth2.createService('slidesOauth')

      // Set the endpoint URLs, which are the same for all Google services.
      .setAuthorizationBaseUrl('https://accounts.google.com/o/oauth2/auth')
      .setTokenUrl('https://accounts.google.com/o/oauth2/token')


      // Set the client ID and secret, from the Google Developers Console.
      .setClientId(CLIENT_ID)
      .setClientSecret(CLIENT_SECRET)

      // Set the name of the callback function in the script referenced
      // above that should be invoked to complete the OAuth flow.
      .setCallbackFunction('authCallback')

      // Set the property store where authorized tokens should be persisted.
      .setPropertyStore(PropertiesService.getUserProperties())

      // Set the scopes to request (space-separated for Google services).
      // this is blogger read only scope for write access is:
      // https://www.googleapis.com/auth/blogger
      .setScope('https://www.googleapis.com/auth/blogger.readonly')

      // Below are Google-specific OAuth2 parameters.

      // Sets the login hint, which will prevent the account chooser screen
      // from being shown to users logged in with multiple accounts.
      .setParam('login_hint', Session.getActiveUser().getEmail())

      // Requests offline access.
      .setParam('access_type', 'offline')

      // Forces the approval prompt every time. This is useful for testing,
      // but not desirable in a production application.
      .setParam('approval_prompt', 'force');
}

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

// from https://stackoverflow.com/questions/31662455/how-to-download-google-slides-as-images/40678925#40678925

function downloadPresentation(id) {
  var slideIds = getSlideIds(id); 

  for (var i = 0, slideId; slideId = slideIds[i]; i++) {
    downloadSlide('Slide ' + (i + 1), id, slideId);
  }
}
function downloadSlide(name, presentationId, slideId) {
  var url = 'https://docs.google.com/presentation/d/' + presentationId +
    '/export/png?id=' + presentationId + '&pageid=' + slideId; 
  var options = {
    headers: {
      Authorization: 'Bearer ' + getService().getAccessToken()
    }
  };
  var response = UrlFetchApp.fetch(url, options); // This is the failing line 93
  var image = response.getAs(MimeType.PNG);
  image.setName(name);
  DriveApp.createFile(image);
}

解决方案

EDIT: I got this working with this code snippet:

var CLIENT_ID = '...';
var CLIENT_SECRET = '...';
var PRESENTATION_ID = '...';

// from https://mashe.hawksey.info/2015/10/setting-up-oauth2-access-with-google-apps-script-blogger-api-example/

function getService() {
  // Create a new service with the given name. The name will be used when
  // persisting the authorized token, so ensure it is unique within the
  // scope of the property store.
  return OAuth2.createService('slidesOauth')

      // Set the endpoint URLs, which are the same for all Google services.
      .setAuthorizationBaseUrl('https://accounts.google.com/o/oauth2/auth')
      .setTokenUrl('https://accounts.google.com/o/oauth2/token')


      // Set the client ID and secret, from the Google Developers Console.
      .setClientId(CLIENT_ID)
      .setClientSecret(CLIENT_SECRET)

      // Set the name of the callback function in the script referenced
      // above that should be invoked to complete the OAuth flow.
      .setCallbackFunction('authCallback')

      // Set the property store where authorized tokens should be persisted.
      .setPropertyStore(PropertiesService.getUserProperties())

      // Set the scopes to request (space-separated for Google services).
      .setScope('https://www.googleapis.com/auth/drive')

      // Below are Google-specific OAuth2 parameters.

      // Sets the login hint, which will prevent the account chooser screen
      // from being shown to users logged in with multiple accounts.
      .setParam('login_hint', Session.getActiveUser().getEmail())

      // Requests offline access.
      .setParam('access_type', 'offline')

      // Forces the approval prompt every time. This is useful for testing,
      // but not desirable in a production application.
      .setParam('approval_prompt', 'force');
}

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

function getSlideIds(presentationId) {
  var url = 'https://slides.googleapis.com/v1/presentations/' + presentationId;
  var options = {
    headers: {
      Authorization: 'Bearer ' + getService().getAccessToken()
    }
  };
  var response = UrlFetchApp.fetch(url, options);

  var slideData = JSON.parse(response);
  return slideData.slides.map(function(slide) {
    return slide.objectId;
  });
}


// from http://stackoverflow.com/questions/31662455/how-to-download-google-slides-as-images/40678925#40678925

function downloadPresentation(id) {
  var slideIds = getSlideIds(id); 

  for (var i = 0, slideId; slideId = slideIds[i]; i++) {
    downloadSlide('Slide ' + (i + 1), id, slideId);
  }
}

function downloadSlide(name, presentationId, slideId) {
  var url = 'https://docs.google.com/presentation/d/' + presentationId +
    '/export/png?id=' + presentationId + '&pageid=' + slideId; 
  var options = {
    headers: {
      Authorization: 'Bearer ' + getService().getAccessToken()
    }
  };
  var response = UrlFetchApp.fetch(url, options); // This is the failing line 93
  var image = response.getAs(MimeType.PNG);
  image.setName(name);
  DriveApp.createFile(image);
}

function start() {
  var service = getService();
  var authorizationUrl = service.getAuthorizationUrl();
  Logger.log('Open the following URL and re-run the script: %s',
      authorizationUrl);

  if (service.hasAccess()) {
    downloadPresentation(PRESENTATION_ID);
  }
}

I'd guess that the client ID and secret don't come from project you think they come from. You can verify this by visiting your project's credentials page and seeing if there's a matching client ID listed under 'OAuth 2.0 client IDs'. The project containing that client ID needs to have the Slides API enabled.

Also note: the /export/png endpoint you're using isnt a documented/supported Google API so it may be renamed or break in the future. If you're interested in an official API for getting rendered PNGs of slides via the Slides API, follow along with this issue on the tracker.


Previous content:

Your code is also slightly different than the snippet you're copying from. It's using ScriptApp.getOAuthToken() to get the value of the authorization header, but you're calling a different getService().getAccessToken() function. That looks like you're using the apps-script-oauth2 library to generate your OAuth token. If that's the case, confirm that the Slides API is enabled on the Developer console project that generated the clientId and client secret you're passing in to OAuth2.createService, as its not necessarily the same project attached to your script. If switching to ScriptApp.getOAuthToken() is an option for you, that may work as well.

If that doesnt fix your issue, mind providing more of your code? The snippet you've pasted doesn't seem to match the error message, as your code appears to be making a request to docs.google.com, not slides.googleapis.com as mentioned in the error.

这篇关于“Google幻灯片API尚未用于项目...之前或已禁用”的403错误消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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