MS Flowを活用してFormsから勤怠連絡を一括送信してみた

## 弊社の勤怠連絡システムの説明

弊社では、社内ツールとしてMicrosoft Office365を使用しています。
勤怠連絡もOutlookメールで送り、Teamsにも転送されたりしています。

![01_現行イメージ図.png](https://qiita-image-store.s3.amazonaws.com/0/316374/345442fc-33d5-fe85-0f66-f9090339cb99.png)

Teamsには全体向けの勤怠連絡チャネルと、部署内の勤怠連絡チャネルもあります。
部署チャネルは残業・休日出勤の承認を得るために作られましたが、遅刻連絡が多くを占めています。

ただ、事前に予定している休みや早退ならともかく、遅刻するような時には三度手間が掛かります。
個人端末に会社のOfficeアカウント情報を登録するというのも、情報機密的に気が引ける。
何よりメールにしろTeamsにしろ、**文章を読まないと、誰がどのくらい遅刻するのか分からない**のが不便。
ということで、可能な範囲で独自にFlowを構築し、一括処理してみました。

## 改良イメージ

![02_改良イメージ図.png](https://qiita-image-store.s3.amazonaws.com/0/316374/27aa39e4-7ce8-a2ed-e6ae-970615ff8d4f.png)

ブラウザからFormsを開いて、そこから必要事項を入力して送信。
するとメールもTeamsにも、それぞれに合わせた文言で送信してくれる。
そのうえ、予定表（カレンダー）にも予定として登録すれば一目瞭然！
アカウントを紐付けずFormsを開くだけだから、メールの送信は出来ても受信はしなくてセキュリティも安心。

MSのサービスを使っているのに、ブラウザアイコンはEdgeじゃなくてChromeで良いのか？
と思われるかも知れませんが、大丈夫です。弊社製品の動作確認ブラウザは「最新のGoogleChrome」ですから。

![03_カルテZERO動作環境.png](https://qiita-image-store.s3.amazonaws.com/0/316374/bb9228a0-c61f-f79a-445b-88c8fb27d2b0.png)

## Formsを作成する

![04_Formsイメージ図.png](https://qiita-image-store.s3.amazonaws.com/0/316374/dccebfdb-1719-05dc-64ea-ccc1897d15c8.png)

- 遅刻理由
- どのくらい遅れるか
- その他連絡事項

この3項目だけ。
連絡事項は「今朝掃除当番だったので誰か助っ人お願いします」とか。無ければ省略。

![05_Forms項目追加メニュー.png](https://qiita-image-store.s3.amazonaws.com/0/316374/51f9e4e9-3f17-699a-9da2-8c6f7c9c8b26.png)

Formsの項目作成は、ラジオボタン選択やテキストボックス入力など簡単。
どのくらい遅れるかを時刻で入力できれば良かったのですが、
「日付」は年月日だけだったので「30分/1時間/その他」からプルダウンで選択する形に。
「その他」を選んだ場合は、別途テキストボックスが出てきます。

そして右上にある共有メニューから、回答と送信の収集対象を
「**リンクにアクセスできる全てのユーザーが回答**」にしておきます。
「所属組織内のユーザーのみが回答」にすると、結局ログインが必要になってしまいますから。
ログインが必要なくなる分、**取得したURLを他の人に教えないように注意**。

![06_Formsリンク取得.png](https://qiita-image-store.s3.amazonaws.com/0/316374/c23167e9-05e9-1b98-b1dd-2a95895625fb.png)

## テンプレートからFlowのベースを作成

まず、Flowの完成イメージがこちら。
スイッチの中身については最後に説明します。
![07_Flow完成図.png](https://qiita-image-store.s3.amazonaws.com/0/316374/b950cd40-9b63-8213-17f3-02fc578024fe.png)

https://japan.flow.microsoft.com/ からFlow管理画面に入り、「テンプレート」を選びます。
１から作っても良いのですが、簡単なフローならテンプレートが用意されているので便利。

![08_Flowテンプレート選択1.png](https://qiita-image-store.s3.amazonaws.com/0/316374/20efaff3-d293-1a74-487a-0dbdf970b22f.png)

Formsを使っているテンプレートの中から、今回は「Formsの応答を受信したら通知を送信する」を参考にします。
アカウントの連携が成功したら「続行」。通知は使いませんけれど。

![09_Flowテンプレート選択2.png](https://qiita-image-store.s3.amazonaws.com/0/316374/b8eee9b9-b3ef-20c9-be94-f3e1b8b792f7.png)

テンプレートの初期内容はこんな感じ。

![10_Flowテンプレート編集1.png](https://qiita-image-store.s3.amazonaws.com/0/316374/1ec72543-2f09-056d-9fd2-f8158d54dfc6.png)

先頭の「When a new response is submitted（新しい応答が送信されるとき）」で、
フォームIDを先程作成した勤怠連絡フォームを選択。

応答が送信されると**ループ処理に入ります**。ここがFormsでFlowを作るときのネックの1つ。

フォームからは以下のような感じで1件分の応答通知が出力されていますが、
連続回答にも対応しているのか、分解してLoop処理が必要になるようです。

```
[
  {
    "webhookId": "********-****-****-****-************",
    "eventType": "ResponseAdded",
    "resourceData": {
      "formId": "********************************************************************************",
      "responseId": 1
    },
    "eventTime": "2019-03-18T08:26:25.0175407Z"
  }
]
```
※webhookIdとformIdはマスクしていますが、実際は正しいIDが入ります

「Get response details（応答の詳細を取得する）」でも、同様にフォームIDから勤怠連絡フォームを選択。
次にある通知送信は今回は要らないので、三点リーダメニューから削除してしまいます。

![11_Flow通知削除.png](https://qiita-image-store.s3.amazonaws.com/0/316374/ddd30e0d-314c-322c-4358-4907cbdc638b.png)

## Formsの回答をそのままメッセージに埋め込む

通知を削除した代わりに新しいアクションを追加することが出来るので、まずはメールの送信を選んでみます。
V2を選ぶとHTMLメールも出来るようですが、簡単なテキストメールならV2が無い方でも十分。

![12_Flowメール送信選択.png](https://qiita-image-store.s3.amazonaws.com/0/316374/910e63a6-d561-0dd5-43d5-44272b3a4680.png)

送信先や固定の文言はそのまま入力すれば良いですし、
フォームに入力した内容を直接埋め込む場合は「動的なコンテンツ」から参照できます。

![13_メール文面埋め込み.png](https://qiita-image-store.s3.amazonaws.com/0/316374/082d04a6-0931-49a4-9800-06011e45e717.png)

テストの間はとりあえず、宛先を自分自身にしておいて保存。
保存されたかどうか分かりにくいですが、上部タイトル横に「保存済み」と出れば保存成功です。

![14_Flow保存確認.png](https://qiita-image-store.s3.amazonaws.com/0/316374/303d208f-e5eb-445c-bd88-442712de4bab.png)

保存したら、最初に作ったFormsを開き、フォームから回答をしてみます。

![15_Forms入力例.png](https://qiita-image-store.s3.amazonaws.com/0/316374/3b424bdb-0c4e-f389-6681-d9ce492a0def.png)
　↓
![16_メール受信結果.png](https://qiita-image-store.s3.amazonaws.com/0/316374/d2baed56-ac07-59b5-5266-999c7bf0cbd6.png)

メールが送信されました！
理由も時間も、その他連絡事項もちゃんとフォームで回答したとおりになっています。
導線の矢印上にカーソルを合わせると、分岐を作ることも出来ます。

![17_並列分岐追加.png](https://qiita-image-store.s3.amazonaws.com/0/316374/000d3af2-fa78-b8a8-f776-709321fe9628.png)

メールと同じ要領で、分岐先にTeams投稿を追加すれば、Teamsにも同時に投稿できるようになります。
テスト中はまだ送信しない方が良いですが。

![18_Teamsメッセージ送信追加.png](https://qiita-image-store.s3.amazonaws.com/0/316374/25cd4d3f-cbd5-dabb-9a6f-a351d91ac628.png)

これで、ここまでは作れました。

![19_中間イメージ図.png](https://qiita-image-store.s3.amazonaws.com/0/316374/7fb0014f-2095-4020-2b6b-54e2ea7fd134.png)

## 日付データを加工する

ただ、これだとフォームに入力した内容しかメール文中に入れられません。
メール表題に日付を付けたり、予定時刻を入れるには、日時データを加工してアクションを作成します。

まずはメール表題に付ける日付から。
送信するのは当日朝を想定して、今日の日付を「01/23」のような文字列に変換します。

メールを送信する手前のところで「アクションを追加」を選択。
「組み込み」の中にある「データ操作」を選んで、データ操作の中から「作成」を選びます。

![20_データ操作選択.png](https://qiita-image-store.s3.amazonaws.com/0/316374/38cf937f-98c0-f72f-4f80-f67bc024145d.png)

![21_データ作成選択.png](https://qiita-image-store.s3.amazonaws.com/0/316374/f7f8f90e-fc11-29d0-c24d-6eff56dd7ee1.png)

「作成」を作成したところで、「作成」のままだとややこしいので名前を「月日」に変えておきます。
加工した出力データを埋め込んだ後からは、名前変更することが出来なくなるので最初のうちに。

![22_データ作成名称変更.png](https://qiita-image-store.s3.amazonaws.com/0/316374/afa7de0d-4687-4cc5-a008-f272088877ac.png)

名前を変えたら、入力のテキストボックスを選択。
メール本文中にFormsの回答を埋め込むときは動的なコンテンツを使いましたが、
今度は「式」を使って、関数を組んで値を生成します。

![23_データ関数選択.png](https://qiita-image-store.s3.amazonaws.com/0/316374/f017f45b-81ef-ffb0-d552-a5942450f179.png)

色んな関数があり、繁用関数もピックアップされていますが、リファレンスはこちら。
https://docs.microsoft.com/ja-jp/azure/logic-apps/workflow-definition-language-functions-reference

日付・時刻関数もあるので、その中から以下のように関数を組みました。

```
formatDateTime(convertFromUtc(utcNow(), 'Tokyo Standard Time'), 'MM/dd')
```

現在のタイムスタンプを取得する関数はUTCで返してくるので、UTCを日本標準時に戻してから月日形式に変換します。
TimeZoneIDの名前がJapanやAkashiでなく「Tokyo Standard Time」には違和感ありますが、[そう決まっているようなので](https://docs.microsoft.com/ja-jp/previous-versions/windows/embedded/gg154758(v=winembedded.80))。

式の関数欄に入力してOKすると、関数が入力されます。月日の入力に直接コピペしたらダメです。

![24_データ関数入力.png](https://qiita-image-store.s3.amazonaws.com/0/316374/7e346a81-e543-6e31-2940-2629e44402f3.png)

すると、メール文面で選べる動的なコンテンツの中に「月日」の「出力」が追加されるので、
これを件名に入れると、その日の日付を件名に追加することが出来るようになります。

![25_月日埋め込み.png](https://qiita-image-store.s3.amazonaws.com/0/316374/7cbe90f7-ec0d-3a75-c0d0-b71e015b52fd.png)

前回実行した回答からテストするとこの通り。

![26_月日埋め込み結果.png](https://qiita-image-store.s3.amazonaws.com/0/316374/dc36e1e4-0677-066a-6680-a976a01386aa.png)

## 日時データを加工して予定を登録する

月日を生成した要領で、予定追加のための日時も作成していきます。
予定追加する場合に肝になるのが、標準では**予定の開始時刻・終了時刻もUTC指定**であること。
そのため、一度JSTに変換して長くなるより、UTC基準のまま計算してしまった方が分かりやすいと思います。
弊社の場合、始業時刻はちょうど9時（＝UTCの0時）なので、この1行で済ませてしまいました。

```
startOfDay(utcNow())
```

もし10時始業だったら1時間足して、こんな感じで。

```
addHours(startOfDay(utcNow())), 1)
```

続いて予定終了時刻となる出勤予定時刻。
まず式の入力欄に**関数を入力してから動的なコンテンツに切り替えて**、
始業時間を選ぶと、関数の中に動的コンテンツを差し込むことも出来ます。

![27_関数内に始業時刻挿入.png](https://qiita-image-store.s3.amazonaws.com/0/316374/a66c6ac2-597c-13c8-eb57-b1e2e698f97f.png)

あとは第二引数に30を付け足してOKすれば、30分後が終了時間に。

予定表へのイベント作成は、Office 365 Outlookの「イベントの作成(V2)」アクションを選んで、
予定表ID、イベントの件名、開始時刻に始業時刻、終了時刻に30分後を設定します。

![28_イベント作成.png](https://qiita-image-store.s3.amazonaws.com/0/316374/a932ea44-6021-52f6-83ec-344344a3ce16.png)

開始時刻も終了時刻も変数名は「出力」となってしまうので見分けが付きにくくなりますが、
三点リーダメニューからコードレビューを開けば、確認できるようになっています。

![29_イベント作成コードビュー.png](https://qiita-image-store.s3.amazonaws.com/0/316374/c42a4217-c138-95fd-8910-ad20a37deaad.png)

終了時刻はFormsでの選択に応じて変えたいので、
組み込みアクションの中からスイッチを使い、遅刻時間の選択に応じて振り分けます。

![30_スイッチ選択.png](https://qiita-image-store.s3.amazonaws.com/0/316374/5ec49546-6512-75e0-0d8d-c9748639b7cb.png)

スイッチの中身がこんな感じ。
「30分」でも「1時間」でも無い場合、その他(default)は予定上は3時間にしています。

![31_スイッチ内部分岐.png](https://qiita-image-store.s3.amazonaws.com/0/316374/ca5b6e2c-9684-b037-ea3b-40341d3f6eba.png)

これで冒頭で書いたイメージの完成です。

![01_現行イメージ図.png](https://qiita-image-store.s3.amazonaws.com/0/316374/345442fc-33d5-fe85-0f66-f9090339cb99.png)

これでメール・Teamsでの勤怠連絡に加えて、
自分の予定表を見てもらえれば、30分遅刻することが一目で分かるようになりました！

![32_予定追加結果.png](https://qiita-image-store.s3.amazonaws.com/0/316374/e4ac975c-bcc3-62fa-422f-afde8ef40a1b.png)

## 終わりに

半月前に遅刻した日に思い立ってFlowを作り上げてみましたが、出番はまだ来ていません。

実は昨年6月頃まで社内システムがGSuiteだった頃にも、
GoogleフォームとGoogleAppsScriptでメール+カレンダーへの一括送信を作っていたのですが、
そっちも作ったあと出番が無いままOffice365へ移行したので、作り直していませんでした。
このFormsもこのまま出番が無いのが良いのですが、これを機にFlowも活用してみようかと。

だいぶ長くなってしまいましたが、この記事が他にFlow構築に挑む方の参考になれば幸いです。