2016-12-28 8 views
1

GoogleスプレッドからGoogleスライドを生成しようとしています。問題のないSheetsスクリプトを使用しましたが、Googleスライドを認証しようとすると、Oauth権限のプロンプトが表示された後に、このエラーが表示されています。 Developers ConsoleでGoogleスライドAPIとドライブAPIが有効になっていることを確認しました。403「GoogleスライドAPIはプロジェクトで使用されていません...前または使用できません」

"リクエストが失敗しました...返されたコード403:切り詰められたサーバーの応答:{" error ":{" code ":403、" message ":" GoogleスライドAPIはプロジェクトproject-id- ...前またはそれがdisab ...(行93、ファイル "コード")

のコードが失敗しました。 。クライアント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). 
     // 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); 
} 
+0

正しいプロジェクトIDに対してAPIを有効にしていますか?デベロッパーコンソールのプロジェクトプルダウンから選択しますか? (間違ったプロジェクトでAPIを有効にする前にこのエラーが発生していたので、これについて言及します) – Bardy

+0

はい、このアカウントの唯一のプロジェクトであり、プロジェクトのAPIを有効にする方法を理解するのに時間がかかりました。しかし、提案のおかげで –

答えて

1

編集:私はこのこのコードsnippと協力してしまった et:

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

私は、クライアントIDと秘密があなたのプロジェクトから来ていないと思います。 your project's credentials pageにアクセスして、「OAuth 2.0クライアントID」の下に一致するクライアントIDがあるかどうかを確認することで確認できます。そのクライアントIDを含むプロジェクトでは、Slides APIを有効にする必要があります。

注::使用している/ export/pngエンドポイントは、ドキュメント化された/サポートされているGoogle APIではないため、今後名前が変更されるか、破損する可能性があります。 Slides APIでスライドのPNGをレンダリングするための公式のAPIに興味がある場合は、issue on the trackerに従ってください。


前のコンテンツ:

あなたのコードはまた、あなたがからコピーしているスニペットよりもわずかに異なっています。認証ヘッダーの値を取得するのにScriptApp.getOAuthToken()を使用していますが、別のgetService().getAccessToken()関数を呼び出すことになります。あなたはOAuthトークンを生成するためにapps-script-oauth2ライブラリを使用しているようです。その場合、スクリプトに添付されている同じプロジェクトである必要はないため、OAuth2.createServiceに渡すclientIdとクライアントのシークレットを生成した開発者コンソールプロジェクトでSlides APIが有効になっていることを確認します。 ScriptApp.getOAuthToken()への切り替えがオプションであれば、それも有効です。

これで問題が解決しない場合は、さらにコードを提供してください。貼り付けたスニペットはエラーメッセージと一致していないようです。エラーが示すように、コードがslides.googleapis.comではなくdocs.google.comにリクエストしているようです。

+0

コードが追加されました。あなたが言うように、私はClientIDとクライアントの秘密を制御することを可能にする関数のScriptApp呼び出しを置き換えました。 スニペットが正しいです。テンプレートとして使用するスライドがhttps://docs.google.com/presentation/d/1V7k5UTjにあるため、docs.google.comからリクエストしていますが、これはリダイレクト。 –

+0

@Bruno、実際に 'downloadSlide'と呼ばれる部分を追加するのを忘れないでください。私はあなたの全体のスクリプトで再現しようとすることができます。私はまだクライアントのID /シークレットは、あなたが期待していないプロジェクトに属しているとは思わないAPIが有効になっている。 –

+0

あなたは問題ありませんが、downloadSlideを呼び出す関数が間違っています。 main関数は有効なIDを持つdownloadSlidesを呼び出します(2回検証され、最後にはIDをhttps://docs.google.com/presentation/d/に追加して正常に動作します)。 私はプロジェクトをダブルチェックしました。これはアカウントに関連付けられた唯一のプロジェクトで、GoogleドライブとGoogleスライドAPIの両方が有効になっていると報告しています。 私はまだ問題の鍵は「最初に使用された」側のエラーメッセージであり、無効ではないと思います。 –

-1

これはOPの質問に直接答えではないに設定しなければならなかったが、直接、第一の部分に対処しないのOAuthの認証情報の正規リダイレクトURIの設定、とありました最初の文の「GoogleスプレッドからGoogleスライドを生成しようとしています....」これは、video (and accompanying blog post [s]を作成した正確な使用例です。注:ポストのペイロードはJSONですが、動画の例はPythonで書かれているので、Python以外の開発者は単純に擬似コードとして使用できます)。

+0

私は自分のコードを実装する前にそれを見ました...いい言及ですが、あなたが言うように質問への答えではありません –

関連する問題