FormsとPower AutomateでEntra IDのゲスト招待システム&棚卸システムをつくってみる(その7:棚卸編)

今回から棚卸処理が始まります
過去6回にわたり、Formsを使ったゲスト招待システムの作成にお付き合いいただき、ありがとうございます。
いよいよ今回から棚卸処理を前回までとは別のクラウドフローで作っていきます。
基本的な考え方
クラウドフローのトリガーには1日1回実行させる繰り返しを使います。もう少し凝ってみたければ、以前に記事を書いたこちらを参考にしてもらうのも良いかと思います。

https://qiita.com/DaddyDaddy/items/08d6f20b6ed7bdd57967
ゲストを管理しているSPOリストから棚卸対象を一覧化する
SharePointリストには、InventoryDeadline列を用意しています。この列にはゲスト招待の申請の際に、何日間ゲストを有効にするかをリクエストするのですが、申請が通った日に日数を加えた日付が入っています。
ゲストの棚卸では、この日付の2週間前になったら、申請者(すでに退職している場合には承認者)に、ゲストとして招待した社外のユーザーを続けてゲスト扱いするかどうかを決めさせることにします。

今日の日付と棚卸期限が一致したら削除の対象となりますから、今日の日付に14日間を加えた日付と、招待期限(InventoryDeadline)の日付を比較します。
たとえば、本日が5/3なら期限を2週間前に控えた5/17よりも手前の日付である一覧を取得したいです。

Power AutomateではSharePointやExcelのテーブルから行の一覧を取得する際に、ODataフィルタークエリを利用できます。列名と以下のような演算子を使って、マッチした行だけに絞り込むことができます。
演算子 | 意味 | 例 |
---|---|---|
eq | 等しい(equal) | Name eq 'Tanaka' |
ne | 等しくない(not equal) | Age ne 30 |
gt | より大きい(greater than) | Price gt 1000 |
ge | 以上(greater than or equal) | Score ge 80 |
lt | より小さい(less than) | Age lt 18 |
le | 以下(less than or equal) | Quantity le 50 |
現在の日付から14日先の日付を取得して、InventoryDeadline列の値と比較して取得します。結果が正(True)となる値が取得できます。ついでに、 and 演算子も使ってApprovalStatusが’ゲスト’と一致する行に絞り込んでおきます。
これはゲストの申請中や、すでに削除されたものを取り除き、現在ゲストであり、かつ(And)期限が近い外部ユーザーだけを一覧化するためです。

申請者に棚卸リクエストメールを送信する
棚卸期日が近づいているゲストの申請者に、ゲストの取り扱いを決めてもらうためにメールを送信します。
受け取った申請者がメール上の選択肢を選ぶだけで棚卸ができると素晴らしいので、私も初めて使うアクションですが「オプションを指定してメールを送信します」を試してみます。まずは、自分自身にテストメールを送ってみて、どのようなメールが届くのか確認します。

届いたメールをOutlookで見てみると、以下のようなメールが届きました。どうやら青く表示されているボタンを押せば返信できるようです。

試しに、Choice2 をクリックしてみると、以下のような画面に変わりました。

クラウドフローの結果をみてみると、なんとChoice2が選択されたことが結果として記録されています!

これは素晴らしいのですが、問題があります。「複数の項目の取得」アクションで取得した複数の申請者に対して、Apply to eachで連続してメールを送信した場合、各ユーザーの入力結果が返されるまで待機するのでは?
と思いながら、試しに以下のような処理を作ってみました。申請者がメール上の選択肢をクリックした内容をTeamsで確認してみます。あらかじめSPOリストには棚卸対象を2行追加しておきました。

1件目のメールが届きました(承認者がJSONのままだったのはご愛嬌。メールも改行されていないので、HTMLの改行タグが必要みたい。あとで修正します。)
90日延長をクリックします。すると、Teamsには選択された日数が通知されました。


Apply to each は待機したままです。2件目を処理したら終了するのでしょうが・・・1件目が完了するまで2件目には進まないんだろうか?

2件目はアデルさんを申請者としていたので、アデルさんは「ゲスト招待を終了」を選択してみます。するとApply to eachは終了しました。
再度実験
もういちどテストを実行してみます。今度は、アデルさんにメールが届いているかどうかを先に確認しましたが、届いていません。いっぽう、ループ1件目のdaddyさんの元にはメールが届いています。ということは、daddyさんが回答しないとアデルさんには棚卸メールは届かないということになります。これはいけない。
以下の2つの対策を施すことで、複数の申請者に対してメール送信と、その回答に対する処理が行われました。
対策1 コンカレンシー制御をつかう
Apply to eachで順番待ちをするのではなく各回を同時に処理するために、コンカレンシー制御の設定をすると良いようです。並列処理の次数は最大何件のメールをおくるかを想定して設定するとよいでしょう。

対策2 タイムアウトの設定
もうひとつは、「オプションを指定してメールを送信します」アクションのタイムアウト期間設定です。
いつまでも待機していてはリソースの無駄遣いですので、1週間でタイムアウトすることにして「P7D」と入力しました。

メール回答のテキストを数値に変えてSPOリストを更新
メールで回答された選択肢の日数と、それによって現時点から日数を加算した棚卸期限をSPOリストに書き込みます。
最初は以下のようにスイッチで条件わけしてSPOリストに書き込もうかとも思ったのですが、ちょっと冗長ですね。

変数をつかうと、コンカレンシー制御の場合には値が変わってしまうとのことだったので、「作成」のなかでif関数をつかって整数に変化しました。
//作成
if(equals(outputs('オプションを指定してメールを送信します')?['body/SelectedOption'], '90日延長'), 90,
if(equals(outputs('オプションを指定してメールを送信します')?['body/SelectedOption'], '180日延長'), 180,
if(equals(outputs('オプションを指定してメールを送信します')?['body/SelectedOption'], '360日延長'), 360,
if(equals(outputs('オプションを指定してメールを送信します')?['body/SelectedOption'], 'ゲスト招待終了'), 0, null)))))
これをSPOリストに書き込みます。棚卸期限にはもともとの棚卸期限にメールで回答された日数を加算します。

SPOリストの棚卸期限が更新されたので、つぎにこのクラウドフローが実行される際には棚卸対象として抽出されません。
ついでに、申請者に対して期限が延長されたことをメールでお知らせします。「作成」がゲスト招待終了を示す0では無いことを条件にしました。

ゲスト招待終了の処理は?
今回はユーザーからの選択肢によってゲスト招待終了が選ばれた場合、棚卸日数に0が加算されるようにしました。つまり、棚卸日付は動かないという意味です。
棚卸期限が過ぎている場合にゲストから削除する処理は別途必要ですが、ゲスト招待終了を選択されたのですから度々催促メールを送らないようにしましょう。
このクラウドフローが動作する条件は、ステータスが「ゲスト」であることなので、「ゲスト削除予定」に切り替えます。延長日数は0にして保存をクリックしたところ、エラーが発生。実はSPOリストを元にFormsを作成する際に数値の範囲を90〜360に設定していたため、0の数値は受け付けないのでした。
無理に0にする必要もないので、更新させないため空欄にと思いましたが、それだと必須項目なのでやはりエラー。仕方がないので元の値をもう一度上書き保存することにしました。

延長のSPOリストへの更新は条件の手前で行っていましたが、「作成」の結果がゼロの場合にはSPOリスト更新を受け付けてくれないので、条件の中で更新するように変更しました。

テストしてみます
SPOリストの元の状態はこちら。2名がゲスト状態です。

コンカレンシー制御のおかげで、1人目のメールで「ゲスト招待終了」をえらぶと、その時点でSPOリストも更新されました。

2人目は「360日延長」を選択してみました。備考欄に状況が記録され、新たな延長日数が記録されるはず・・・


InventoryDeadlineの欄が更新去れるべきところ、ApplicationDateTimeを更新してしまっていました。気を取り直してもう一回。
1人目はすでにステータスが「ゲスト削除予定」担っているので、2人目だけが処理されました。これで棚卸期限が変更され、棚卸対象がいなくなったのでフローを再度実行しても処理対象はいなくなりました。

おさらい
今回は棚卸対象の申請者に対して、棚卸期限2週間前にメール送信でゲストの取り扱いの選択を求める処理を作成しました。
- SPOリストに対して、棚卸対象をODataクエリのフィルターをつかって一覧化して、メールを送信しました。
- 「オプションを指定してメールを送信」アクションを使って、ワンクリックで返答ができるようにしました。
- コンカレンシー制御をONにしないと、複数の申請者に対してメールを送信しても順番待ちが生じてしまう点に注意が必要でした。
- コンカレンシー制御のなかで変数を使うのは危険なので、メールの返信でうけた選択肢を整数に変化させるのにif関数とequals関数を使いました。
こんな人が作ってます
これでほぼ完成ですが、肝心のEntra ID のゲストからの削除処理がまだ残っていました。次回はそのあたりを加えていきます。
QiitaやこのブログではPower Automateの話題を中心に投稿を行っていますので、ぜひ「いいね」してくださると励みになります。
ディスカッション
コメント一覧
まだ、コメントがありません