IM-BloomMaker でリモートワークの報告メールを送信するアプリを作ってみた

はじめに

IM-BloomMaker と IM-LogicDesigner で「リモートワークの報告メールを送信するアプリ」を作成したので、公開します。

新型コロナウィルスによる緊急事態宣言を受けて、弊社 NTTデータイントラマート の赤坂本社ではリモートワークをしている社員がほとんどです。
弊社の開発本部では、在宅勤務におけるルールとして、勤務開始と終了のタイミングで、開発本部メンバーのメーリングリスト宛に報告メールを送ることが義務付けられています。

【在宅勤務開始】【PDG】 2020-04-17 %名前%

お疲れ様です。%名前% です。

本日の予定は以下の通りです。
- 10:00-18:30(例)

作業場所:自宅

作業内容は以下を予定しています。
- %予定作業1%
- %予定作業2%

以上、よろしくお願いします。

ここで、以下の課題が発生しました。

  • 所属によっては、送信するアドレスが 1 つではなく、毎回宛先を設定するのがめんどくさい
  • 毎回メーラーを開くのがめんどくさい。(開発本部では、メインのコミュニケーションツールに IMBox を利用しており、メールはあまり利用していません。)
  • メールのタイトルを、テンプレート通りに設定するのがめんどくさい
  • 文章をテンプレート通りに記載するのは、もっとめんどくさい
  • 受信されるメールのタイトルの中で 【在宅勤務終了】 や 【在宅勤務完了】 などの表記揺れがあり、メールの振り分けルールを作るのがめんどくさい

いずれも些細なことではあるのですが、これらを解決するアプリを作成しようと考え、実装して社内システムに導入しました。

作成するアプリの要件

上述した課題や、報告メールのルールをもとに設定した要件は以下です。

  • 出勤 または 退勤 のタイミングで、それぞれのメールのテンプレートが利用できること。
  • メールの宛先 ( To, CC ) は、毎回入力しなくて良いこと。
  • メールのタイトルにルールを持たせること。
  • 所属グループごとに 【PDG】 や 【クラウドG】 のように、固定文字列を挿入できること。

ダウンロードはこちら

以下の資材は、 2020 Spring 以降の環境で、利用可能です。

IM-LogicDesigner インポート資材 : 181221_im_logicdesigner-data.zip

IM-LogicDesigner のインポート機能を利用してインポートしてください。
インポート後、インポートしたルーティング定義の認可 URI の設定を行ってください。
以下の資材がインポートされます。

種別 ID / ルーティング
フロー im_cookbook_181221_flow_remote_work_report_mail
ルーティング im_cookbook/181221_remote_work_report_mail

IM-BloomMaker インポート資材 181221_im_bloommaker-data.zip

IM-BloomMaker のインポート機能を利用してインポートしてください。
また、ルーティングは資材に含まれていませんので、ご自身での作成をお願いいたします。
以下の資材がインポートされます。

種別 ID
コンテンツ im_cookbook_181221

そのまま利用すると、メールが送信されてしまうのでご注意ください。
なお、メールの From は、ログインしているユーザのメールアドレスが利用されます。
メールアドレスが設定されていないユーザは、利用できないようになっています。

実装のポイント

変数の設計

作成したコンテンツは、以下のような変数構造になっています。

{
  "state": {
    // 画面上のエレメントで利用する変数
  },
  "requestData": {
    // サーバサイドに送信するためのリクエストデータを格納するオブジェクト
  },
  "responseData": {
    // サーバサイドからレスポンスデータを受け取るためのオブジェクト
  },
  "temporary": {
    // アクション内で利用する一時変数。ここの変数は、画面に直接影響を与えない。
  }
}

このような構造にすることで、変数が何に使われているのかがわかりやすくなると考えています。

また、定数は以下のような構造になっています。

{
  // 出勤タイプ
  "TYPE": {
    "START": "start",
    "END": "end"
  },
  // 所属組織
  "DEPARTMENT": {
    "NONE": "",
    "PDG": "pdg",
    "CLOUDG": "cloud",
    "TSG": "support"
  },
  /* 省略 */
}

列挙型 (enum) のような利用をする場合は、オブジェクトを作成し配下に定数を作成してあります。
こうすることで、列挙が後から増えた場合も、メンテナンスがしやすいと思います。

出勤・退勤 の自動判別

ページ読み込み時のタイミングで動作するアクション「初期表示イベント」内で、以下の実装を行っています。
15 時以降は退勤が設定されるようになっています。


if (new Date().getHours() >= 15) {
  $variable.state.type = $constant.TYPE.END;
  $variable.state.message = $constant.END_EMAIL_TEMPLATE;
}

ページ読み込み時のイベントは、「コンテナ」のプロパティを編集してください。
2020 Spring からは、「コンテナを選択」アイコンが追加されましたので、ぜひご利用ください。

2019 Winter までは、選択しているエレメントを、 Ctrl キーを押しながらクリックすることで、コンテナを選択できます。

テキストボックスに値が入力されたら、次のテキストボックスが出現

アクションに以下のような機能を入れています。

  • To や CC を指定するテキストボックスにユーザが値を入れたら「To のリスト更新」アクションを発火
    1. リストの中に空文字が存在する場合は、空文字を除去
    2. カスタムスクリプトで、リストの一番最後に空文字を追加
  • 確認ダイアログを開くタイミングで「確認ダイアログを開く」アクションを発火
    1. リストの中に空文字が存在する場合は除去する。

「To のリスト更新」アクションでは、以下のようなカスタムスクリプトを実行しています。

const list = $im.resolve('$variable.state.toList');

const tempList = list.filter((s) => s);
tempList.push('');

$variable.state.toList = tempList;

一般的に、 JavaScript のラムダ式はとても便利なのですが、 Internet Explorer での動作を考慮すると、スクリプト開発モデルでは利用できません。
しかし、 IM-BloomMaker のカスタムスクリプトでは、 ES6 ベースのスクリプトを記述しても、 Internet Explorer で動作するよう、自動でトランスパイル(変換)される仕組みが実装されています。
そのため、レガシーブラウザを意識することなく、ラムダ式やテンプレートリテラルなどを利用したスクリプトを実装することができます。

To, CC, 所属組織のキャッシュ

ひとことで書くと、ブラウザの localStorage を利用して実装されています。
そのため、キャッシュにおける処理については、サーバサイドでの実装は行っていません。

localStorage は、ブラウザに標準で実装されているキー・バリューの保存領域です。
なお localStorage はとても簡単な仕組みであり、 JavaScript から簡単に中身を参照できてしまいます。
そのためセキュアな情報の保存には利用してはいけないことに注意してください。

ダイアログを開くタイミングで発火する「確認ダイアログを開く」アクションでは、 localStorage にキャッシュを持たせています。

if (localStorage) {
  const json = JSON.stringify({
    department: $variable.state.department,
    toList: $im.resolve("$variable.state.toList"),
    ccList: $im.resolve('$variable.state.ccList')
  });
  localStorage.setItem($constant.LOCAL_STORAGE_KEY, json);
}

また、ページ読み込み時のタイミングで発火する「初期表示イベント」アクションでは、 localStorage
保存してあるキャッシュからの復元処理を実装しています。

if (localStorage) {
  const json = localStorage.getItem($constant.LOCAL_STORAGE_KEY);
  if (json) {
    const cache = JSON.parse(json);
    $variable.state.department = cache.department;
    $variable.state.toList = cache.toList;
    $variable.state.ccList = cache.ccList;
  }
}

上記のコードにおいて、 if (localStorage) の if 文で全体が囲まれています。
Internet Explorer の設定で localStorage の仕様をオフにできる機能があり、これによってスクリプトの実行時エラーが発生してしまうことを防ぐためです。

なお、 intra-mart Accel Platform では、もともと以下のような制限事項が存在します。そのため、上記については「念の為」の実装です。

  • intra-mart Accel Platform リリースノート - 制限事項 - クライアントブラウザ

    ローカルストレージやCookieの保存および読み取りが可能な設定でブラウザを利用してください。

ダイアログ内の、メール本文のラベル

フォームのテキストエリアでは、以下のようにメール本文が初期値として入力されています。

これを、確認ダイアログで表示する際に「ラベル」エレメントをのまま利用すると、以下のように行の始めに半角スペースが詰められてしまいます。

この事象を回避するために、「ラベル」エレメントに mail-message-preview のような id を付与して、以下のような CSS を設定しています。

#mail-message-preview {
  white-space: pre;
}

こうすることで、以下のように、行のはじめの半角スペースが詰められず、期待通りに表示されます。

このように、 IM-BloomMaker では CSSエディタを利用することで、簡単に CSS を設定することができます。

おわりに

当該記事でご紹介したように、身近な改善を短期間で実現することができました。
こういったちょっとした改善は、 IM-BloomMaker / IM-LogicDesigner / IM-FormaDesigner の得意とするところです。
これを機に、より深く製品を知っていただけると幸いです。

最後まで読んでいただき、ありがとうございました。