通知文面テンプレートの書き方
通知文面(タイトル・本文)を作成する方向けの手引き。
- 対象読者:
notification_templateに登録する文面を書く方 - 前提:通知基盤(Worker)は、この文面に値を差し込んで SSE・メール・受信箱へ配信する
- 関連:【通知基盤】機能設計
1. どこに書くか
Section titled “1. どこに書くか”文面は notification_template テーブルの 2 つの列に入る。
| 列 | 内容 |
|---|---|
notification_title_template | 通知タイトル。受信箱の一覧・メールの件名になる |
notification_content_template | 通知本文。受信箱の詳細・メール本文になる |
どの文面が使われるかは、次の4 つの組み合わせで決まる。
| キー | 例 | 意味 |
|---|---|---|
notification_case | FLIGHT_PLAN_CONFLICT_CAUSED | 通知ケース(何が起きたか) |
notification_dest_type | SELF | 宛先種別(誰に送るか) |
notification_method | EMAIL | 通知手段(SSE / OS / EMAIL / UI) |
| 適用期間 | available_date_from 〜 available_date_to | いつからいつまで使う文面か |
同じキーで期間が重なる文面は登録できない(DB の除外制約で弾かれる)。文面を差し替えるときは、
古い行の available_date_to を新しい行の available_date_from に合わせる。
期間を先に登録しておけば予約もできる(例:明日 9 時から新文面)。
通知手段ごとに別レコードになる。同じ通知でも、メールは丁寧に長く、SSE は短く、といった書き分けができる。 10 月デモでは OS 通知(
OS)は対象外なので用意不要。
2. 記法(Thymeleaf テキストテンプレート)
Section titled “2. 記法(Thymeleaf テキストテンプレート)”HTML ではなくプレーンテキストとして扱う。タグは書かない。
2-1. 値を埋め込む
Section titled “2-1. 値を埋め込む”[(${userName})] さん
飛行計画が重複しています。機体ID: [(${aircraft_id})][(${...})]… 値をそのまま出す。通常はこちらを使う[[${...}]]… エスケープして出す。テキスト文面では通常使わない
2-2. 条件で出し分ける
Section titled “2-2. 条件で出し分ける”[# th:if="${orgName}"]所属組織: [(${orgName})][/]2-3. 繰り返す
Section titled “2-3. 繰り返す”以下の飛行計画が対象です。[# th:each="plan : ${plans}"]- [(${plan.flight_no})]([(${plan.start_time})])[/][# で始めて [/] で閉じる。閉じ忘れると文面が壊れるので注意。
3. 使える変数
Section titled “3. 使える変数”3-1. 予約語(通知基盤が必ず用意する 5 つ)
Section titled “3-1. 予約語(通知基盤が必ず用意する 5 つ)”どの通知ケースでも使える。業務側が Outbox に入れる必要はない。
| 変数 | 内容 | 例 |
|---|---|---|
userId | 宛先ユーザのID | 3f0c1e42-9c53-... |
userName | 宛先ユーザの名前 | 山田 太郎 |
toAddress | 宛先メールアドレス | taro@example.com |
orgId | 宛先ユーザが所属する組織のID | 8a12b7d9-4e60-... |
orgName | 宛先ユーザが所属する組織の名前 | 〇〇ドローン株式会社 |
toAddressは全通知手段で共通の予約語。メール設定を持たないユーザ宛の SSE 通知などでは 空文字になる。文面に載せるときは 3-3 の「値が無いとき」を確認すること。
3-2. 業務が渡すパラメータ(param)
Section titled “3-2. 業務が渡すパラメータ(param)”通知を依頼する側(業務サービス)が Outbox の param に入れた JSON のキーが、そのまま変数名になる。
// Outbox の param に入っている JSON{ "aircraft_id": "DRN-2026-X1", "latitude": 35.65858, "longitude": 139.74543}機体 [(${aircraft_id})] が飛行禁止エリアに侵入しました(緯度 [(${latitude})] / 経度 [(${longitude})])。どのケースでどのキーが来るかは、通知を依頼する業務側と合わせること。
3-3. 値が無いときの挙動
Section titled “3-3. 値が無いときの挙動”- 変数が存在しない、または値が
nullの場合は空文字として描画される(エラーにはならない) - 「値が無ければ行ごと消したい」場合は
[# th:if=...]で囲む
4. 守っていただきたいこと
Section titled “4. 守っていただきたいこと”| # | ルール | 理由 |
|---|---|---|
| 1 | param のキー名は英数字とアンダースコアのみ(aircraft_id は可、aircraft-id は不可) | [(${aircraft-id})] は「aircraft 引く id」という引き算と解釈され、値が出ない。ドット・スペース・先頭数字も同様 |
| 2 | 値の見せ方(桁数・単位・書式)は、渡す側で確定させる | 通知基盤は値を加工しない。受け取った文字列をそのまま差し込む。35.65858 を 35.66 と出したいなら、渡す時点でそう入れる |
| 3 | HTML タグを書かない | テキストとして扱うため、タグはそのまま文字として出る |
| 4 | 外部の画像・リンク先を埋め込まない | メールの到達性に影響するほか、文面は暗号化対象の情報を含みうる |
| 5 | 個人情報を文面に直接書かない | 宛先ごとの値は予約語(userName 等)で差し込む。テンプレート自体は宛先に依存しない形にする |
| 6 | 文面が見つからない場合、その通知手段はスキップされる(通知全体は止まらない) | 10 月デモの割り切り。登録漏れは静かに欠落するため、必要な case × dest_type × method の組み合わせを揃えること |
4-2. メール通知(EMAIL)で追加でお願いしたいこと
Section titled “4-2. メール通知(EMAIL)で追加でお願いしたいこと”10 月デモのメール通知は Amazon SES で送り、宛先には Microsoft Teams のチャネルも含まれます。 実際に送って確認した結果として、次の 4 点をお願いします。
| # | ルール | 理由 |
|---|---|---|
| 1 | タイトルだけで内容が分かるように書く | タイトルが Teams チャネルの投稿タイトルになります。 一覧では本文が見えないため、「通知があります」のような文面だと何の通知か分からなくなります |
| 2 | タイトルに改行を入れない | 件名は 1 行です。改行が入っていた場合、通知基盤側で半角スペースへ置き換えます |
| 3 | 段落は空行(改行 2 つ)で区切る | 空行での段落分けは Teams でもメールクライアントでも意図どおりに表示されることを確認しています。単一改行 1 つだけの挙動は未検証なので、段落の区切りには空行を使ってください |
| 4 | 装飾(太字・色・表)は使えない | 本文はプレーンテキストで送ります(HTML メールにはしません)。強調したいときは 【】 や記号で表現してください |
改行コード(\n / \r\n)はどちらで登録していただいても構いません。送信時に通知基盤が \r\n(メールの規格)へ揃えます。
5. 記入例(デモシナリオ 2 本)
Section titled “5. 記入例(デモシナリオ 2 本)”5-1. 飛行禁止エリアへの侵入(INTRUSION_NOFLY_AREA)
Section titled “5-1. 飛行禁止エリアへの侵入(INTRUSION_NOFLY_AREA)”タイトル
[(${aircraft_id})] が飛行禁止エリアに侵入しました本文(メール)
[(${userName})] さん
[(${orgName})] が運航する機体 [(${aircraft_id})] が、飛行禁止エリアに侵入しました。発生位置: 緯度 [(${latitude})] / 経度 [(${longitude})]
速やかに違反状態を回避してください。5-2. 飛行計画同士の競合(起因側)(FLIGHT_PLAN_CONFLICT_CAUSED)
Section titled “5-2. 飛行計画同士の競合(起因側)(FLIGHT_PLAN_CONFLICT_CAUSED)”タイトル
飛行計画の重複が検出されました本文(SSE。画面に短く出す想定)
[(${userName})] さんの飛行計画が他の計画と重複しています。運航調整を開始してください。6. 登録のしかた
Section titled “6. 登録のしかた”notification.notification_template への INSERT で登録する。
INSERT INTO notification.notification_template (notification_case, notification_dest_type, notification_method, notification_title_template, notification_content_template, available_date_from, available_date_to)VALUES ('INTRUSION_NOFLY_AREA', 'SELF', 'EMAIL', '[(${aircraft_id})] が飛行禁止エリアに侵入しました', '[(${userName})] さん' || chr(10) || '...', '2026-10-01 00:00:00+09', '2099-12-31 23:59:59+09');available_date_toは終わりを決めていなければ十分先の日時を入れる(NULL 不可)- 同じキーで期間が重なる行があると、除外制約でエラーになる
7. 確認したいことがあれば
Section titled “7. 確認したいことがあれば”- どのキーが
paramに来るかが分からない → 通知を依頼する業務側へ確認 - 文面が正しく差し込まれるか試したい → エアロダインへご連絡ください。ローカル環境で描画結果を確認できます
本書の記法は Thymeleaf のテキストテンプレートモードに基づく。**描画エンジンの実装は Step3 で行い、 そこで実際の描画結果を確認する。**差異が見つかった場合は本書を更新する。
@author Yuki Sudoh (Aerodyne Japan)