BIGLOBEの「はたらく人」と「トガッた技術」

承認者だって楽したい😊Gmail上で承認できる社内システムをAppSheetで作る

ビジネスはスピードが命!承認だって、内容に問題がなければササッと終わらせたいですよね。そこでGoogleのノーコード開発ツールAppSheetを活用し、Gmail上で承認・却下の操作ができる承認アプリを作ってみました。

開発部門(基盤本部)の高玉です。BIGLOBEは業務にGoogle Workspaceを利用していて、メールはGmailを使っています。Gmailを使っていると分かるのですが、GoogleドライブやGoogleドキュメントから届くメールは動的メール(Dynamic Email)になっています。メールの文面にボタンやテキスト入力欄が埋め込まれていて、そのまま操作できます。

AppSheetを使えば、この動的メールを使った社内システムを作ることができます。この記事では簡易的な承認アプリを題材に、その作り方を丁寧に解説していきます。この記事で基本を押さえれば、AppSheetが提供するより高機能な承認アプリのテンプレートを理解するのにも役立ちます。現場に導入するには、慣れないAppSheetを使って申請してもらうより、従来のGoogleフォームを使う方がスムーズでしょう。そこで、Googleフォーム経由でAppSheetにデータを登録する方法も解説しています。

AppSheet上の画面操作を丁寧に解説した分、記事が長くなってしまいました。しかし、実際に手を動かしてみると、それほど時間はかかりません。ぜひお試しください。

動的メール、AppSheetで作れるってよ

動的メールはAMP for Emailという技術で実現されています。

developers.google.com

社内システムから届くメールも動的メールになっていると便利ですよね。ただ、動的メールを送信するには、Googleの事前審査を受けてセキュリティ的に問題がないことを確認してもらうなど、色々と手間がかかります。

しかし、Google Workspace Review 2022を視聴した時に、AppSheetを使えば動的メールを送信できることを知りました(ちなみに、2023年3月23~24日にさらに大規模なGoogle Workspaceのイベントを開催されるそうです)。Googleのブログでその様子を紹介しています。

https://storage.googleapis.com/gweb-cloudblog-publish/original_images/1_dynamicemailbloggmail.gif

Gmail の受信トレイでノーコード アプリを利用する方法 | Google Cloud 公式ブログより引用)

AppSheetで社内システムを作れることは前から知っていたのですが、動的メールを送信できることを知り、俄然興味が湧きました。早速試作に取り掛かり、承認者がGmail上で承認・却下ボタンを押せるところまで、何とか作ることができました。

私がやりたかったことはあくまで「動的メールを使うこと」で、AppSheetを使うことではありません。そこで、申請者には使い慣れたGoogleフォームから申請できるよう工夫しました。GoogleフォームとAppSheetを連携させるところにはGoogle Apps Scriptを使っているのでノーコードにはなりませんが、利用者にとっては違和感なく導入できると思います。

AppSheetを試して分かったデータモデリングの重要さ

先に、AppSheetを初めて使って感じたことをご紹介します。

AppSheetはコードを書かずに、色々なアプリを作ることができます。では、そうして生まれたたくさんのアプリを比較すると、何が違ってくるのでしょうか?デザインの違いなどもありますが、本質的にはデータ構造が違ってきます。データ構造の違いが、ビジネスロジックの違いになって現れます。

なので、AppSheetでアプリを作るには、アプリ使うデータを設計するデータモデリングが必須になります。特に、AppSheetはリレーショナルデータベースを使ってアプリを動かします。なので、リレーショナルモデルの理解が必須です。行・レコードを一意に特定するためのキーについても良く理解する必要があります。

これから紹介する承認アプリは簡易的なもののため、リレーショナルモデルの説明は省略しますが、キーについては事あるごとに気をつけるようお伝えしていきます。

より複雑なビジネスロジックを実装したくなったら、ぜひリレーショナルモデルについて調べてみてください。コードを書く時間を減らせる分、データモデリングの時間を意識的に増やす必要があると強く思いました。

ここから先は自分で作りたい方向け

ここからは、承認アプリを作っていく過程を全てご紹介していきます。簡単なロジックなのですが、画面を多用することもあり、かなり長い記事になってしまいました。ただ、データ構造もシンプルにして、AppSheetに慣れていない方にも工夫したつもりです。もしよろしければ最後までお付き合いください。

AppSheetやリレーショナルモデルに慣れている方は、公開されているテンプレートを実際にお試しいただくのがよいでしょう。AppSheetはアプリの雛形となるテンプレートを多数公開しています。その中に ApprovalsManager Approvalsがあります。動的メールの送信も設定済みです。Copy and Customizeボタンを押して自分の環境にコピーして試すことができます。

「テンプレートを試してみたけれど、中身を読み解くのはちょっと難しそう」と感じられた方は、どうぞ続きをお楽しみください。

まずはデータモデリングから

ここからは、

  • 申請者がGoogleフォームで申請し
  • 承認者がGmail上で承認する

承認アプリを作る過程をご紹介していきます。開発するステップは次の通りです。

  1. データモデリング
  2. GoogleスプレッドシートからAppSheetのアプリを作成
  3. Gmailにメールを送信してメール上で承認
  4. Googleフォームから申請してAppSheetにデータ連携

では早速、データモデリングに取り組んでいきます。アプリで使うデータを設計します。コードを書かずに開発できるのがAppSheetの特長ですが、コードを書かずに済む時間をぜひデータモデリングに充てていただければと思います。

登場人物は、申請者と承認者です。 申請者は申請画面で、申請内容と承認者のメールアドレスを入力します。 承認者は承認画面で、申請を承認、もしくは、却下します。

承認アプリで必要になる申請データには次の6つの項目が必要です。

  • 申請
    • 申請時刻
    • 申請者のメールアドレス
    • 申請内容
    • 承認者のメールアドレス
    • 承認結果(承認 or 却下)
    • 承認時刻

データベースに保存する時に重要なのが、どの項目をKey(キー)として扱うか?です。もしキーが同じデータが複数あると、それらデータは同じデータとして扱われてしまいます。違うデータには、必ず違うキーを設定する必要があります。

もし申請時刻をキーにしてしまうと、同時に申請があった場合にそれぞれを識別することができなくなります。そこで、キーになる項目として申請IDを新しく追加することにしました。申請は次の7つのデータ項目で表現します。

  • 申請
    • 申請ID(追加)
    • 申請時刻
    • 申請者のメールアドレス
    • 申請内容
    • 承認者のメールアドレス
    • 承認結果(承認 or 却下)
    • 承認時刻

試行錯誤を繰り返すうちに、もしも期待どおりに動かなくなったら、キーとなる項目を正しく作れているかを確認してみてください。

スプレッドシートからアプリを作る

データモデリングが完了したらGoogleスプレッドシートを新しく作り、そのスプレッドシートを元にAppSheetでアプリを作ります。

モデリング結果に従ってスプレッドシートを作る

スプレッドシートにシートを追加し、シートの名前を申請にします。そして、モデリング結果の項目を列にして入力します。

このスプレッドシートを元に、AppSheetで承認アプリを作ります。スプレッドシート上部のメニュー「拡張機能」> 「AppSheet」> 「アプリを作成」を選択します。

AppSheetがスプレッドシートを読み取り、自動的にアプリを作ってくれます。

スマホ画面のプラス(+)アイコンを押すと、新しい申請を追加することができます。 承認結果、承認時刻以外の申請項目を入力して、Saveボタンを押してみます。

すると、申請が保存されます。表示がおかしいですが今は気にせず、リストの一番上をタップします。

すると、先ほど入力した申請が表示されます。

えんぴつアイコンを押せば、追加した申請を編集できます。また、画面下部の「申請」を押せば、リスト表示になります。

申請シートにも、申請した内容が表示されています。

スプレッドシートからAppSheetを起動しただけで、ごく簡単な承認アプリを作ることができました👏

このアプリをカスタマイズして、さらに使いやすくしていきます。Customize your app(あなたのアプリをカスタマイズする)ボタンを押して先に進むと、以下の画面に変わります。

この画面は古い開発画面(レガシーエディター)です。ここから先はレガシーエディターで説明をしていきます。お使いの環境によっては画面レイアウトが異なっているかもしれません。画面の見栄えを変更するには、画面上部のhttps://storage.googleapis.com/support-kms-prod/qJPUOdtjZDyLswtPi5jex7nEJfpxUeJHDLwRアイコンを押してください。

データ型を設定する

見栄えを修正したい気持ちを抑えて、まずはデータ型(データ項目のTYPE)を設定していきます。AppSheetはデータ型に応じて入力画面を自動的に作り直してくれるので入力が楽になりますし、不正なデータを保存しなくて済むようになります。

まずはデータ項目が並ぶテーブルを確認します。左ペインでDataを選択し、Tablesタブで「申請」テーブルを選択します。

そして申請テーブルの上部View Columns(列を見る)ボタンを押します。上部にあるColumnsタブを選択し、申請テーブルを選択するのと同じ操作になります。

TYPE列を見ると、どの項目もTextになっています1。適切なものを選択していきます。

NAME(項目名) TYPE(タイプ)
_RowNumber Number
申請ID Text
申請時刻 DateTime
申請者のメールアドレス Email
申請内容 Text
承認者のメールアドレス Email
承認結果 Enum
承認時刻 DateTime

承認結果はEnumにします。Enumeration(列挙)の略です。入力する時に承認却下の2つから選択できるように設定します。承認結果の左横にあるえんぴつアイコンをクリックします。

TypeをEnumに設定し、Type DetailsのValuesにあるAddボタンを2回押して、2つの項目承認却下を入力します。最後に右上にあるDoneボタンを押して終了です。

これで申請テーブルのTYPEの設定が終了しました。

テーブルの設定が終わったら、AppSheetの画面右上にあるSAVEボタンを押しましょう。SAVEボタンが押されるまで、アプリに変更は反映されません。そしてもう一度、申請を追加してみます。右ペインに画面のプレビューが表示されます(もし表示されていなければ、右端にある三角形のアイコンを押してください)。+(プラス)アイコンを押すと、申請の入力画面が表示されます。

TYPEを変更した項目は、先ほどから表示が変わっています。申請時刻はカレンダーを使って入力できるようになり、メールアドレスはアットマーク(@)を使った正しい形式でなければ、This entry is invalidと赤字で警告されてSaveできなくなりました。

データ項目のTYPEを正しく指定したおかげで入力が楽になり、不正なデータを保存せずに済むようになりました。

自動でデータ項目を入力する

新しい申請を追加する時に、申請IDの項目には最初からランダムな文字列が入力されていました。このように、自動で入力される項目を増やしていきます。先ほどと同様に、左ペインDataから、Columnsタブで申請テーブルを選択します。自動入力の設定は、テーブルの設定を右にスクロールすると出てくるINITIAL VALUE(初期値)を使います。上から2つ目の申請IDにはすでにUNIQUEID()と入力されています。

さらに、申請時刻にUTCNOW() + "009:00:00"、申請者のメールアドレスにUSEREMAIL()と入力していきます。UTCNOW()はUTC時間の現在時刻で、そこに日本のタイムゾーン+9時間を反映します。USEREMAIL()はアクセスした人のメールアドレスを入力します。

NAME(項目名) INITIAL VALUE
_RowNumber
申請ID =UNIQUEID()
申請時刻 =UTCNOW() + "009:00:00"
申請者のメールアドレス =USEREMAIL()
申請内容
承認者のメールアドレス
承認結果
承認時刻

承認時刻はINITIAL VALUEではなく、FOMULAにUTCNOW() + "009:00:00"を入力します。少し左にスクロールして戻ります。これはApp fomulaという機能で値が変化した時に関数を実行します2

NAME(項目名) TYPE FOMULA INITIAL VALUE
_RowNumber Number
申請ID Text =UNIQUEID()
申請時刻 DateTime =UTCNOW() + "009:00:00"
申請者のメールアドレス Email =USEREMAIL()
申請内容 Text
承認者のメールアドレス Email
承認結果 Enum
承認時刻 DateTime =UTCNOW() + "009:00:00"

AppSheetの画面右上にあるSAVEボタンを押して、設定を反映します。先ほどと同じように申請を作成します。+(プラス)アイコンを押して申請画面を表示すると、申請時刻と申請者のメールアドレスが最初から入力されています。ここで申請をSaveしておきます。

今度は、先ほどの申請で承認結果を選択してみます。プレビュー画面下の申請アイコンを押し、新しい方の申請(2行目)を選択し、えんぴつアイコンをクリックします。すると承認時刻が現在時刻になっています。承認者が申請を編集し、承認結果を入力すると承認時刻が更新されるようになりました。

さて、この状態だと申請者が自分で承認結果を入力できてしまいますね。次のステップで修正していきます。

承認者だけが承認する

承認者だけが承認結果を編集できるようにしましょう。Columnsタブで申請テーブルを開き、右側にあるEDITABLE?(編集できるか?)に編集を可能にする条件を設定します。

承認者がアクセスしている時にだけ、承認結果を編集可能にします。そこで、承認結果のEDITABLE?に、[承認者のメールアドレス]=USEREMAIL()と入力します。ただ、この条件を入力するために、ちょっとした操作が必要になります。承認結果の左にあるえんぴつアイコンをクリックし、Update Behavior(データを更新するときの振る舞い)の下にあるEditableの更に右にあるフラスコアイコンをクリックします。

条件[承認者のメールアドレス]=USEREMAIL()を入力し、右上のDoneボタンを押します。

では、正しく設定できたか画面で確認します。まず画面右上のSaveボタンを押して変更を反映します。次に、画面プレビューから一番最初の申請を選択してみます。すると、承認・却下のボタンが表示されなくなりました。新しい申請を追加する時も同様です。

次に利用者のメールアドレスを承認者のメールアドレスに変更してみます。プレビュー画面の下にあるPreview app asで承認者のメールアドレスを入力しApplyボタンを押します。すると承認・却下のボタンが表示されるようになりました。承認・却下ボタンを押してSaveすと、承認時刻が更新されます。

EDITABLE?のチェックを外せば、編集できないようになります。申請時刻、申請者のメールアドレスはEDITABLE?のチェックを外しても、INITIAL VALUEが設定されているので自動入力されます。

また、申請者しか申請内容を編集できないように、申請内容のEDITABLE?に[申請者のメールアドレス]=USEREMAIL()と入力しておきましょう。

NAME(項目名) EDITABLE?
_RowNumber
申請ID
申請時刻
申請者のメールアドレス
申請内容 [申請者のメールアドレス]=USEREMAIL()
承認者のメールアドレス
承認結果 [承認者のメールアドレス]=USEREMAIL()
承認時刻

これで簡易版の承認アプリ3の完成です👏。いよいよ、この記事の目玉である、Gmail上での承認操作を実現していきます。

おまけで、申請一覧の表示を整えておきます(この先の説明には関係ありませんが、見栄えを良くしたい方もいらっしゃると思うので)。左ペインUXを選択し、Primary Viewで申請を選びます。View typeでdeckを選び、View Options では、

  • Primary header: 申請内容
  • Secondary header: 申請者のメールアドレス
  • Summary column: 申請時刻

をそれぞれ選択すると、見栄えが良くなります。

Gmail上で承認する

新しい申請が登録されると承認者にメールを自動送信し、承認者がGmail上で承認結果を入力できるようにします。

Automationでbotを追加する

Automation(自動化)でbot(ロボット)を作ることで、データの追加や変更に応じた自動処理を実行できるようになります。左ペインAutomationを選択すると、New Botの左に、オススメの自動処理が表示されます。Email on new recordを選択します。

すると、申請テーブルに新しいrecord(行)が追加されると、メールを送信するbotが作成されます。ここからは、送信する内容を調整していきます。真ん中のペインにある「Send an email」を選択します。もし、右ペインの画面プレビューに設定情報が表示されない場合、画面プレビュー上にあるギアアイコン(Settings)を選択します。

  • 右ペイン Settings
    • Email TypeはEmbedded app view(アプリの画面を埋め込む)
    • Table nameは申請
    • ToはAddボタンを押して[承認者のメールアドレス]と入力してEnter
    • Email subjectとEmail bodyは後で変更するので、とりあえずこのまま
    • App view to embed in mail body(メール文面に埋め込むアプリ画面)は申請_Detailを選択

App view to embed in mail bodyの下にあるPreview email body(メール文面のプレビュー)ボタンを押すと、別タブが開きメールのプレビューが表示されます。

画面の細かい調整は後回しにして、新しい申請に対してメールが送信されるかをテストしてみます。AppSheetはアプリの状態をPrototype(試作)とDeploy(公開)で切り替えられます。まずはPrototypeのまま開発すると影響範囲が狭くて安全なのですが、アプリの開発者にしかメールを送信できません。そこで、テストのために承認者に自分のメールアドレスを追加して、自分宛てに承認を依頼してみます。

忘れずにSaveをしてから続けます。画面プレビューで申請を追加し、承認者に自分のメールアドレスを入力します。もし画面プレビューにSettingsが表示されているままの場合、プレビュー上部でスマホアイコンを選択してください。申請一覧が表示されるので、右下のプラス(+)ボタンを押して申請を追加します。

うまく動作すれば、プレビューでみたのと同様な文面のメールが自分のところに届きます。

もしbotが期待どおりに動作しない場合は、エラーが発生していないかAudit Historyで確認します。左ペインManageを選択し、MonitorタブからAudit Historyを選択します。Launch log analyzerボタンを押すと別タブが開き、実行ログを確認できます。

ここまでで、承認依頼のメールが届くことが確認できました。いよいよ、Gmail上で承認の操作ができるようにします。

Quick edit columnsを追加する

Gmail上で承認できるようにするために、Quick edit columns(列をサクッと編集)を追加します。設定したデータ項目を画面上で素早く変更できるようになります。

左ペインUXを選択し、Primary Viewsから申請を選択します。画面を下にスクロールするとRef Viewsが出てきます。出てこない場合は、Show system views(システム画面を表示)ボタンを押してください。

Ref Viewsの下にある、申請_Detailを選択します。View Optionsの下にあるQuick edit columnsでAddボタンを押して枠を追加し承認結果を選択します。すると申請_Detail画面上に承認・却下ボタンが表示され、操作できるようになります。ボタンが表示されない場合は、画面プレビュー下のPreview app asが承認者のメールアドレスになっているか確認してください。

忘れずにSaveしてから、再び自分を承認者にして申請を追加します。メールの本文には、先ほど設定した申請_Detail画面が表示され、Gmail上で承認・却下ボタンを操作できるようになりました👏

承認ボタンを押すと、画面に小さく Saving...と表示され、それが終わると、承認時刻が更新されます。

Googleフォームから申請する

ここまでで承認者がGmail上で承認できるアプリが完成しました。しかし、新しく申請をするためにAppSheetを起動してもらう必要があります。AppSheetに馴染みのない方でも申請できるよう、Googleフォームから申請できるようにしてみます。

Googleフォームから入力したデータをAppSheetに連携する方法は、Googleフォーム用のAppSheetアドオンを使うやり方4と、AppSheetのAPIを呼び出すやり方があります。どちらもApps Scriptによるコーディングが必要になります。組織によってはアドオンが有効化されていない場合もあるので、今回は後者のAPIによる連携をご紹介します。

先にデータの流れを紹介しておくと、(1) Googleフォームへ入力、(2) 回答用のGoogleスプレッドシートに追記、(3) Apps Scriptを起動しAppSheet API呼び出し、(4) AppSheetのbotを起動し承認者に承認依頼のメールを送信、となります。(3) でコーディングが必要になります。

モデリング結果に従ってフォームを作る

Googleフォームを新しく作成し、最初に実施したデータモデリングの結果に従って、入力する項目を決めていきます。

申請ID、申請時刻、申請者のメールアドレス5はApps Scriptで生成し、申請に必要なその他の項目をフォームに作っていきます。

  • 申請
    • 申請ID(Apps Scriptで生成)
    • 申請時刻(Apps Scriptで生成)
    • 申請者のメールアドレス(Apps Scriptで生成)
    • 申請内容(フォームで入力)
    • 承認者のメールアドレス(フォームで選択)
    • 承認結果(申請時は不要)
    • 承認時刻(申請時は不要)

次は、フォームに入力された申請を処理するApps Scriptを準備します。

フォームのイベントをApps Scriptで受け取る

Googleフォームへの入力をトリガーにしてApps Scriptを実行する方法は2つありますが、フォームの回答に対してスプレッドシートを作る方がスクリプトの記述量を少なくできます。

フォームの回答タブから、スプレッドシートをリンクし、新しいスプレッドシートを作成します。

回答のスプレッドシートの上部メニュー「拡張機能」> 「Apps Script」でスクリプトエディターを開きます。

フォームからスプレッドシートに連携される送信イベントの仕様はこちらです。

developers.google.com

まずは、フォームからApps Scriptにイベントが連携されるかを確認します。次のスクリプトをスクリプトエディターに入力して保存します。実行ログにフォームから受け取った情報を表示するスクリプトです。なお、保存する時にプロジェクト名を決めるように促されます。どんな名前でも良いですが、今回はApplicationFormと入力しました。

function onFormSubmit(e) {
  console.log(e.namedValues);
}

次に、フォームからイベントを受信するためにトリガーを設定します。スクリプトエディターの左ペインでタイマーアイコンのトリガーを選択します。

少し分かりづらいのですが、画面右下にあるトリガーを追加ボタンを押します。

  • 実行する関数を選択
    • onFormSubmit
  • 実行するデプロイを選択
    • Head
  • イベントのソースを選択
    • スプレッドシートから
  • イベントの種類を選択
    • フォーム送信時
  • エラー通知設定
    • 今すぐ通知を受け取る

トリガーの設定ができたら、忘れずに画面右下にある保存ボタンを押します。実行権限について聞かれたら、付与を許可します。

ここまで設定できたら、フォームからApps Scriptにイベントが渡っているかを確認します。フォームに値を入力し送信ボタンを押します。

回答シートに戻って、フォームに入力した値が記録されているかを確認します。

スクリプトエディターに戻って、実行ログを確認します。左ペインの実行数を選択します。

フォームとApps Scriptの連携を確認できました。次は、Apps ScriptからAppSheetにデータを連携します。

Apps ScriptからAppsSheetのAPIを呼び出す

Apps ScriptからAppSheet APIを呼び出してデータを連携します。AppSheet APIの利用方法はこちらをご覧ください。ポイントは、HTTPリクエストヘッダーにApplicationAccessKeyを、URLにApp Idとテーブル名を入れることです。

support.google.com

ApplicationAccessKeyとApp Idは、AppSheetの開発画面で調べます。左ペインManageを選択し、Integrationタブを開きます。IN: from cloud services to your appにApp Idが表示されます。Enableをチェックすると、Create Application Access Keyボタンが表示されます。ボタンを押すと、Show Access Keyボタンが表示されるので押すと確認できます。これらの値が漏洩すると不正アクセスが可能になります。ご注意ください。

確認したApp IdとAccess Keyはスクリプトに記述したくないので、スクリプトプロパティに保存します。スクリプトエディターに戻って、左ペイン設定のギアアイコンを選択し、下の方にあるスクリプトプロパティで、スクリプトプロパティを編集ボタン、スクリプトプロパティを追加ボタンを押します。

  • APP_ID
  • APPLICATION_ACCESS_KEY

をそれぞれ追加して、AppSheetで確認した値をそれぞれ記入し保存します。

その上で、スクリプトエディターに次のスクリプトを追記します。

apply()はフォームから連携されたnamedValuesをAppSheetに追加します。

toRowObj()はフォームから連携されたnamedValuesをAppSheetのデータ形式に変換します。

appendRow()はAppSheetのAPIを呼び出して、データを追加します。追加が成功すると、追加したデータがJSON形式で返却され、失敗すると空文字が返却されます。

function apply(namedValues) {
  const tableName = '申請';
  return appendRow(tableName, toRowObj(namedValues));
}

function toRowObj(namedValues) {
  const obj = {
    '申請ID': Utilities.getUuid()
  };
  Object.keys(namedValues).forEach(key => {
    const value = namedValues[key][0];
    if (key === 'タイムスタンプ') {
      obj['申請時刻'] = value;
    } else if (key === 'メールアドレス') {
      obj['申請者のメールアドレス'] = value;
    } else {
      obj[key] = value;
    }
  })
  return obj;
}

function appendRow(tableName, rowObj) {
  if (!tableName) throw `テーブル名がありません。`;
  if (!rowObj) throw `追加するデータがありません。`;
  const props = PropertiesService.getScriptProperties().getProperties();
  const appId = props['APP_ID'];
  if (!appId) throw `スクリプトプロパティにAPP_IDがありません。`;
  const ApplicationAccessKey = props['APPLICATION_ACCESS_KEY'];
  if (!ApplicationAccessKey) throw `スクリプトプロパティにAPPLICATION_ACCESS_KEYがありません。`;
  const url = `https://api.appsheet.com/api/v2/apps/${appId}/tables/${tableName}/Action`;
  const options = {
    method: 'post',
    headers: {
      ApplicationAccessKey
    },
    contentType: 'application/json',
    payload: JSON.stringify({
      'Action': 'Add',
      'Properties': {},
      'Rows': [rowObj]
    }),
    muteHttpExceptions: true
  };
  // console.log(UrlFetchApp.getRequest(url, options));
  const res = UrlFetchApp.fetch(url, options);
  const result = {
    responseCode: res.getResponseCode(),
    contentText: res.getContentText()
  }
  console.log(result);
  return result;
}

では追記したスクリプトが正しく動作するか確認します。まずは、Apps ScriptからダミーのデータをAppSheetに追加できるかを確認します。確認のためのテストコードをスクリプトエディターに追記します。

function test_申請が成功すると_200_レスポンスと追加結果が返却される() {
  const namedValues = {
    '申請内容': [ 'Apps Scriptの書籍を購入します。' ],
    'メールアドレス': [ 'staff1@example.com' ],
    '承認者のメールアドレス': [ Session.getActiveUser().getEmail() ],
    'タイムスタンプ': [ '2023/02/03 7:23:21' ]
  };
  const result = apply(namedValues);
  if (result.responseCode !== 200 || result.contentText === '') throw 'NG';
}

テストではappy()の返却値を確認して、失敗していればNGの例外を出します。スクリプトエディターの実行ログに何も表示されなければ正常です。このテストをスクリプトエディターで実行すると、AppSheetにデータが追加され、スプレッドシートに新しい申請が追加され、承認依頼のメールが自分宛てに届きます。

スクリプトエディターにNGのログが表示される場合は、スクリプトエディターの実行ログや、前述したAppSheetのAudit Historyを確認して失敗の原因を探ります。

ここまで確認できたら、スクリプトエディターで、onFormSubmit()を書き換えて、フォームから受け取ったイベントをAppSheetにそのまま連携します。

function onFormSubmit(e) {
  apply(e.namedValues);  
}

最後に、Googleフォームで承認者のメールを自分にして申請すると、承認依頼メールが自分に届くことを確認します。

最後に、AppSheet上でDeploy(公開)すれば、他の人も使えるようになります。AppSheetの左ペインManagerを選択し、Deployタブを選択します。先に、deployment checkを実行して公開可能かを確認し、大丈夫ならMove app to deployed stateボタンを押して公開します。お疲れ様でした👏

まとめ

この記事では、業務で動的メールを使うためにAppSheetを使うプロセスをご紹介しました。プロセスを説明するために、かなり長い記事になってしまいましたが、最後まで読んでくださりどうもありがとうございます。

Apps ScriptとGoogleフォームを併用して、AppSheetを使っていることを利用者から隠蔽する方法もご紹介しました。ノーコードにはなりませんが、AppSheetを業務に導入する際のハードルを下げる一つの手段になると思います。応用していただければ幸いです。

AppSheetを使いこなすにはリレーショナルモデルの理解が重要です。今回はじめてAppSheetを使ってみて、「あれ?なんで動かないの?」と頭を悩ませた結果、やっとそのことに気がつきました。BIGLOBEの新人エンジニア研修でも、データモデリング(リレーショナルモデル)は基礎から学んでもらっています。データ構造の違いがアプリの振る舞いの違いになって現れるAppSheetは、データモデリングを学ぶ教材としても優れていると思います。

AppSheetはたくさんのテンプレートを公開しています。気になるアプリが見つかったら、ぜひ中を覗いてみてください。うまく流用すれば、すぐに業務改善に役立つかもしれません。ぜひご活用ください💪

Apps Scriptを活用して業務を改善した話はこちらでもご紹介しています。よろしければご覧ください。

style.biglobe.co.jp

※ Google、Gmail、Google Workspace、Google Apps、AppSheet は Google LLC の商標であり、このブログはGoogle によって承認されたり、Googleと提携するものではありません。

※ 記載している団体、製品名、サービス名称は各社またはその関連会社の商標または登録商標です。


  1. AppSheetはまだ日本語が不得意なようで、項目名からTYPEを類推してくれませんでした。
  2. 当初は承認時刻のTYPEをChangeTimestampにし、承認結果の変更をWatchする実装にしていました。しかしGmailから承認結果を操作した時の時刻にタイムゾーンが反映されませんでした。そこで仕方なく、FOMULAにUTC時間とタイムゾーンを手入力して設定しています。
  3. 実際の業務では様々な承認フローが存在します。例えば、申請の種類に応じて承認者が変わるケースや、複数の承認者が必要なケースなど。異なる承認フローを実現するには、データモデリングから設計し直す必要があります。
  4. Googleフォーム用のAppSheetアドオンを使うとAppSheet APIを呼び出さなくても、回答用のスプレッドシートに入力されたデータをAppSheetに連携できます。そこで、回答用シートに追加で申請ID、申請結果、申請時刻の3つの列を追加すればOKです。ただしAppSheet側で申請IDを自動入力できないため、回答用シートにデータが入力されたことをトリガーにしてApps Scriptで申請IDを付与する必要があります。こちらのスクリプトを参考にしてください。
  5. Google Workspaceを使っている場合、フォームに登録した人のメールアドレスを自動的に収集できます。