EC-CUBE4.0 Web APIを使ってスプレッドシートに商品情報を取得する

[EC-CUBE Advent Calendar 2020](https://qiita.com/advent-calendar/2020/ec-cube) 7日目の記事です。

今年の9月に公開された [EC-CUBE 4.0 Web API プラグイン](https://www.ec-cube.net/products/detail.php?product_id=2121) 。
じつはちゃんと触ったことなかったので、この機会にとやってみました。

## この記事に書いてあること
googleスプレッドシートのGoogleAppsScript(GAS)から、EC-CUBEのAPIをコールして、商品情報をシートに表示します。

本文の最終的なソースコードはこちらに置いてあります。
https://gist.github.com/ryo-endo/98e3b6db69acbb8727e225ba8cc297ab

※とはいえEC-CUBE 4.0 Web API プラグイン はOAuth2.0で認可を実装しているので、EC-CUBEの記事というよりはGASでOAuth2.0のクライアントを実装する記事になってます。たぶん。

## 事前準備
- [EC-CUBE 4.0 Web API プラグイン](https://www.ec-cube.net/products/detail.php?product_id=2121)をインストール済みのEC-CUBEサイト。
- googleスプレッドシート

## プロジェクトにOAuth2ライブラリの追加
GASでOAuth2を利用する場合は [OAuth2 for Apps Script](https://github.com/googleworkspace/apps-script-oauth2) を利用するのが定番のようなので、[Setup](https://github.com/googleworkspace/apps-script-oauth2#setup) の指示に従ってメニュー＞リソース＞ライブラリから追加しておきます。

## EC-CUBEにクライアントの追加
EC-CUBEの管理画面＞設定＞API管理＞OAuth管理からクライアント用のキーを新規発行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113212/1b2d4fda-544f-0207-4cbb-81a88c826e8d.png)
スコープは `read` を指定。 
リダイレクトURI、以下のコードをGASで実行することで取得できるので、それを貼り付けます。
ref [OAuth2 for Apps Script #Redirect URI](https://github.com/googleworkspace/apps-script-oauth2#redirect-uri)

```js
function logRedirectUri() {
  var service = OAuth2.createService('eccube');
  Logger.log(service.getRedirectUri());
  // ログにURIが表示される
}
```

## アクセストークンの取得する

EC-CUBE Web APIでサポートしているのはOAuth2.0の認可コードフロー(Authorization code Grant)です。
[OAuth2 for Apps Script](https://github.com/googleworkspace/apps-script-oauth2) のReadmeにあるサンプルをEC-CUBE Web APIの利用に合わせて書き換えました。

getService関数でOAuth2ライブラリに必要なパラメータを設定しています。
[EC-CUBE Web API ドキュメント](https://doc.ec-cube.net/eccube-api4/)にあるエンドポイントと、先程登録したクライアントの情報をもとに必要なパラメータを書き換えてください。

```js
function main() {
    var service = getService();
    if (!service.hasAccess()) {
        // アクセス権がない場合はスプレッドシートのスライドバーに認可URLを表示する
        var authorizationUrl = service.getAuthorizationUrl();
        var template = HtmlService.createTemplate(
            '<a href="<?= authorizationUrl ?>" target="_blank">Authorize</a>. ' +
            'Reopen the sidebar when the authorization is complete.');
        template.authorizationUrl = authorizationUrl;
        var page = template.evaluate();
        SpreadsheetApp.getUi().showSidebar(page);
    } else {
        // アクセストークンを取得してログに表示してみる
        Logger.log(service.getAccessToken())
    }
}

// ライブラリの初期化
function getService() {
    return OAuth2.createService('eccube')
        .setAuthorizationBaseUrl('https://{EC-CUBEの管理画面URL}/authorize')
        .setTokenUrl('https://{EC-CUBEのURL}/token')
        .setClientId('クライアントID')
        .setClientSecret('クライアントシークレット')
        .setPropertyStore(PropertiesService.getUserProperties())
        .setScope('read')
        .setCallbackFunction('usercallback')
}

// クライアント作成時に登録したコールバックURIでこの関数が呼び出される
function usercallback(request) {
    var service = getService();
    var isAuthorized = service.handleCallback(request);
    if (isAuthorized) {
        return HtmlService.createHtmlOutput('Success! You can close this tab.');
    } else {
        return HtmlService.createHtmlOutput('Denied. You can close this tab');
    }
}
```

showSidebar関数を実行すると、スプレッドシートのタブに以下のようなサイドバーが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113212/4ea7855f-0d4b-76cd-0c5e-d71a325c88e9.png)
リンク先に行くと、管理画面にログイン後に権限移譲の確認画面が表示されるので「許可する」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113212/3ab7c3e9-9f7d-3b93-5639-c2ff6319c181.png)
この画面が表示されたら認可コードが正常に取得できています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113212/a0b7f56c-fc2d-e036-d796-6d610793de8d.png)
再度showSidebar関数を実行すると、今度はelseに処理が流れます。ログにアクセストークンを出力しているので確認して見ましょう。

## APIをコールして商品情報をセルに書き出す

EC-CUBE Web API はGraphQLで実装されています。
[EC-CUBE Web API ドキュメント](https://doc.ec-cube.net/eccube-api4/)の「商品情報の取得」に従ってAPIをコールしてみます。

先程のshowSidebar関数でログ表示していたところを書き換えて、getProduct関数(後述)を呼び出します。引数にはアクセストークンを渡しています。

```js
function showSidebar() {
    var service = getService();
    if (!service.hasAccess()) {
        ...省略...
    } else {
        getProduct(service.getAccessToken()); //追加
    }
}
```

getProduct関数ではアクセストークンを使いAPIから商品データを取得。その後A1セルに書き出しています。

```js
function getProduct(token) {
    const apiUri = 'http://{EC-CUBEのURL}/api';
    const queryBody = `{
        product(id:1) {
            id,
            name
        }
    }`;
    const options = {
        method: "post",
        contentType: "application/json",
        headers: {
            Authorization: 'Bearer ' + token,
        },
        payload: JSON.stringify({ query: queryBody })
    }
    var response = UrlFetchApp.fetch(apiUri, options);
    var result = JSON.parse(response.getContentText());
  
    // 取得した商品名をA1セルに書き出す
    const productName = result.data.product.name;
    const sheet = SpreadsheetApp.getActiveSheet();
    sheet.getRange(1,1).setValue(productName);
}
```

無事に商品名が取得できました。やったね！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113212/188b1d30-e5bc-0c5b-dd25-aba6edc7f299.png)

## いろいろ応用できそう

今回は必要最低限のサンプルで実装してみましたが、

- 受注情報の一覧を取得 →スプレッドシートで集計してみる
- 商品情報を取得 → スプレッドシートで編集して → 書き換え

みたいな応用がいろいろできそうですね。

EC-CUBE4.0 Web API と スプレッドシートの組み合わせ。ぜひ試してみてください！