株式会社スマレジの開発部でスマレジのサーバサイドを作っています

スマレジプラットフォームAPIのアクセストークンをGASで取得する

こんにちは!株式会社スマレジ、開発部のmasaです。

梅雨が長引いていますねー・・・。せっかくのGo Toも雨続きだと、なかなか踏み切れないですよね。。。 早くカラッと晴れた空と入道雲を仰ぎたいですね!

さて、以前GASを使ったスマレジプラットフォームAPIのアクセストークンの取得方法を紹介しておりましたが、 正式版リリースに際して、トークン取得の仕様が変更されたので、GASのほうも新しいテンプレートをご用意いたしました!

最新版のアクセストークン取得用スクリプト

function getAccessToken() {
    // プロパティサービスに予め、必要な定数を定義しておく。
    const contractId = PropertiesService.getScriptProperties().getProperty("SMAREGI_CONTRACT_ID_DEVELOPMENT"); // サンドボックス用契約ID
    const scope = PropertiesService.getScriptProperties().getProperty("SMAREGI_APP_SCOPE_REQUIRED"); // 要求するスコープ(複数ある場合は、半角スペースで区切ること)
    const clientId = PropertiesService.getScriptProperties().getProperty("SMAREGI_APP_CLIENT_ID"); // アプリのクライアントID([アプリ]->[対象のアプリ]->[2. 環境設定])
    const secret = PropertiesService.getScriptProperties().getProperty("SMAREGI_APP_SECRET"); // アプリのクライアントシークレット([アプリ]->[対象のアプリ]->[2. 環境設定])

    // 下記、ハードコーディング用(危険なのでプロパティサービスを使うようにしてください。)
    // const contractId = "sb_xxx123x0(契約ID)";
    // const scope = "スコープ(Ex. pos.products.read等)詳しくはプラットフォームAPIの仕様書をご覧ください。";
    // const clientId = "クライアントID";
    // const secret = "クライアントシークレット";

    const grantType = "client_credentials"; // 認証方法を指定(固定値)
    const url = 'https://id.smaregi.dev/app/' + contractId + '/token'; // end point

    const headers = {
        'Authorization' : 'Basic ' + Utilities.base64Encode(clientId + ":" + secret, Utilities.Charset.UTF_8), // Basic認証用にエンコード
        'Content-Type' : 'application/x-www-form-urlencoded'
    };

    const payload = {
        'grant_type' : grantType,
        'scope' : scope
    };

    const options = {
        'method' : 'post',
        'headers' : headers,     // header情報を追加
        'payload' : payload      // トークンを設定
    };

    try {
        //外部へアクセスさせる
        let resStr = UrlFetchApp.fetch(url, options).getContentText();
        if (resStr.length === 0) {
            throw new Error("受信データがありませんでした。");
        }
        let resJson = JSON.parse(resStr);
        Logger.log(resStr);
        // 取得したアクセストークンとスコープを、プロパティサービスに登録
        PropertiesService.getScriptProperties().setProperties({"SMAREGI_APP_SCOPE":resJson.scope, "SMAREGI_APP_ACCESS_TOKEN":resJson.access_token});
        // if (resJson.scope !== scope) {
        //     // developersサイト側で許可していないスコープを指定した場合、ここでエラーになる。
        //     throw new Error("アクセストークンは更新されましたが、要求したスコープと許可されたスコープが一致しません。developersサイトのスコープを確認して下さい。");
        // }

        }
    } catch(e) {
        Logger.log("エラー:" + e);
        throw new Error(e);
    }
}

簡単な説明

このスクリプトを動かす前に、プロパティサービスに下記のデータを登録してください。

  1. SMAREGI_CONTRACT_ID_DEVELOPMENT: sbより始まる開発者向け契約ID
  2. SMAREGI_APP_SCOPE_REQUIRED: 使用したいスコープ(スコープの詳しい説明は、プラットフォームAPI仕様書をご確認ください)
  3. SMAREGI_APP_CLIENT_ID: アプリのクライアントID([アプリ]->[対象のアプリ]->[2. 環境設定]より確認)
  4. SMAREGI_APP_SECRET: アプリのクライアントシークレット([アプリ]->[対象のアプリ]->[2. 環境設定]より確認)

プロパティサービスの登録方法は過去ブログをご覧ください。

masa2019.hatenablog.com

上記定数を登録し、実行して正常終了(何も起こらない)場合は、プロパティサービスに下記の定数が追加されています。

  1. SMAREGI_APP_SCOPE: 許可されたスコープ
  2. SMAREGI_APP_ACCESS_TOKEN: 発行されたアクセストーク

※ 認証エラー時には、エラ〜メッセージが表示されます。

また、コメントアウトしておりますが

        // if (resJson.scope !== scope) {
        //     // developersサイト側で許可していないスコープを指定した場合、ここでエラーになる。
        //     throw new Error("アクセストークンは更新されましたが、要求したスコープと許可されたスコープが一致しません。developersサイトのスコープを確認して下さい。");
        // }

プラットフォームAPIでは、developersサイト上で許可したスコープ以外をトークン取得時のスコープに指定しても、許可されません。 そのため、許可されるスコープと要求したスコープが異なる場合があります。 要求したスコープと一致させたい場合は、上記コメントアウトを解除してください。

今日、これを書いていて、「スコープ周りの解説したほうがいいかなー」と思い始めた自分がいるので、 近いうちにスコープ指定の方法を記載すると思います。