dayjournal memo

Total 974 articles!!

Try #017 – GASでAPI配信してスプレッドシートからwebページを更新できるようにしてみた

Yasunori Kirimoto's avatar

画像


画像




画像



この記事は、「Google Apps Script Advent Calendar 2018」の8日目の記事です。




GASでAPI配信して、スプレッドシートからwebページを更新できるようにしてみました!



みなさんは、webページのnews更新にCMSを導入したり、直接HTMLを更新したりしていませんか?

webページを更新する担当者が、PCを触る程度のスキルだとどうでしょうか?CMS導入を選択して投稿フォームで入力もありですが、静的なwebページだとその機能のためにCMSを入れるのもオーバースペックな気がします。

手軽な静的サイトジェネレータでも、スキルによってはコマンド(黒い画面)が使えなかったりもすると思います。

そんな中、Excelのような表計算ソフトを利用できる人は結構いると思います。webページ更新時に、みんなが使いやすいツールを利用すると良いかもなんてことを考えていました。



全体の構成です。できるだけシンプルに。


フロントエンド


バックエンド

  • スプレッドシート
  • Google Apps Script


バックエンド


まずは、バックエンドを構築してみます。

お好きな名前でスプレッドシートを新規作成し、A列にnews情報を記入します。1行目が題名で、2行目から表示文章です。

画像



次に、ツール → スクリプトエディタをクリック

画像



次に、GASで配信用のAPIを構築してみます。


script.gs


//スプレッドシートの値をAPI配信
function doGet() {
    //スプレッドシート取得
    var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();

    //シートを取得
    var sheet = spreadsheet.getActiveSheet();

    //値の最終行を取得
    var lastrow = sheet.getLastRow();

    //JSON変数初期化
    var json = [];

    //セルの一覧を取得
    for (var i = 2; i <= lastrow; i++) {
        //セルの値を取得
        var value = sheet.getRange("A" + i).getValue();

        //値を格納
        var name_obj = {
            news: value
        };

        //JSONを追加
        json.push(name_obj);
    }

    //JSONP形式に変換
    var jsonp = "apicallback(" + JSON.stringify(json) + ")";

    //JSONPで配信
    return ContentService
        .createTextOutput(jsonp)
        .setMimeType(ContentService.MimeType.JAVASCRIPT);

}


上記のコードを、GASのエディタにコピーし保存します。

画像



次に、公開 → ウェブアプリケーションとして導入をクリック

画像



バージョン: 好きな値
ユーザー: 自分
アクセスユーザー: 全員(匿名ユーザーを含む)
設定したら導入をクリック

画像



許可を確認をクリック

画像



自分のアカウントをクリック

画像



許可をクリック

画像



API配信先のURLが作成されたら、コピーしておきます。

画像




フロントエンド


最後に、フロントエンドを構築してみます。

bootstrap4-starterの「index.html」と「script.js」を修正します。


index.html


<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title>bootstrap4 Starter</title>
</head>

<body>

<!--ナビバー-->
<nav class="navbar navbar-expand-lg navbar-light bg-light">
    <a class="navbar-brand" href="./">menu</a>
    <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
    </button>
    <div class="collapse navbar-collapse" id="navbarSupportedContent">
        <ul class="navbar-nav mr-auto">
            <li class="nav-item dropdown">
                <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                    Dropdown
                </a>
                <div class="dropdown-menu" aria-labelledby="navbarDropdown">
                    <a class="dropdown-item" href="#content1">content1</a>
                    <div class="dropdown-divider"></div>
                    <a class="dropdown-item" href="#content2">content2</a>
                    <div class="dropdown-divider"></div>
                    <a class="dropdown-item" href="#content3">content3</a>
                </div>
            </li>
        </ul>
    </div>
</nav>


<!--題名-->
<div class="jumbotron text-center">
    <h2>bootstrap4 Starter</h2>
</div>


<!--本文-->
<div class="container">
    <br><br>

    <!--news部分追加-->
    <div class="row" id="news">
    </div>

    <br><br>
    <div class="row" id="content1">
        <div class="col-sm-12">
            <div class="mx-auto">
                <p>content1-1</p>
                <img class="img-thumbnail" src="./img/img01.jpg" />
            </div>
        </div>
        <div class="col-sm-12">
            <div class="mx-auto">
                <p>content1-2</p>
                <img class="img-thumbnail" src="./img/img02.jpg" />
            </div>
        </div>
    </div>
    <br>
    <div class="row" id="content2">
        <div class="col-sm-6">
            <div class="mx-auto">
                <p>content2-1</p>
                <img class="img-thumbnail" src="./img/img03.jpg" />
            </div>
        </div>
        <div class="col-sm-6">
            <div class="mx-auto">
                <p>content2-2</p>
                <img class="img-thumbnail" src="./img/img04.jpg" />
            </div>
        </div>
    </div>
    <br>
    <div class="row" id="content3">
        <div class="col-sm-4">
            <div class="mx-auto">
                <p>content3-1</p>
                <img class="img-thumbnail" src="./img/img05.jpg" />
            </div>
        </div>
        <div class="col-sm-4">
            <div class="mx-auto">
                <p>content3-2</p>
                <img class="img-thumbnail" src="./img/img06.jpg" />
            </div>
        </div>
        <div class="col-sm-4">
            <div class="mx-auto">
                <p>content3-3</p>
                <img class="img-thumbnail" src="./img/img07.jpg" />
            </div>
        </div>
    </div>

</div>

    <script src="./app.js"></script>

</body>
</html>


script.js


//JSONPのAPI取得
var url = "ここに配信したAPIのURLを入れる";
$.ajax({
    type: "GET",
    url: url,
    dataType: 'jsonp',
    contentType: 'application/javascript',
    jsonpCallback: 'apicallback',
})
    .then(
        //取得
        function (data) {
            //取得したJSONをHTMLに追加
            for (var i = 0; i < data.length; i++) {
                //HTML作成
                var newsall =
                            '<div class="col-sm-12">' +
                                '<div class="mx-auto">' +
                                    '<p>' + data[i].news + '</p>' +
                                '</div>' +
                            '</div>';
                //HTMLに追加
                $('#news').append(newsall);
            }
        },
        //取得失敗
        function () {
            alert("取得に失敗しました。");
        });


本来はJSONでGETしたいのですが、GASではCROSではじかれてしまいます。今回はあえてJSONPで取得しています。



実行環境

node v10.0.0
npm v6.4.1


パッケージインストール

npm install

ビルド

npm run build

開発用

npm run dev


開発用で確認してみます。

画像


スプレッドシートの値がNewsに表示されます。



試しに、スプレッドシートの値を追加してみます。

画像



ブラウザをリロードすると、反映されます。

画像




GASでAPI配信して、スプレッドシートからwebページを更新できることが確認できました!

更新情報を、手軽にスプレッドシートで管理できるのは魅力的ですね!



book

Q&A