質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.40%

  • JavaScript

    18112questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • Google Apps Script

    1011questions

    Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

  • Google API

    594questions

    Googleは多種多様なAPIを提供していて、その多くはウェブ開発者向けのAPIです。それらのAPIは消費者に人気なGoogleのサービス(Google Maps, Google Earth, AdSense, Adwords, Google Apps,YouTube等)に基づいています。

Google apps scriptで作った関数がエディターでは動くが外部から叩けない

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 3,076

googleスプレッドシートにスクリプトを追加しAPIとして公開後、auth認証してjavascriptから呼び出してみたのですが、
スクリプトエディターでは動くのに外部から叩くと動かない関数がありまして、原因を探しています。

例えばgoogle app script側で

function myAPI()
{
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  var ss = sheet.getRange(1,1).getValues();
  return ss;
}

このような関数を用意し、外部から実行すると

Error calling API:
{
  "name": "myAPI",
  "done": true,
  "error": {
    "code": 3,
    "message": "TypeError",
    "details": [
      {
        "@type": "type.googleapis.com/google.apps.script.v1.ExecutionError",
        "scriptStackTraceElements": [
          {
            "function": "myAPI",
            "lineNumber": 4
          }
        ],
        "errorMessage": "null のメソッド「getActiveSheet」を呼び出せません。",
        "errorType": "TypeError"
      }
    ]
  }
}

といった具合でエラーが返ってきます。
getActiveSheetが実行できていないようです。

しかしLogger.log()などでss変数を覗いてみると、きちんと返ってきました。
イメージ説明

呼び出し側のプログラムを変更せず、以下のようなAPIを用意し外部から実行すると通ります。

function myAPI(hoge)
{
  var result = [hoge]
  return JSON.stringify(result);

}


GASで用意されてる関数を叩かなければ、特に問題なく結果が返ってきました。

スクリプトエディターのデバッガーでは値がとれるのに、外部から叩こうとするとエラーがでる原因が知りたいです。なにかご存じの方がいればアドバイスをお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

GAS側コード

function myAPI()
{
  var ss = SpreadsheetApp.openById("スプレッドシートキー");
  var sh = ss.getActiveSheet();
  var val = sh.getRange(1,1).getValue();
  return val;
}

公開→実行可能APIとして導入から諸々設定

リソース→Developers Console プロジェクトから諸々設定(Execution API有効化、認証設定)

この設定周りはいろいろと面倒くさいのですがキータの記事を参考にしてみてください。

サーバー側に置くHTMLファイル
公式サイトのサンプルを参考に、必要な部分を変更しています。
JavaScript Quickstart

<html>
  <head>
    <script type="text/javascript">
      // Your Client ID can be retrieved from your project in the Google
      // Developer Console, https://console.developers.google.com
      var CLIENT_ID = '<YOUR_CLIENT_ID>'; // ←認証情報設定から拾う

      var SCOPES = ['https://www.googleapis.com/auth/spreadsheets'];

      /**
       * Check if current user has authorized this application.
       */
      function checkAuth() {
        gapi.auth.authorize(
          {
            'client_id': CLIENT_ID,
            'scope': SCOPES.join(' '),
            'immediate': true
          }, handleAuthResult);
      }

      /**
       * Handle response from authorization server.
       *
       * @param {Object} authResult Authorization result.
       */
      function handleAuthResult(authResult) {
        var authorizeDiv = document.getElementById('authorize-div');
        if (authResult && !authResult.error) {
          // Hide auth UI, then load client library.
          authorizeDiv.style.display = 'none';
          callScriptFunction();
        } else {
          // Show auth UI, allowing the user to initiate authorization by
          // clicking authorize button.
          authorizeDiv.style.display = 'inline';
        }
      }

      /**
       * Initiate auth flow in response to user clicking authorize button.
       *
       * @param {Event} event Button click event.
       */
      function handleAuthClick(event) {
        gapi.auth.authorize(
          {client_id: CLIENT_ID, scope: SCOPES, immediate: false},
          handleAuthResult);
        return false;
      }

      /**
       * Calls an Apps Script function to list the folders in the user's
       * root Drive folder.
       */
      function callScriptFunction() {
        var scriptId = "ENTER_YOUR_SCRIPT_ID_HERE"; // ←スクリプトエディタのURL欄から拾うか、「ファイル」→「プロジェクトのプロパティ」から拾う

        // Create an execution request object.
        var request = {
            'function': 'myAPI'
            };

        // Make the API request.
        var op = gapi.client.request({
            'root': 'https://script.googleapis.com',
            'path': 'v1/scripts/' + scriptId + ':run',
            'method': 'POST',
            'body': request
        });

        op.execute(function(resp) {
          if (resp.error && resp.error.status) {
            // The API encountered a problem before the script
            // started executing.
            appendPre('Error calling API:');
            appendPre(JSON.stringify(resp, null, 2));
          } else if (resp.error) {
            // The API executed, but the script returned an error.

            // Extract the first (and only) set of error details.
            // The values of this object are the script's 'errorMessage' and
            // 'errorType', and an array of stack trace elements.
            var error = resp.error.details[0];
            appendPre('Script error message: ' + error.errorMessage);

            if (error.scriptStackTraceElements) {
              // There may not be a stacktrace if the script didn't start
              // executing.
              appendPre('Script error stacktrace:');
              for (var i = 0; i < error.scriptStackTraceElements.length; i++) {
                var trace = error.scriptStackTraceElements[i];
                appendPre('\t' + trace.function + ':' + trace.lineNumber);
              }
            }
          } else {
            // The structure of the result will depend upon what the Apps
            // Script function returns. Here, the function returns an Apps
            // Script Object with String keys and values, and so the result
            // is treated as a JavaScript object (folderSet).
            var folderSet = resp.response.result;
            if (Object.keys(data).length == 0) {
                appendPre('No data returned!');
            } else {
              Object.keys(data).forEach(function(id){
                appendPre(data[id]);
              });
            }
          }
        });
      }

      /**
       * Append a pre element to the body containing the given message
       * as its text node.
       *
       * @param {string} message Text to be placed in pre element.
       */
      function appendPre(message) {
        var pre = document.getElementById('output');
        var textContent = document.createTextNode(message);
        pre.appendChild(textContent);
      }

    </script>
    <script src="https://apis.google.com/js/client.js?onload=checkAuth">
    </script>
  </head>
  <body>
    <div id="authorize-div" style="display: none">
      <span>Authorize access to Google Apps Script Execution API</span>
      <!--Button for the user to click to initiate auth sequence -->
      <button id="authorize-button" onclick="handleAuthClick(event)">
        Authorize
      </button>
    </div>
    <pre id="output"></pre>
  </body>
</html>

これでA1に入力した値がそのままブラウザに表示されると思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/11/15 15:20

    丁寧にありがとうございます。
    実はこちらの問題に関してはいろいろいじっているうちに解決してしまったのですが、
    このスクリプトはサンプルスクリプトとしてこれから開発してきたいと思います!
    ありがとうございます!

    キャンセル

同じタグがついた質問を見る

  • JavaScript

    18112questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • Google Apps Script

    1011questions

    Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

  • Google API

    594questions

    Googleは多種多様なAPIを提供していて、その多くはウェブ開発者向けのAPIです。それらのAPIは消費者に人気なGoogleのサービス(Google Maps, Google Earth, AdSense, Adwords, Google Apps,YouTube等)に基づいています。