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

QRコードとApps Scriptで社内業務を楽しくデジタル化

開発部門(基盤本部)でエンジニアの育成を担当している高玉です。

BIGLOBEではスタッフ部門とエンジニアが協力して、社内業務を改善しています。試行錯誤を繰り返しながら何とか成功させた例として、QRコード、GoogleフォームとApps Scriptを活用して、備品の補充を簡単に依頼できる仕組みをご紹介します。Google Workspaceを利用している会社や学校ならすぐに取り込める仕組みですので、ぜひご活用ください。

新人エンジニアのスキルアップを狙ってはじめたこの取り組みですが、数々の失敗もありました。そこから得られたノウハウや、Apps Scriptを使いこなすための細かいテクニックまでご紹介していきます。

QRコードを使った備品の補充依頼

まず、完成した仕組みをご紹介します。文房具棚や複合機のそばにQRコードを掲示しています。

BIGLOBEでは社員にGoogle Workspaceが利用できるAndroid™のスマートフォンを配布しています。封筒やコピー用紙など備品が不足している場合にスマホでQRコードを読み取ります。するとスマホにGoogleフォームが表示され、備品の補充を依頼できます。

フォームが送信されるとその内容が即座にスタッフ部門のGoogle Chatへ通知され、スタッフが在庫から物品を補充します。

使ってみた方からは、嬉しい感想をたくさんいただきました。

  • 備品の担当者をわざわざ探す手間が省けた
  • 備品がすぐに補充されるようになった
  • QRコードを読む体験が楽しい😊

ただ、一番のハードルはQRコードを読めるかどうかです。スマホの機種によって読み取り方が違うため、つまづいている人も多くいました。そこで、社内イントラブログで「普段、どうやってQRコードを読んでいますか?」と質問し、情報を集めて共有しました。

  • カメラアプリでQRコードを読むのが一番直感的
  • それができない機種では、Googleレンズを起動する
    • カメラアプリから起動
    • ホーム画面のGoogleウィジェットから起動
    • ホームボタンを長押しして「QRコードをスキャンして」と話しかける

Googleレンズを起動する方法

社内で「困ったらQRコードを読んでみる」という新しい体験が受け入れられてホッとしています。そして何より嬉しかったのが、スタッフ部門の喜びの声です。

  • 不足品の巡回が不要になった
  • 備品の使用頻度が記録されるので、文具棚に入れておくべき「標準品」を工夫できるようになった
  • アイデアが形となり、仕事が楽になる経験を通じて、仕事をするのが楽しくなった🎉

デジタル化によって、無駄な巡回を減らせただけでなく、漠然としていた使用頻度がハッキリと分かるようになりました。その結果、効果の高い工夫ができるようになったのは大きな収穫です。

失敗からの学び

この業務改善の取り組みは、新人エンジニアのプログラミングスキル向上を目的にはじめました。社内で改善したいことを募集して、意気揚々と開始したのですが、当初はことごとく失敗してしまいました…。失敗の理由と対策は次の通りです。

  • 試作品はできたが、設定が面倒で結局使われなかった
    • ⇒ 機能を絞ってとりあえずリリース
  • 自動化するには元の業務を変更しなければいけないが、変えたくなかった
    • ⇒ 要求者との会話のキャッチボールを大切に

機能を絞ってとりあえずリリース

動くものを素早く作り、体験してもらうことを優先しました。当初は、文房具ごとにQRコードを発行し、それを連続で読み取らせるアイデアも出たのですが、Apps Scriptで実装するのは少し大変です。そこで「QRコードを読んだら、フォームを表示するだけ」にあえて機能を絞り込みました。

フォームの項目も必要最小限にしてサクッと作り、実際に「QRコードを読む」ことが体験できるように実装し、その行為が受け入れられるかを検証しました。

要求者との会話のキャッチボールを大切に

コミュニケーションに気をつけて、真の要求を一緒に探しました。業務に詳しいスタッフ部門は、改善のアイデアもたくさん持っています。一方、エンジニアはそうしたアイデアを聞くと「実装しやすいか?難しいか?」という観点で反射的に回答しがちです。その結果、実際の業務からかけ離れた実装になってしまうこともあります。

アイデアに対して「できる・できない」と回答する前に、「そもそも、どうしてその要望を叶えたいのか?」を引き出すよう、会話のキャッチボールを心掛けました。

業務改善で仕事を楽しく

業務改善は失敗するのが当たり前、と思いながら、工夫を続けている様子をお伝えしました。

アイデアが形となるのは楽しいものです。また、仕事が楽になれば、次のチャレンジに使える余裕も生み出せます。デジタル化したい業務はまだまだありますので、楽しみながら取り組んでいくつもりです。

なお、新人エンジニア研修の最後に実施するチーム開発演習でも、Apps Scriptを使った社内システムを作っています。今回ご紹介したボトムアップのアプローチと違い、アジャイル開発(スクラム)のプロセスに則って、中規模のウェブアプリを開発しています。ご興味があればぜひご覧ください。

style.biglobe.co.jp

style.biglobe.co.jp

Google Workspace / Apps Script のTips集

ここからは、実際に使っている技術を詳しく紹介していきます。ちなみに、新人エンジニアには「使える武器を普段から増やしておく」ことの大切さを訴えています。使える手段が多ければ、課題解決が楽になるからです(その反面、ハンマーを持つと何でも釘に見えてしまうもので、どう適用するかは十分に気をつける必要がありますが)。かなり細かい話になりますが、参考になれば幸いです。

GoogleスプレッドシートでQRコードを作る

GoogleフォームのURLをQRコードに変換するのに、スプレッドシートを使うことができます。

スプレッドシートのIMAGE関数とENCODEURL関数、そして(Deprecatedされた)Google Chats APIを使います(いつGoogle Chats APIが使えなくなってもおかしくありません。ご注意ください)。

support.google.com

support.google.com

developers.google.com

例えば、A1セルにURLを入力し、B1セルにQRコードを表示する次の関数を入力します。

=IMAGE("https://chart.googleapis.com/chart?chs=450x450&cht=qr&chl="&ENCODEURL(A1))

すると、B1セルにQRコードが表示されます。

Googleフォームの事前入力でフォームの数を減らす

Googleフォームの「事前入力したURLを取得」を使うと、フォームを1つ準備して、そのフォームに予め値を設定した状態のURLを別々に払い出すことができます。

support.google.com

複合機のコピー用紙補充フォームは1つだけ準備しました。プルダウンでどの複合機かを指定します。

複合機を選択した状態で「リンクを取得」ボタンを押せば、その複合機用のURLを取得できます。上述した方法で、そのURLをQRコードに変換します。

回答に応じたセクション移動を再帰させ一度に複数の申請をする

QRコードを読んだ後に開いた申請画面で、複数の物品を申請するテクニックです。「回答に応じてセクションに移動」を再帰的に利用します。

support.google.com

文房具棚は、文房具、封筒、紙袋、といった異なる分類の物品を扱っています。扱う物品全てを一つの画面に表示すると、数が多すぎて選択するのが大変です。そこで、分類ごとにセクションを分けつつ、最初に「何を補充しますか?」と質問して、分類を選んでもらうことで、一画面で表示する物品を絞ります。

各セクションでは、その分類に含まれる物品をチェックボックスで選択させます。そして最後に「他に補充するものはありますか?」と質問して、必要であれば別の分類も選べるようにします。

こうすることで、QRコードを読んだ後、一度の申請で複数の分類から物品を選べるようになります。逆にこうしておかないと何度もQRコードを読んでもらう必要が出てきます。

Googleフォームからの通知はやり方が2種類ある

Apps Script を使って、フォームが送信されるとGoogle ChatやGMailに通知をしています。そのスクリプトを記述する場所は、Googleフォームのスクリプトエディタか、回答のスプレッドシートのスクリプトエディタになりますが、イベントのデータ形式がそれぞれ異なるので要注意です。

Googleフォームのエディタを使う場合は こちらです。FormResponseオブジェクトが渡されるのですが、若干使いづらいので、 Googleフォームで送信されたデータを使いやすいJSONに変換するにあるコードでJSONに変換して使います。

一方、スプレッドシートのエディタを使う場合はこちらです。namedValuesの値が配列になっていることに注意が必要ですが、これで十分なことがほとんどです。

なおフォームで受信した情報をGoogle Chatで通知するには、Webhookを使います。

developers.google.com

function notify(text) {
  const webhookUrl = 'https://chat.googleapis.com/v1/spaces/xxx/messages?key=xxx&token=xxx';
  const response = UrlFetchApp.fetch(url, {
    method: 'post',
    headers: {
      contentType: "application/json; charset=UTF-8"
    },
    payload: JSON.stringify({ text })
  };
  console.log(response);
}

もちろん、メールで通知することも可能です。

developers.google.com

メールの送信元は、そのApps Scriptを作った人になりますが、options に {noReply: true} を指定しておくと、送信元がnoreplyになるので便利です。

Googleフォームの項目と回答スプレッドシートの列をあわせる

Googleフォームの項目を試行錯誤しながら作っていると、回答のスプレッドシートの列の並びが、フォームの項目の順序とはずれてきます。そんな時は、フォームとスプレッドシートのリンクを一度解除して、再びリンクします。回答データはフォーム側がModelとして持っていて、スプレッドシートはそのView / Controllerでしかないので、簡単にリンクし直すことができます。

まず、フォーム、もしくは、スプレッドシートで「フォームのリンクを解除」します。フォームから解除するには、回答タブのケバブメニュー(縦に並んだ三つの点)から、スプレッドシートからならシートのタイトルから、それぞれ選びます。

次に、スプレッドシートの回答タブで「回答先を選択」します。既存のスプレッドシートを選んだ場合でも、新しいシートが追加されて、古い回答シートは残されます。

メールアドレスから氏名を取得して入力項目を減らす

Googleフォームの項目数はできる限り減らしたいものです。Google Workspaceだと、フォームに入力した人のメールアドレスを自動的に取得できるので、そこからAdmin Directory SDK ServiceのUsers.get()を利用して氏名を取得できます。

なお、Google Workspace の設定によっては、Users.get()のオプションに{viewType: 'domain_public'}が必要になるので注意してください。

developers.google.com

Apps Script から Admin Directory を利用するには、次のドキュメントが役に立ちます。

developers.google.com

Apps Scriptでユニットテスト

少し複雑なロジックを書く時にユニットテストが欲しくなります。特に、Googleフォームからの通知など、わざわざフォームを操作しないと動作を確認できないコードは調整が面倒です。CLIを使ってApps Scriptを開発できる clasp を使うほどでもない場合は、自作のassert関数を使ってテストケースを書き、スクリプトエディタ上で実行しています。

/**
 * 与えられた条件が true であることを表明する。
 * @param {boolean} cond 条件
 * @throws もし条件が true でないなら NG
 */
function assert( cond ) {
  if(cond !== true) throw 'NG'
}

/**
 * 与えられた値が期待値と同じ(===)ことを表明する。
 * @param {string} actual 値
 * @param {string} expected 期待値
 * @throws もし値が期待値と同じでないなら NG
 */
function assertEquals( actual, expected ) {
  if(actual !== expected) throw `NG: ${actual} !== ${expected}` 
}

/**
 * 与えられた関数を実行した結果、例外が発生することを表明する。
 * @param {function} func 関数
 * @throws もし関数を実行した結果、例外が発生しないなら NG
 */
function assertThrows(func) {
  try {
    func();
  } catch (e) {
    Logger.log(e);
    return;
  }
  // Exception が発生して、ここは実行されないはず
  throw 'NG: 例外が発生しませんでした。';
}

その他、Apps Scriptの便利なテクニック

とても便利なGoogle Workspace / Apps Scriptですが、何が制限になるかは最初に調べておく必要があります。

Google サービスの割り当て

developers.google.com

なお、Apps Script でコーディングする時に、知っていると便利なのが、関数名の末尾にアンダースコア(_)をつけるとプライベートになることや、関数の説明をJSDocで書けること、です。

developers.google.com

実行速度を上げるためのベストプラクティスもあるので、参考にしてみてください。

developers.google.com

※ QRコードは、株式会社デンソーウェーブの登録商標です。

※ Google、Google Chat、GMail、Google Workspace、Androidは、Google LLCの商標です。

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