ども、やんしーです。

※平成30年9月7日更新・変更あり

この度、アクロヨガジャパンのRisaが全国ツアーをやることになりました!
おめでとうございます~^^パチパチ

https://tour2018.acroyogajapan.tokyo
こちらが詳細サイトになってまっせ。

この記事で伝えたいこと

今回、そのツアーのウェブサイトをわたしが作ることになったんですね~。
ありがとうございます!

作りにあたり、ちょっと色々と試したくなったのもあり、以下の構成で作成してみました!

この記事では、その仕組みを簡単に紹介できればと思います。。

構成図

zapier5

見づらい、わかりづらいのも多いですが・・w

やってること

  1. GoogleSheetsで都道府県ごとのツアー情報を管理。変更や追加があれば修正。
  2. GoogleSheets上の内容を反映するため、CognitoFormsでNetlifyのbuild hookをcall
  3. NetlifyはGitlabのコードを取得。
  4. GoogleSheetsの内容を取得するコードが書かれており、変更を反映してビルド/デプロイ
  5. デプロイが成功したらCloudFlareのキャッシュクリアAPIを叩く
  6. 反映される

簡単に要約するとこんな感じですかね?

GoogleSheetsとCognitoFormsは、私だけではなくRisa本人が更新しやすいように準備しました。

CognitoFormsを実行したあとは、すべて自動になってます。

それぞれのアプリについて

それでは上記概要図に記載されているアプリをひとつづつ見ていきます。

CognitoFormsって?

banner-772x250

CognitoFormsは簡単にフォームが作れるサービスです。
けっこう細かいところに手が届きます。
色々なinput要素の組み合わせ、条件分岐、エラーハンドリング・・などなど、基本的なフォームであれあば十分過ぎる機能があります。

以前案件で業務フローにCognitoFormsで窓口を立てるというのがあり、そのときに調査したのですが、Ajax的に「外部データを選択肢に利用することができない」以外は、どのフォームサービスより優れていると思います。

Netlifyにアクセスしてビルドしてもらうことは厳しいので、
CognitoFomsに「反映ボタン」だけ用意しました。

以下の流れで利用してもらっています。

1.GoogleSheetsを更新(変更しただけでは反映されない)
2. 内容を確認し、問題なければCognitoFormsの「反映ボタン」クリックする。

GoogleSheetsって?

google-sheets-logo

MicroSoftで例えるとExcelのようなものです。基本オンラインで編集するため、共有したり外部連携が楽チンにできます。

ちなみに、今回はjson化するためWeb公開する設定にしています(リンクをしっていれば見れるレベル)。

ファイル > ウェブに公開に進むとウェブ上で公開されます。
これだけだとjson化されないけど、公開したのちに以下のURLでアクセスするとjsonで取得できるのだぁーよ。

https://spreadsheets.google.com/feeds/list/識別値/od6/public/values?alt=json

識別値は普通に当該GoogleSheetsにアクセスした場合のURL内の/d/以降の値を指しているんでね、注意してください。

json化した状態であれば取得も容易なんですよねー。

Netlifyって?

20170822104459

これはなんだろ、一言で言うと静的サイトに特化した、ビルド・デプロイしやすいホスティングサービスかな?

自分はソースコードの管理にGitlabを使っているんだけど、(設定次第だが)Gitlabのmasterにpushすると、自動でNetlifyがソースコード拾って、ビルド・デプロイしてくれるんすよ。

ただ、基本静的サイトに特化しているので、動的サイトをつくるのは微妙だったりもします。。。
なので、phpやpython、go、nodejsをそのままサーバサイドに配置して、ユーザからページリクエストがあるたびに実行することはできない(と思っているけど違うかな?)

そのため、ビルド時にプログラムを実行し、静的化する。という手法をとってみたで。

今回の内容で言うと、GoogleSheetsのJsonを取得するプログラムはphpで作り、ビルド時に取得しています。

また、今回詳細には触れないけど、RSSで外部ブログから「最新情報」を取得して表示させるプログラムもphpで作りやした。
この取得もビルド時に取得していので、RSSの更新はZapierで監視して、更新があったらNetlifyのbuild hookが自動で叩かれるようにしている。

gitlabって?

gitlab

一言で言うと、Githubみたいなもんです。公開しなくても使えます。

今回は、以下のようなソースコードを管理していまっす~。

  1. ウェブサイトのマークアップコード
  2. HTML出力プログラム
  3. GoogleSheets取得プログラム
  4. RSS取得プログラム
  5. ビルド時に実行するプログラム

CloudFlareって?

cloud-flare-603x234

これはSSL化とコンテンツキャッシュに利用しているんでっせ。

SSLアクセラレーションなんて言葉を使ったりもしますけど、CDNのエッジサーバ上でSSL化してもらい、httpsでアクセスできるようにしています。
証明書自体がエッジサーバにあると考えてもらえればと。

NetlifyにもSSL化できる機能はあるのですが、コンテンツキャッシュでCloudFlare使ってるし、そんな強固に暗号化する必要のあるサイトではないので、今回の構成にいたった次第です。。。

まあ、もっと色々なやりかたはあるけど、こんな感じに至りました。。

Zapierって?

20161123220504

今まで、システム同士を連携・統合する場合、その結合部分をカキカキしていたと思うんですね。
ただ、それが不要になるという最強サービスでござんす。

他にもIFTTTやINTEGROMATやBuilt.ioなど色々似たようなサービスはありますが、Zapierはシンプルで使いやすいです。

Zapierは条件分岐など複雑なことはできず(フィルタで篩をかけるくらい)、あくまでシステムの流れを組んで、APIを叩いてデータを送るというシンプルな構成を組むことができるので、自分は好きです。

IFTTTはちょっと個人向け過ぎるし、ちと弱い。
INTEGROMATやBuilt.ioは条件分岐とかループとかすげー細かいことできるけど、あまり処理を混合させたくないんですよね。。。

フロント(入力)
テキスト最適化処理(フォーマット)
API叩く(Zapier)
アプリ実行される(ここで条件処理)
結果返す
通知

こんな感じで層によって、用途はハッキリとわけたほうが自分はのぞましいと思っています。

今回は、Netlifyのビルドプログラムで条件などはカキカキしています。

もういっかいやってることのおさらい

概要図

zapier5

  1. まず、RisaがGoogleSheetsで何か更新します。
  2. GoogleSheetsを更新しただけでは何も起こらないので、CognitFormsを実行し、Netlifyのbuild hookを叩きます。

以下のようなことが実行されるんですね。。
build.shの例)

mkdir -p "./htdocs/about/"
mkdir -p "./htdocs/area/"
SCRIPT_FILENAME=build.php REQUEST_URI=/home php build.php > "./htdocs/index.html"
SCRIPT_FILENAME=build.php REQUEST_URI=/area_chugoku php build.php > "./htdocs/area/chugoku.html"
・
・

まあ、ドキュメントルートと、ディレクトリを作ってあげて、
built.phpを実行して、その結果で1行づつhtmlファイルに出力してます。要はphpのフレームワークでウェブサイトを動的に作ってるんですが、それを1ページづつ取得してhtmlファイルとして出力してるんですねぇ。。

なんとめんどくさい。
けど、今回は1行づつやっちゃってますが、ファイル構成とかを別のconfigにして、それを読み込むとかもできるので、シェルをもう少し組み方を変えればめんどくさくないですね~。

実行しているbuild.phpはこんな感じ。$nameの処理は割愛しますが、要はリクエストURIがhomeじゃなければこっち、homeならばこっち、みたいな処理です。

if ( $name !== 'home' ) {
	$dir = dirname(__FILE__);
	include $dir . "/template/inc/header_area.php";
	include $dir . "/template/inc/spredsheets.php";
	require $dir . "/template/detail_area.php";
} else {
	$dir = dirname(__FILE__);
	include $dir . "/template/inc/header_home.php";
	require $dir . "/template/home.php";
	include $dir . "/template/inc/footer.php";
}

spredsheets.phpではGoogleSheetsの情報を取得していてこんな感じ

<?php
$data = "https://spreadsheets.google.com/feeds/list/識別値/od6/public/values?alt=json";
$json = file_get_contents($data);
$json_decode = json_decode($json);

$val = $json_decode->feed->entry;

foreach ($val as $v) {
        $k = $v->{'gsx$area'}->{'$t'};
        $area[$k][] = array(
                "name"     => $v->{'gsx$name'}->{'$t'},
                "title"    => $v->{'gsx$title'}->{'$t'},
                "date"     => $v->{'gsx$date'}->{'$t'},
                "address"  => $v->{'gsx$address'}->{'$t'},
                "place"    => $v->{'gsx$place'}->{'$t'},
                "produce"  => $v->{'gsx$produce'}->{'$t'},
                "link"     => $v->{'gsx$link'}->{'$t'},
        );
}

他にも色々してるけど、メインはこの上の部分かな。$areaの配列に格納して使いやすいように。

割愛してる部分も多いですが、主要なプログラムは上くらいかな?

  1. 上記プログラムでbuildが成功すると、deployされます。
  2. 成功をきっかけにCloudFlareのキャッシュクリアのAPIを叩きます。

CloudFlareのAPIを叩くにあたって、Zapierでの設定に少しハマってしまったので、注意点をひとつ共有できればと思います。

ZapierでCloudFlareのキャッシュクリアのAPIを叩くときは、以下を選択しないとだめ

zapier3

結局METHODはPOSTなんですが、RequestDataの入力方法が違うのか、CUSTOM METHODを選択したのち、次のページでPOSTを選択しないとエラーが返ってきちゃうんですよね。。

zapier4

  1. 問題なければ通知がきて完了です。

最後に

今回の事例は。色々な外部アプリケーションを使い、それらをZapierで統合し、なるべくコードレスにするという形を取った結果なんですね。

ちなみにホスティングのNetlifyも無料、Zapierも無料版、CloudFlareも無料、GoogleSheetsも無料なので、タダで管理機能付きのウェブサイトができました。

中小規模で、且つ、少しくらいい複雑な業務フローだったとしても、個人情報を扱わず、承認フローもなければ、コードレス、無料で対応することは結構できそうです。

ちなみに、わたしやんしーはサラリーマンでもありますが副業で請け負ってこういうことやってますので、気軽にご相談ください。

ただ、副業なので、ゆるく楽しくできる方限定にしてます。

なにかあればコメントでご指摘を。