【5分でSaaSアプリ作成】スマレジアプリ・スターターパックを公開しました 

#はじめに
[スマレジ](https://smaregi.jp/)という非常に多機能なPOS・勤怠管理システム・オーダーシステムを低価格で提供しているタブレットPOSサービスがあるのですが、2020年8月[^1]より、アプリマーケット上の『アプリ』という形で開発者が独自に機能を追加し、スマレジユーザーに売ることが出来るサービスが開始しました。

スマレジ本体のデータのほぼ全てがAPIで公開されているため、店舗の売上や勤怠のリアルタイムのデータを取得できるなど、非常に面白いサービスなのですが、アプリマーケットが賑わわないと、そもそもアプリが使われません（MacのApp Storeがいい例ですね）。アプリ開発にはSaaSサービスとの連携アプリともあって、OpenID Connectなど最低限の実装が少し高いハードルになっています。

そのため、これらの最初に躓く部分を出来る限り取り払い、簡単にアプリを作れるテンプレートとして「スマレジアプリ・スターターパック」を作りました。このパックを使うと、アカウント取得などの事前準備が終わっていれば、**約５分**でアプリを作成し、スマレジのプラットフォームとつなぐことができます。

OpenID Connectでのログイン機能もスターターパックで提供されるので、アプリの機能に集中することができます。スターターパックという名前の通り、実装したい機能を簡単に追加できるようにしているため、このパックを元に本番アプリの作成・公開も可能です。

本記事では、スターターパックの概要と使用方法を書いています。スターターパックの詳細なしくみやアーキテクチャについては後日別の記事で書きますが、仕組みを理解していなくても問題なくアプリを動かせるようになっています。

##特徴
こちらのスターターパックを使うだけで、スマレジのOpenIDでログイン機能を持ち、契約期間内の契約者にはHello Worldを表示するアプリを**Google Cloud**上でデプロイすることができます。アプリの部分を最低限にしていますので、まずHello Worldアプリを実装できたら、簡単にアプリで実装したい機能を追加していくことができます。

以下のような特徴を持っています。

- ユーザー数が100人程度で、月あたりのログイン数が1000アクセス程度の想定で、**月額約3円**のクラウドコストで収まる設計
- ユーザー数が**10万人**となっても落ちないスケールアウト設計
- IaCに沿ったパッケージのため、インスタンスの設定やデプロイもすべてコード化されています。ローカルで起動して簡単にテストができ、デプロイもスクリプトを走らせるだけです
- 障害時・エラー時にすぐにアラートが来るようにデフォルトで設定済みです（解除も可能）

##構成
全体がサーバーレス構成となっております。Google CloudのFaaSであるCloud Functionを使う構成です。サーバー等のミドルウェアはGoogle Cloudで管理されるため、開発者はそのミドルウェア上で動くコードだけを開発・デプロイすればよい形です。

データベースにはFirestoreというNoSQLを使っておりますが、アプリからの使い勝手もよく、データの確認もGUIで簡単にできます。

- Python3.8ベース
- メインコンポーネント：Cloud Function＋Firestore
- サブコンポーネント：Cloud Storage（実行バイナリの保存先）、Error Reporting（アラート用）

##必要要件
- MacOSでの開発を想定（スクリプト構成のため）
- Google Cloud環境
- Docker環境

##パッケージのダウンロード
GitHubでホストしていますので、こちらから`git clone`していただくか、ZIPでダウンロードして下さい。
[スマレジ・スターターパックのGitHubレポはこちら](https://github.com/senbishi21/smaregi-app-starter)


#使い方

##手順の概要
1. Google Cloudで新しいプロジェクトを作成：30秒程度
1. Google Cloudのウェブ画面からFirestore（データベース）を作成：30秒程度
1. スターターパックの初期化スクリプトを実行：1分程度
1. （並行して）スマレジのアプリを作成し、IDやキーをスターターパックの設定ファイルにコピー：30秒程度
1. メイン画面のコードをデプロイし、URLを設定ファイルにコピー：1分半程度
1. 残りの２つのコンポーネントをデプロイ：1分程度

1・２・４のステップ以外はすべてスクリプトで自動化されているので、デプロイのやり方などを知らなくても全く問題ありません。合計で時間は５分ほどかかりますが、ほとんどが待ち時間となります。これらの手順の前に、事前準備で必要なものを揃えておいて下さい。

##事前準備
必要な事前準備は以下の通りです。すでにインストール済みであれば、各項目はスキップしていただいて構いません。
1. スマレジの開発アカウントの取得
2. Google Cloudのアカウント取得、CLIツールのインストール
3. Dockerのインストール

スマレジのシステムとの連携の関係で、ローカルサーバーだけではアプリを動かせません。パブリックにアクセス可能なサーバーが必要な関係上、スターターパックではGoogle Cloudでのデプロイを前提にしてます。今後、AWSやAzure等で提供できるように機能追加予定です。（もしくは有志の方、ぜひPRお待ちしています！）

###1. スマレジ開発アカウントの取得
[こちらに](https://help.smaregi.jp/hc/ja/articles/360051440053-%E9%96%8B%E7%99%BA%E8%80%85%E3%82%A2%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B)スマレジ公式のチュートリアルがあありますので、こちらの通りにセットアップして下さい。

###2. Google Cloudの準備
Google Cloudは約３万円ほどの無料枠があるので、スターターパックを走らせても課金されることはありません。また、１ヶ月スタータパックを走らせても、100ユーザー程度では**月10円**もかからず運用できますので、ご安心下さい。必要無くなれば、プロジェクトを消すことで、全てのリソースを削除できるため、追加で課金が発生することもありません。

[こちらの公式ページ](https://cloud.google.com/)から始められます。Googleアカウントとクレジットカードの登録が必須となりますが、課金はデフォルトでオフになっており、課金されることはありません。また、CLIツール（Google Cloud SDK）が必須となるため、[こちらの公式ガイド](https://cloud.google.com/sdk/docs/install?hl=ja)にしたがってGoogle Cloud SDKをインストールして下さい。

###3. Dockerのインストール
ローカル環境で開発ができるように、Dockerベースのスクリプトを用意しています。[こちらの公式ガイド](https://docs.docker.jp/docker-for-mac/install.html)にしたがってDocker Desktop for Macをインストールして下さい。インストール後、以下を実行してみて動けば問題ありません。

```console
docker run --rm helloworld
```

これですべての事前準備が完了です！

##詳細な手順

### 1. Google Cloudで新しいプロジェクトを作成
Google Cloudのアカウントを作成したら、まずは新しいプロジェクトを作って下さい。今後はこのプロジェクト配下に全てのリソースが配置されます。また、削除も用意になるので、他のプロジェクトがあっても、別で作られることをおすすめします。

![Screen Shot 2021-03-21 at 16.37.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1228813/1275e597-c09a-2959-62c9-a89363974b9b.png)


### 2. Google CloudのGUIでFirestore（データベース）を作成
次に、FirestoreというデータベースをGUIで作成します。残念ながら、現在（2021-03)ではCLIが提供されていないため、GUI上でセットアップをする必要があります。
![Screen Shot 2021-03-21 at 18.50.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1228813/fe7b3b13-9697-0496-4cdc-e683be6bb810.png)


### 3. スターターパックの初期化スクリプトを実行
gitからソースコードをcloneして、初期セットアップ用のシェルスクリプトを実行しましょう。このときに作成したGoogle CloudのプロジェクトIDが聞かれるので、入力して下さい。また、Google Cloudへログインするようリクエストされるので、立ち上がったブラウザからログインして下さい。

```console
git clone https://github.com/senbishi21/smaregi-app-starter.git　（もしくはzipダウンロードでも可能）
smaregi-app-starter/_init/init.sh
```
![Screen Shot 2021-03-22 at 13.09.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1228813/81438b38-42c8-7560-c223-0f80a80e2d8c.png)

Google CloudのFirestoreのページで以下のように表示されたら成功です。
![Screen Shot 2021-03-21 at 19.43.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1228813/61a35b58-8ac3-bc39-0fcc-01d739028687.png)

### 4. スマレジアプリを作成し、認証情報を設定ファイルにコピー
（こちらの手順は３番と並行して行うこともできます。）
アプリを動かすには、まずアプリの認証情報が最初に必要です。認証情報を生成するため、アプリを初期登録する必要があります。以下のステップの通り勧めていけば大丈夫です。
![Screen Shot 2021-03-21 at 18.50.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1228813/e746e315-b91e-510a-32e5-01bc6e565863.png)
![Screen Shot 2021-03-21 at 18.50.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1228813/4382d88e-1a5d-1cf2-2d3a-b78ad9c965cc.png)
![Screen Shot 2021-03-21 at 18.50.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1228813/6b104ec5-6e85-a525-1569-2bbd95cb9907.png)
![Screen Shot 2021-03-21 at 18.50.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1228813/330b59a2-fb34-47fc-ad62-dd285a3d6edd.png)


アプリを作成したら、コピーした認証情報を_init/credentials/secrets.txtに入力して下さい。ダブルクオート等は不要です。QA_MAIN_URL以外を埋めて下さい。例：

```
QA_APP_CLIENT_ID=xxxx
QA_APP_CLIENT_SECRET=xxxxx
PROD_APP_CLIENT_ID=xxxxx
PROD_APP_CLIENT_SECRET=xxxxx
LOCAL_CONTRACT_ID=xxxx

QA_MAIN_URL=変更して下さい
PROJECT_ID=xxx
```

### 5. cf-mainのコードをデプロイし、URLを設定ファイルにコピー

cf-main/のフォルダで`./run.sh`を実行すると、ローカルでスタンドアローンで起動するウェブサーバーが動きます。自動でブラウザも開くので、こちらで以下のような画面がでたら成功です。

![Screen Shot 2021-03-22 at 9.36.15 copy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1228813/04cbd56d-ee20-88ae-6afc-56672fe22c31.png)

問題なければ、`./deploy.sh qa`を実行して、デプロイして下さい。こちらでGoogle CloudのCloud FunctionというFaaSサービスにコードをデプロイしています。デプロイには約1~2分ほどかかります。終了したら、Google CloudでCloud Functionのページを見てみて下さい。以下のように、緑のアイコンとなっていれば成功です。
![Screen Shot 2021-03-22 at 13.54.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1228813/17aa6429-a114-2ae9-a472-833db720534c.png)

qa-mainと表示されている部分をクリックすると、トリガーURLという項目があるので、それを_init/credentials/secrets.txtのQA_MAIN_URLにコピーして下さい。


### 6. 残りの２つのコンポーネントをデプロイ
のこりのcf-redirect-OIDC, cf-contract-webhookで`./deploy.sh qa`を実行して下さい。同じように約２分ほどかかりますので、終了したら、Cloud Functionのページで緑のアイコンとなっていることを確認して下さい。

cf-contract-webhookはアプリの使用を始める時・終了する際に、スマレジ側から呼ばれるWebhook型のサーバー（コンテナ）です。スマレジのアプリ画面で、以下のように設定して下さい。設定のあと、「テスト通知を送信」というボタンを押すと・・・
![Screen Shot 2021-03-21 at 21.13.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1228813/0eda62e4-5d06-52b1-0bfc-303df6a16e5c.png)

以下のように契約者情報がFirestoreデータベースに入ったことを確認出来ると思います。これで、アプリの契約が開始・終了した時にデータベースに保存されるようになりました。
![Screen Shot 2021-03-21 at 21.16.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1228813/94b089d3-6f88-4e52-b5ca-2d9c9e6e4de4.png)

##完了！
これですべて完了です！cf-mainのURLにアクセスしてみて下さい。以下のようにスマレジのOpenIDのページにリダイレクトされ、ログイン（認証）してアプリを認可すると、以下のように自分のアプリが表示され、契約者IDも反映されるはずです。QA環境では10分でクッキーの有効期限が切れるようになっているので、手早くリダイレクトの動作をテストできます。

- ![Screen Shot 2021-03-22 at 7.59.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1228813/7f891f39-46e3-f71c-01f3-aadc3c7dc2a3.png)
![Screen Shot 2021-03-22 at 9.36.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1228813/e2164ec1-5aaf-4c3a-8946-94db8f0a65f1.png)

あとは、実装したい機能やウェブページをcf-mainにて実装すればOKです！PythonのFlaskをベースにしているので、かなり簡単に機能やロジックの実装ができると思います。
また、QAとPROD環境をデプロイスクリプトの変数でスイッチ出来るようにしていますので、開発のCI/CDを行いやすいコードになっております。

#補足

##OSSについて
当コードはGitHub上にホストしていますので、PR大歓迎です。ただし、以下のルールを守って頂けると幸いです。

- セキュリティ情報（CloudのTokenやCredential情報等）はDockerfileに入れ込まず、_init/credentialsのフォルダでのみ保持する。こちらのフォルダは.gitignoreで無視されるため、空のテンプレートファイルを_init/credentials-templateに入れ込んで下さい。
- ディレクトリ内でrun.shでローカルに走らせる、deploy.shでクラウド環境にデプロイする、という構成をお願いします。ローカルで走らせることがない場合、run.shをなくすか、echoでその旨を伝えるだけのスクリプトにして下さい。

##料金について
料金のシミュレーションは[Google Cloud price estimate](https://cloud.google.com/products/calculator/#id=ef72688d-7603-43f6-966b-e1228df7188e)で。

- 100人のユーザーが1000アクセス/月で、５分ごとにスマレジのデータを同期する場合の料金シミュレーションでは月のコストが2.44円です：[料金詳細参考ページ](https://cloud.google.com/products/calculator/#id=ef72688d-7603-43f6-966b-e1228df7188e)
- 10万人のユーザーが全員毎日5アクセスする大規模システムで、５分ごとにスマレジのデータを同期する場合の料金シミュレーションでは月のコストが19万円/月となります：[料金詳細参考ページ](https://cloud.google.com/products/calculator/#id=70979084-4852-4428-94f7-ece23e8dd449)

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1228813/ee35ca82-6b9a-20c1-106a-403b297a7650.png" width=600 />

##スマレジアプリマーケットについて
スマレジアプリマーケットに登録された開発者には、スマレジの担当者からアプリの作り方等について、かなり手厚いサポートが受けられますので、ぜひ活用してみて下さい！私自身もかなりお世話になっています。

また、テクニカルサポートは[スマレジ Developers Community](https://community.smaregi.dev/)で受け付けているそうで、レスポンスが早い上、機能改善のケースでも実装が早いです。

どちらも、Appl○のiOSアプリや○ndroidアプリストアの対応より相当に早く、サポートも手厚いですので、どんどん使っていくのが早道です。

##その他参考資料
- [【スマレジアプリを作ってみた#3】認証機能の実装](https://qiita.com/JoBins/items/5b3eee45324466b01a64)：こちらの方がOpenIDでのログインの仕組みなど紹介してくださっています。
- [【スマレジアプリを作ってみた#5】Sandboxでの動作確認（テスト）](https://qiita.com/JoBins/items/c7624db16f238f0f875d)：同じ作者の方で、本番環境でのテスト手法を共有してくださってます。

##注釈
[^1]: [スマレジ・アプリマーケットのお知らせ](https://premium.ipros.jp/smaregi/news/detail/65341/)