始めに
背景
友人がレンタルスペース事業を始めることにあたって、システム周りの整備を任されました。
その中でレンタルスペースの顧客向けの予約をカレンダーで管理したいと言われました。
顧客は20人ぐらいの想定です。
その話を相談されたのが2020年8月ごろで、使い始めが2020年11月なので、あまり時間はありませんでした。(実際の使い始めたのは12月でした。)
補足としてGsuite(Google Workspace)は契約していたので、GASやその他のアプリは自由に使える状況です。
要件
ただ予約をするだけではなく、いくつか制御を入れたいと言われました。
システムエンジニアの腕の見せどころですね!
【要件】
- 会員登録フォームを作る。
- 会員の人だけカレンダーに予約できる。
- 予約は月に決まった時間だけしか予約できない。
- 予約したらスプレッドシートなどで管理してデータを可視化したい。
また、できればやりたいという【準要件】がこちらです。
- 会員は自動で毎月自動で引き落としされる。
- 支払いがまだの場合は予約できない。
- スプレッドシートから請求書を作成したい。
普段の仕事では要件定義は先輩がやっているのを見ているだけでしたが、今回はいい機会なので実際にやってみようと思いました。
観点
最初は自分で作るのもいいのですが、大掛かりにやって自分の手が回らなくなり管理しきれないことや、バグがでるが改修が間に合わなくて使えないのが嫌だったので既存のプラットフォームを使おうと思って調べていました。
調べるときは【要件】から抽出した以下の観点に絞って調べていきました。
- 低コスト
- 顧客管理できるか
- 拡張性、外部連携
- 管理のしやすさ
価格
起業したてて何かとお金がかかるので、できるだけお金が発生しないものを選びます。
特に有名なプラットフォームだと月額で支払いが発生すると年間かかるお金がバカにならないです。
顧客管理できるか
これは要件の会員だけ予約できることや、月の予約時間制限があることに関係します。
だれでも使えるレンタルスペースではなく会員向けで、なおかつ月額でプランを作るから顧客管理は必須でした。
拡張性
拡張性とは何のことかというと、一番は他システムと連携がとれるかという点です。
特にスプレッドシートやGoogleカレンダー、Slackと連携できるのは必要になってきます。
管理のしやすさ
レンタルスペースは1人で回すため、システムの管理画面があちらこちらにいったり、複雑な設定方法でないことが業務効率を上げる上で必要になってきます。
技術の選定
最終的にはGASに決めたのですが、そこまでのいろいろ調べたのでいくつかご紹介します。
既存のシステムを利用するか自作するかも含めて考えました。
これはだいぶ悩んだので結構調べました。
パターン1 Airリザーブ
https://airregi.jp/reserve/外部連携できないのが痛かった。
マッチしたところ
フリープランで月額0円で利用できる。
タイプとして自由受付と事前設定タイプがあり自由受付からユーザが使う時間を決められるので良い。
Airレジと連携できる。
マッチしないところ
外部連携できないためGoogleカレンダーと連携不可
事前決済できない
パターン2 RESERVA(レゼルバ)
既存のサービスで一番マッチした。ユーザごとの予約時間が制限できれば決定だった。
マッチしたところ
フリープランなら月額無料
フリープランでもできることが多い
Googleカレンダー連携可能
マッチしないところ
ユーザごとに月の最大予約時間上限を設定できない
パターン3 Coubic(クービック)
無料で使える。
レゼルバと同じ感じだった。
パターン4 WordPress + プラグイン
サーバとドメイン費用が掛かる。
プラグインが充実していてシステムを作りやすい。
カレンダー予約用のプラグインもあった。
データベースも使おうと思えば使える。
費用と相談。
パターン5 GoogleAppsScript + Googleカレンダー会議室機能
https://support.google.com/calendar/answer/44105?hl=ja
GASで作るので無料。
自分で作ることになるため労力がかかる。
GASで作るのでGoogleアプリを柔軟に利用できる。
パターン5 GoogleAppsScript + Googleカレンダー予約枠機能
https://support.google.com/calendar/answer/190998?co=GENIE.Platform%3DDesktop&hl=ja
パターン5とほとんど同じ。
予約する側はわかりやすいが、予約枠は時間固定で事前に設定するため予約時間が固定になってしまう。
パターン6 Firebase + JavaScript
https://firebase.google.com/?hl=ja
Firebaseは無料で使える。
自分で作るので時間がかかる。
知識がないので0から調べて作ることになる。
事前決済機能も作ろうと思えば作れるのが良い。
パターン7 AWS + JavaScript
AWSの無料枠内だったら無料。
AWSの知識がないため調べながら作ることになる。
AWSの勉強になる。
AWSの無料枠が1年だけだったため、却下。
開発
最終的に『パターン5 GoogleAppsScript + Googleカレンダー会議室機能』に決定したので、実際にGoogleAppsScriptで作りながら細かい制御をヒアリングしながら作っていきます。
今回は友人も仕様について探り探りだったため、アジャイル的に進めることにしました。
なので「ヒアリング→作る→見せる→修正する」を繰り返して開発していきました。
まずは今回作ったシステムの設計面のお話しです。
設計
技術の選定が終わったので設計段階に入ります。
顧客が使うので使いやすさとセキュリティ面、スプレッドシートで管理しやすい仕様を重点的に意識して設計しました。
※ソースが見たい人は飛ばしてください。
利用アプリ
まずは大枠として何を使うかを明確化しました。
元々言っていた話から
- GoogleAppsScirptでフォーム作成
- Googleカレンダーの会議室機能で会議室という名のみんなが見れるレンタルスペース用のカレンダーを作成
- フォーム入力内容はスプレッドシートに書き出す
- フォーム入力内容からGoogleカレンダーに登録する
- フォーム入力内容から登録完了メールを送信
これらを使えるようにします。
Googleカレンダーの会議室機能はGoogle Workspace登録していないと利用できないので、普通のカレンダーでも代替できます。
エンジニア目線の設計(詳細設計?)
利用アプリでやりたいことの流れは明確化できたので、実際に私が作るとなったときに「これってどうすればいいんだっけ」を整理していきます。
フォーム
実際作った画面を先にお見せするとこんな感じです。
画面の動きはjQueryを使いました。画面の動きが少ないのでVue.jsやReact.jsなどのSPAではなく単純にjQueryを選びました。
クライアントサイドのバリデーションもjQueryで実装しました。必須項目は「必須」のアイコンを添えておきます。
画面のデザインは1から作るのは時間かかるためCSSフレームワークを使いました。
また、スマホからも入力することがあるだろうということでレスポンシブ対応できるものが良いです。
ということで定番のBootstrapではなく今回は最近気になっていたBulmaを使いました。
色はGoogleのアプリのようなマテリアルデザインを意識して作ろうと思ったのですが、友人の御眼鏡に適わなかったので最終的にかわいらしい感じになりました。
Bulmaのテンプレートカラーに上書きしています。
マテリアルデザインの色はこちらから選ぶのがおすすめです。
https://material.io/resources/color/#!/
登録は画面遷移するとGASでどういった動きするかわからなかったので、GASの非同期通信ができるAPIを使い、jQueryとCSSで画面を切り替えました。
またユーザ目線の使いやすさということで読み込む中の画面や確認画面を用意しました。
【確認画面】
【読み込み中】
制御機能
URL自体は知っていれば誰でも表示できる設定にしている関係上、会員であるかのチェックとして、『ユーザID(メールアドレス)』をキーとしてGASでチェックを行っています。
これはスプレッドシートに会員一覧のシートがあるのでそこを参照しています。
月額制なので1か月決められた時間以上使っていないかのチェックも用意しています。
これに関連して、ユーザIDを入力して「照会」ボタンを押すと、非同期で会員の場合に1か月に何時間利用しているかの合計が算出される機能を用意しました。
この機能をつけたら友人に喜んでもらえたので良かったです。
Googleカレンダー用のチェックとして過去日付を登録できないようにしました。また、レンタルスペースは同時に1枠しか使えないため、すでに予定が入っている場合はエラーになるチェックを加えました。
それに関連してユーザがカレンダーを確認できるようにカレンダーのリンクを用意しました。カレンダーはGoogleアカウントを持っていなくても以下のように見れます。
誰かが予定を入れていても内容が見れるわけではなく。「予定あり」とだけ表示されるのでプライバシーも守られています。
もちろんGoogleアカウント持っている場合は自分のカレンダーに予定を入れれるのでGoogleカレンダーで自分の予定を管理している場合は合わせて利用できます。
メール
メールはGMailのAPIを利用しているので違和感なく顧客に送信できます。
制約として送信者が自分のアドレスになってしまうということがあったのですが、これは自分のアカウントにエイリアスを設定できるのでメーリングリストのアドレス名を設定したため、「info@ドメイン名」といったよくある形で送信することができました。
https://support.google.com/a/answer/33327?hl=ja
製造
実際の作成したソースをご紹介します。
前提として実際に作る方はGoogle Apps Scriptを使う準備としてこちらの記事をご覧ください。
以前書いた記事で作成したHTMLの画面と、スプレッドシートへの連携方法は書いたので今回は割愛します。以前の記事をご覧ください。
その他の部分としてカレンダー登録とメール送信部分をご説明します。
それぞれ引数として受け取っているparamは画面で入力した内容が入っています。
//カレンダー予約処理
function registerCalendar(param){
const calendar = CalendarApp.getCalendarById(CALENDAR_ID);
const title = param.user_name;
const startTime = new Date(param.calendar_date_from +' ' + param.calendar_time_from);
const endTime = new Date(param.calendar_date_to + ' ' + param.calendar_time_to);
const options = {
// description: param.comment,
// guests: param.user_id
};
options.from = "info@sample.com";
calendar.createEvent(title, startTime, endTime, {guests: param.user_id});
}
//メール送信処理
function sendRegisterMail(param){
const address = param.user_id;
const title = 'シェアキッチン予約完了通知';
const body = param.user_name + ' 様\n'
+ '以下の内容で予約を受付けました。\n\n'
+ 'メールアドレス:' + param.user_id + '\n'
+'氏名:' + param.user_name + '\n'
+ '日時:' + param.calendar_date_from +' ' + param.calendar_time_from + ' ~ '
+ param.calendar_date_to + ' ' + param.calendar_time_to + '\n'
//+ '備考:' + param.comment + '\n';
GmailApp.sendEmail(address,title,body,{from :'info@sample.com',name:'カスタマーサポート'});
}
カレンダー登録にはcreateEventを使います。
calendar.createEvent(title, startTime, endTime, {guests: param.user_id});
このAPIはカレンダーに開始時間と終了時間からイベントを登録します。
第4引数にはoptionを設定できます。公式リファレンスはこちらです。
メール送信にはsendEmailを使います。
GmailApp.sendEmail(address,title,body,{from :'info@sample.com',name:'カスタマーサポート'});
こちらも第4引数にoptionを指定できます。
公式リファレンスはこちらです。
これで一通り作ることができました!
感想
感想とユーザに使用間については追って記載していこうと思います。