Google スライド #複数ページ: PNGエクスポート

Google スライド #複数ページ: PNGエクスポート

translate Google Slides #Pages: Export as PNG

スライドページをPNG画像に変換し、ファイル型データ項目に格納します。ページID (Object-ID) が未指定(空白)の場合は「最終ページのみ」をPNG化します。”all” が指定された場合は「全ページ」をPNG化します。ダウンロード用URL(30分有効)の取得にも対応します。

Auto Step icon
Configs for this Auto Step
AuthzConfU
U: HTTP認証設定を選択してください *
StrConfA1
A: Drive内でのファイルID(FILE-ID)をセットしてください *#{EL}
StrConfB1
B: PNG化するスライドページの ID を各行にセットしてください(空白:最終ページのみ、”all”: 全ページ)#{EL}
SelectConfC1
C1: PNG画像が格納されるファイル群型データ項目を選択してください(追加) *
StrConfC2
C2: ファイル名を付けて格納したい場合はファイル名をセットしてください#{EL}
SelectConfD
D: ダウンロード用URLが格納される文字列型データ項目を選択してください(更新)
Script (click to open)
// Script Example of Business Process Automation
// for 'engine type: 3' ("GraalJS standard mode")
// cf. 'engine type: 2' ("GraalJS Nashorn compatible mode") (renamed from "GraalJS" at 20230526)

//////// START "main()" /////////////////////////////////////////////////////////////////
main();
function main(){

  //// == Config Retrieving / 工程コンフィグの参照 ==
  const qAuthzSetting  = configs.getObject("AuthzConfU");             /// REQUIRED
  if (qAuthzSetting === null) {
    throw new Error("\n AutomatedTask ConfigError: Config {AuthzConfU} invalid (OAUTH2) \n");
  }
  engine.log(" AutomatedTask Config: Authz Setting: " + qAuthzSetting.getName());

  const strInputfileId = configs.get("StrConfA1") || "";              /// REQUIRED
  if (strInputfileId === "") {
    throw new Error("\n AutomatedTask ConfigError: Config {A: FileID} is empty \n");
  }

  // B: 改行区切りの Page ID(未指定なら最終ページのみ)
  const strPageIdsText = configs.get("StrConfB1") || "";              // NotRequired (multi-line)

  const filesPocketImg = configs.getObject("SelectConfC1");           /// REQUIRED (ファイル型データ項目)
  let   strSaveas      = configs.get("StrConfC2") || "";              // NotRequired
  const pocketUrlData  = configs.getObject("SelectConfD");            // NotRequired(文字列データ項目)



  //// == Data Retrieving / ワークフローデータの参照 ==
  let filesAttached = engine.findData(filesPocketImg); // java.util.ArrayList
  if (filesAttached === null) {
    engine.log(" AutomatedTask FilesArray {C1} (empty)");
    filesAttached = new java.util.ArrayList();
  } else {
    engine.log(" AutomatedTask FilesArray {C1}: " + filesAttached.size() + " files");
  }



  //// == Calculating / 演算 ==

  /// Get Presentation Details (Title, List of Pages)
  // Google Slides API: presentations/get
  // https://developers.google.com/slides/reference/rest/v1/presentations/get
  const request0uri = "https://slides.googleapis.com/v1/presentations/" + strInputfileId;
  let request0 = httpClient.begin().authSetting(qAuthzSetting); // with "Authorization: Bearer XX"

  engine.log(" AutomatedTask ApiRequest0 Start: " + request0uri);
  const response0     = request0.get(request0uri);
  const response0code = (response0.getStatusCode() + "");
  const response0body = (response0.getResponseAsString() + "");
  engine.log(" AutomatedTask ApiResponse Status: " + response0code);
  if (response0code !== "200") {
    throw new Error("\n AutomatedTask UnexpectedResponseError: " + response0code + "\n" + response0body + "\n");
  }

  const response0obj  = JSON.parse(response0body);
  const strFileTitle  = response0obj.title || "slides";
  const slidesArray   = (response0obj.slides && Array.isArray(response0obj.slides)) ? response0obj.slides : [];
  engine.log(" AutomatedTask ApiResponse File Title: " + strFileTitle);

  /// Determine which pages to process
  let pageIdsToProcess = [];
  const trimmedPageIds = strPageIdsText.trim();

  if (trimmedPageIds === "") {
    const lastSlide = slidesArray[slidesArray.length - 1];
    if (lastSlide && lastSlide.objectId) {
      pageIdsToProcess = [ lastSlide.objectId ];
      engine.log(" AutomatedTask Config {B}: Empty. Processing LAST page only: " + lastSlide.objectId);
    } else {
      engine.log(" AutomatedTask Warning: Could not identify the last slide ID.");
      return;
    }
  } else if (trimmedPageIds.toLowerCase() === "all") {
    engine.log(' AutomatedTask Config {B}: "all" specified. Processing ALL pages.');
    for (const slide of slidesArray) {
      if (slide && slide.objectId) pageIdsToProcess.push(slide.objectId);
    }
  } else {
    engine.log(" AutomatedTask Config {B}: Processing specified pages.");
    pageIdsToProcess = trimmedPageIds
      .split(/\r?\n/)
      .map(id => id.trim())
      .filter(id => id !== "");
  }

  if (pageIdsToProcess.length === 0) {
    engine.log(" AutomatedTask Warning: No pages to process.");
    return; // Exit if there are no pages to process
  }

  engine.log(" AutomatedTask Processing " + pageIdsToProcess.length + " page(s).");

  let strContentUrl = "";
  let successCount  = 0;

  // File name base
  // 実体はPNGなので、拡張子は .png に統一(ユーザーが別拡張子を入れても .png に矯正)
  const baseName = (strSaveas === "")
      ? strFileTitle
      : (strSaveas.includes(".") ? strSaveas.substring(0, strSaveas.lastIndexOf(".")) : strSaveas);
  const extension = ".png";

  // --- 各ページのサムネイルPNG生成 ---
  let pageIndex = 0;
  for (const pageId of pageIdsToProcess) {
    pageIndex++;
    engine.log(" AutomatedTask Processing page " + pageIndex + "/" + pageIdsToProcess.length + ": " + pageId);

    // Google Slides API: presentations.pages/getThumbnail
    // https://developers.google.com/slides/reference/rest/v1/presentations.pages/getThumbnail
    const request1uri = "https://slides.googleapis.com/v1/presentations/" + strInputfileId + "/pages/" + pageId + "/thumbnail";
    let request1 = httpClient.begin().authSetting(qAuthzSetting);

    engine.log(" AutomatedTask ApiRequest1 Start: " + request1uri);
    const response1     = request1.get(request1uri);
    const response1code = (response1.getStatusCode() + "");
    const response1body = (response1.getResponseAsString() + "");
    engine.log(" AutomatedTask ApiResponse Status: " + response1code);

    if (response1code !== "200") {
      engine.log(" AutomatedTask Error generating thumbnail for page " + pageId + ". Skipping. Response: " + response1body);
      continue; // 次ページへ
    }

    const response1obj = JSON.parse(response1body);
    if (!response1obj || !response1obj.contentUrl) {
      engine.log(" AutomatedTask Error: Missing contentUrl for page " + pageId + ". Skipping.");
      continue;
    }

    // PNG取得(contentUrl)
    const request2uri = response1obj.contentUrl;
    let request2 = httpClient.begin();
    engine.log(" AutomatedTask ApiRequest2 Start: " + request2uri);
    const response2     = request2.get(request2uri);
    const response2code = (response2.getStatusCode() + "");
    engine.log(" AutomatedTask ApiResponse Status: " + response2code);

    if (response2code !== "200") {
      engine.log(" AutomatedTask Error fetching PNG content for page " + pageId + ". Skipping. Response: " + response2.getResponseAsString());
      continue;
    }

    // ファイル名(複数ページ時は連番)
    const finalFileName = (pageIdsToProcess.length > 1)
      ? (baseName + "_" + (successCount + 1) + extension)
      : (baseName + extension);

    engine.log(" AutomatedTask Saving file as: " + finalFileName);
    const qfile = new com.questetra.bpms.core.event.scripttask.NewQfile(
      finalFileName,
      response2.getContentType(),
      response2.getResponse()
    );
    filesAttached.add(qfile);

    // URLは改行区切りで「追記」
    strContentUrl += request2uri + "\n";
    successCount++;
  }

  //// == Data Updating / ワークフローデータへの代入 ==
  engine.setData(filesPocketImg, filesAttached);
  if (pocketUrlData !== null && strContentUrl !== "") {
    engine.setData(pocketUrlData, strContentUrl.trim()); // 改行区切り
  }

  engine.log(" AutomatedTask Done. Saved files: " + successCount + " / " + pageIdsToProcess.length);
}





/*
▼NOTES:
- If placed this [Automated Step] in the Workflow, an API request will be threw each time a Process arrives.
    - "Questetra BPM Suite" server (client side) ⇒ "Google Slides" API (server side)
    - PNG images (the specified slides converted) etc will be responded (API response).
    - They will be stored in a FILE-type process data item in Questetra BPM Suite.
- The slide page to be imaged is specified by its page ID (Object-ID). (One page ID per line.)
    - If no page is specified, only the last page will be imaged.
    - If "all" is specified as the page, all pages will be imaged.
- For "File ID," refer to the URL when viewing the slide file.
    - docs.google.com/presentation/d/**1p33hGJFUNYixBmMeaV81nsOVYGUUrZIFyErinFp3CI8**
- For "Slide ID" (Slide Object-ID), refer to the URL when viewing the slide.
    - docs.google.com/presentation/d/1p33hGJFUNYixBmMeaV81nsOVYGUUrZIFyErinFp3CI8/edit?slide=id.**g613777c84a_0_0**
    - docs.google.com/presentation/d/1p33hGJFUNYixBmMeaV81nsOVYGUUrZIFyErinFp3CI8/edit#slide=id.**g613777c84a_0_0**
- Workflow App that includes this [Automated Step] require [HTTP Authentication Settings].
    - Create [Authentication Information] (OAuth client) in the "Google Cloud Console."
        - https://console.cloud.google.com/apis/credentials
        - Redirect URI: `https://s.questetra.net/oauth2callback`
        - ⇒ Obtain a [Client ID] and [Client Secret]
    - Configure the access token acquisition method in the [HTTP Authentication Settings] of this WorkflowApp.
        - Set the [Authorization Endpoint URL]:
            - `https://accounts.google.com/o/oauth2/auth?access_type=offline&approval_prompt=force`
        - Set the [Token Endpoint URL]:
            - `https://accounts.google.com/o/oauth2/token`
        - Example [Scope] setting:
            - `https://www.googleapis.com/auth/presentations`
        - (Other [Scope] setting examples):
            - `https://www.googleapis.com/auth/drive`
            - `https://www.googleapis.com/auth/drive.file`
            - `https://www.googleapis.com/auth/spreadsheets https://www.googleapis.com/auth/presentations`
        - ⇒ Click [Get Token]. (You will grant the API requests.)
            - The refresh token will be stored.
            - Refresh token → Access token → API communication

▼NOTES-ja:
- この[自動工程]をワークフロー途中に配置すれば、案件(プロセス)が到達するたびに「APIリクエスト」が発生します
    - "Questetra BPM Suite" サーバ(クライアント側) ⇒ "Google スライド" の API(サーバ側)
    - PNG 画像(指定したスライドが画像変換されたファイル)等がレスポンスされます (APIレスポンス)
    - Questetra BPM Suite の FILE 型プロセスデータ項目に格納されます
- 画像化するページは、ページID(Object-ID)で指定します。(1行につき1ページID)
    - ページ指定が無い場合、最終ページのみが画像化されます
    - ページ指定に "all" が指定された場合、全てのページが画像化されます。
- "ファイルID" は、スライドファイルを表示した際の URL を参照してください
    - docs.google.com/presentation/d/**1p33hGJFUNYixBmMeaV81nsOVYGUUrZIFyErinFp3CI8**
- "スライドID"(Slide Object-ID)は、当該スライドを表示した際の URL を参照してください
    - docs.google.com/presentation/d/1p33hGJFUNYixBmMeaV81nsOVYGUUrZIFyErinFp3CI8/edit?slide=id.**g613777c84a_0_0**
    - docs.google.com/presentation/d/1p33hGJFUNYixBmMeaV81nsOVYGUUrZIFyErinFp3CI8/edit#slide=id.**g613777c84a_0_0**
- この[自動工程]を含むワークフローアプリには、[HTTP 認証設定]が必要です
    - "Google Cloud コンソール" にて、[認証情報](OAuthクライアント)を作成します
        - https://console.cloud.google.com/apis/credentials
        - リダイレクトURI: `https://s.questetra.net/oauth2callback`
        - ⇒[クライアントID](ClientId)と[クライアントシークレット] (Client Secret) を取得
    - ワークフローアプリ等の[HTTP 認証設定]にて、アクセストークン取得方法を設定します
        - [認可エンドポイントURL](Authorization Endpoint URL) の設定:
            - `https://accounts.google.com/o/oauth2/auth?access_type=offline&approval_prompt=force`
        - [トークンエンドポイントURL](Token Endpoint URL) の設定:
            - `https://accounts.google.com/o/oauth2/token`
        - [スコープ]設定例:
            - `https://www.googleapis.com/auth/presentations`
        - (他の[スコープ]設定例):
            - `https://www.googleapis.com/auth/drive`
            - `https://www.googleapis.com/auth/drive.file`
            - `https://www.googleapis.com/auth/spreadsheets https://www.googleapis.com/auth/presentations`
        - ⇒[トークンの取得](Get Token) をクリックします。(「APIリクエスト」を許諾します)
            - リフレッシュトークン (Refresh Token) が格納されます。
            - リフレッシュトークン (Refresh Token) → アクセストークン (Access Token)  → API通信

▼APPENDIX:
- Requests for a large number of images (e.g., 10 or more) may result in API communication timeouts.
    - If communication fails, no response images will be saved.
- Backward compatible
    - Also works as a replacement for `Google Slides #Page: PNG Export`
    - https://support.questetra.com/addons/google-slides-page-export-as-png-2021/
- The download URL (expires in 30 minutes) to the image is tagged with the account of the requester.
    - Anyone with the URL effectively accesses the image as the original requester.
    - Access to the image may be lost if the presentation’s sharing settings change.
- The extension is always forced to `.png`.


▼APPENDIX-ja:
- 大量画像(10枚以上指定など)のリクエストは API 通信がタイムアウトする場合があります。
    - 通信に失敗した場合、レスポンス画像は何も保存されません。
- 上位互換
    - `Google スライド #ページ: PNGエクスポート` の置き換えでも動作します
    - https://support.questetra.com/ja/addons/google-slides-page-export-as-png-2021/
- ダウンロード用URL(30分間のみ有効)はAPI通信の認可者に紐づけられます。
    - URLを知っている人は誰でも画像にアクセスできます。そして認可者によるアクセスと見なされます。
    - なお、ファイルの共有設定が変更されるとダウンロード用URLは無効になります。
- 拡張子は常に `.png` に矯正されます。

*/

Download

warning 自由改変可能な JavaScript (ECMAScript) コードです。いかなる保証もありません。
(アドオン自動工程のインストールは Professional editionでのみ可能です)

Notes

  • この[自動工程]をワークフロー途中に配置すれば、案件(プロセス)が到達するたびに「APIリクエスト」が発生します
    • “Questetra BPM Suite” サーバ(クライアント側) ⇒ ”Google スライド” の API(サーバ側)
    • PNG 画像(指定したスライドが画像変換されたファイル)等がレスポンスされます (APIレスポンス)
    • Questetra BPM Suite の FILE 型プロセスデータ項目に格納されます
  • 画像化するページは、ページID(Object-ID)で指定します。(1行につき1ページID)
    • ページ指定が無い場合、最終ページのみが画像化されます
    • ページ指定に “all” が指定された場合、全てのページが画像化されます。
  • “ファイルID” は、スライドファイルを表示した際の URL を参照してください
    • docs.google.com/presentation/d/1p33hGJFUNYixBmMeaV81nsOVYGUUrZIFyErinFp3CI8
  • “スライドID”(Slide Object-ID)は、当該スライドを表示した際の URL を参照してください
    • docs.google.com/presentation/d/1p33hGJFUNYixBmMeaV81nsOVYGUUrZIFyErinFp3CI8/edit?slide=id.g613777c84a_0_0
    • docs.google.com/presentation/d/1p33hGJFUNYixBmMeaV81nsOVYGUUrZIFyErinFp3CI8/edit#slide=id.g613777c84a_0_0
  • この[自動工程]を含むワークフローアプリには、[HTTP 認証設定]が必要です
    • “Google Cloud コンソール” にて、[認証情報](OAuthクライアント)を作成します
    • ワークフローアプリ等の[HTTP 認証設定]にて、アクセストークン取得方法を設定します
      • [認可エンドポイントURL](Authorization Endpoint URL) の設定:
        • https://accounts.google.com/o/oauth2/auth?access_type=offline&approval_prompt=force
      • [トークンエンドポイントURL](Token Endpoint URL) の設定:
        • https://accounts.google.com/o/oauth2/token
      • [スコープ]設定例:
        • https://www.googleapis.com/auth/presentations
      • (他の[スコープ]設定例):
        • https://www.googleapis.com/auth/drive
        • https://www.googleapis.com/auth/drive.file
        • https://www.googleapis.com/auth/spreadsheets https://www.googleapis.com/auth/presentations
      • ⇒[トークンの取得](Get Token) をクリックします。(「APIリクエスト」を許諾します)
        • リフレッシュトークン (Refresh Token) が格納されます。
        • リフレッシュトークン (Refresh Token) → アクセストークン (Access Token) → API通信

Capture

Appendix

  • 大量画像(10枚以上指定など)のリクエストは API 通信がタイムアウトする場合があります。
    • 通信に失敗した場合、レスポンス画像は何も保存されません。
  • 上位互換
  • ダウンロード用URL(30分間のみ有効)はAPI通信の認可者に紐づけられます。
    • URLを知っている人は誰でも画像にアクセスできます。そして認可者によるアクセスと見なされます。
    • なお、ファイルの共有設定が変更されるとダウンロード用URLは無効になります。
  • 拡張子は常に .png に矯正されます。

See Also

上部へスクロール

Questetra Supportをもっと見る

今すぐ購読し、続きを読んで、すべてのアーカイブにアクセスしましょう。

続きを読む