やる気駆動型エンジニアの備忘録

WPF(XAML+C#)の話題を中心に.NET/Android/CI やたまに趣味に関するブログです

(Power Automate)Plannerに登録したタスクの期限が近い場合に通知するフローを作成する

現在、私が所属しているチームではタスク管理ツールにMicrosoft Plannerを使用しています。 単純な親子関係のないタスクであれば簡単に管理できて、チェックリストや期限の設定もでき、進捗状況や割当状態をグラフやカレンダーで可視化することができます。 また、Web会議は Teams を主に使用していることもあり、連携するならこれが今の所ベストな選択肢となっています。 感覚的には Trello と同じように使えるのもポイントです。

しかし、Planner そのものに期限を通知するための仕組みはありません。 そのため、業務で利用する際に「遅延しているタスク」がモリモリ増えていって、このままではタスク管理している意味がない!と思い、Power Automate で毎日通知するようにしました。

今回はその方法についてまとめておきます。

環境

  • Power Automate
  • Planner
  • チャットツール

チャットツールは何でも良いです。Slack や Teams ならコネクタがあるのでそちらを使いましょう。 弊社では Chatwork を使っていたのでカスタムコネクタを作ってメッセージを送るようにしました。

今回は Power Automate がメインで、カスタムコネクタや Planner についての話はしません。

やりたいこと

やりたいことは以下の3つです。

  1. 当日が期限のタスク一覧を通知する
  2. その週が期限のタスク一覧を通知する
  3. 遅延しているタスク一覧を通知する

実際のところ、この3つは通知が必要なタスクかどうかの判断以外はすべて同じなので1つだけ説明して、他は差分箇所のみ紹介します。 そしてこれを実行すると以下のようなメッセージが表示されます。

f:id:iyemon018:20200913165236p:plain

通知するメッセージには以下の情報を記載します。

  • 期限
  • タスクタイトル
  • 割り当てられた担当者の名前

フローを作成する

フローは次のような構成になっています。 全体のざっくりとした流れはスケジュール実行→Plannerからタスク取得→通知用メッセージ初期化→条件に一致するタスクを収集・メッセージの整形→チャットに送信となっています。 詳細は番号にそって説明します。

f:id:iyemon018:20200913165945p:plain

1. スケジュールの設定

説明するまでもないですね。通知したい時間を設定します。 タスクの通知なので、できれば朝一番か業務開始直前とかが良いと思います。

2. タスクを一覧表示します

Planner から該当するグループ・プランのタスクを収集します。 こちらも説明は不要ですね。 取得したいグループ・プランIDを指定するだけです。

3. 変数を初期化する/4. 変数を初期化する 2

今回、変数は2つ用意しました。 1つは期限であるタスク一覧を通知するためのメッセージで、もう1つは実際に通知するメッセージです。 参考までに今回は以下のように設定しました。

③期限であるタスク一覧を通知するためのメッセージ
・名前:task_list
・種類:文字列
・値:(何も設定しない)

④実際に通知するメッセージ
・名前:chatwork_send_message
・種類:文字列
・値:(何も設定しない)

なぜこんな回りくどいやり方をするかと言うと、今日が期限のタスクが0件の場合にどう通知するかを考慮したためです。

今日が期限のタスクが0件の場合、通知された側としては何が表示されていればいいでしょうか? 今回のケースでは「今日が期限のタスクは0件です。」と通知するようにしました。

仮に、「通知しない」という選択をした場合、フローが動いているのかどうか通知を見た側はわかりません。 そうなるとフローが間違っているのか期限になるタスクが無いのか判断できません。 そうなるよりは通知は増えますが、「0件です」と表現したほうがわかりやすいと思います。 (チームによってどう通知するべきかは変わるのでここは調整してください)

この要件を満たしたいので、「3. 変数を初期化する」に期限が今日であるタスク一覧の通知用メッセージを代入し、「4. 変数を初期化する 2」に実際に通知するメッセージを代入します。

5. タスク一覧を収集してメッセージを整形する

ここが一番のメインです。収集したタスクを条件に一致するかどうか判断し、一致する場合はメッセージを作成します。 収集するタスクは複数あるのでループで処理していきます。 更に詳しく見ていきます。

f:id:iyemon018:20200913171214p:plain

ポイントは2つ。「a. 通知すべきタスクかどうかを判断する」の条件と「b. 割当先ユーザーごとにメッセージを整形する」のメッセージ整形部分です。

a.通知すべきタスクかどうかを判断する

ここでは、「今日が期限のタスクかどうか」を判断します。 条件式には次のものを設定しています。

  • <empty(items('タスク一覧を収集してメッセージを整形する')?['dueDateTime'])>次の値に等しい<false>
    Planner では期限dueDateTimeは空欄でも許容されます。空欄の場合はこれ以降の条件式で比較した場合、エラーになるためこの条件を先頭に持ってきています。
  • <値 達成率>次の値未満<100>
    Planner の達成率は数値で表現され、範囲は 0 ~ 100 となっています。100 だと達成してしまうため、100 未満としています。
  • <ticks(items('タスク一覧を収集してメッセージを整形する')?['dueDateTime']) >次の値以上<ticks(addDays(utcNow(), 0))>
    期限が UTC の現在日時以降かどうかを判断しています。わざわざaddDaysで 0 日を加算しているのは、この後の条件式と比較しやすいためです。 また、判定する期間を変える場合(例えば今週期限のタスクを収集するといったケース)、0 の部分を変更するだけでいいので少し楽できます。
  • <ticks(items('タスク一覧を収集してメッセージを整形する')?['dueDateTime'])>次の値未満<ticks(addDays(utcNow(), 1))>
    期限が UTC の現在日付+1日以前かどうかを判断しています。上の条件と組み合わせて"今日"という条件を作り出しています。

b.割当先ユーザーごとにメッセージを整形する

条件に一致したタスクを収集できたら次はメッセージの整形です。 Planner では、1つのタスクに対して複数ユーザーを割り当てることができます。 通知するのであればタスクに割り当てられた全員に通知するべきです。

通知メッセージの内容は要件次第ですが、今回は1つのタスクに複数ユーザーが割り当てられた場合、ユーザーごとに1行メッセージを追加していくことにしています。 「割当先ユーザーごとにメッセージを整形する」がループになっているのはそのためです。 このループでは割り当て先ユーザーIDを値としています。 実は、Planner でタスクを収集しても割り当てられたユーザー名は取得できません。 そこで、ユーザーIDを使います。

このユーザーIDは、Microsoft 365 の ID に紐付けられています。 なので、Microsoft 365 の「ユーザー プロフィールの取得(V2)」を選択し、"ユーザー(UPN)"に Planner から取得したユーザーID を指定してやればOKです。

そうすればメッセージの整形に取得したユーザーの表示名を使用することができます。

6. 期限が今日のタスクがあるか判定する

ここまでで、期限が条件に一致するタスクを通知するためのメッセージを作っているので、そのメッセージが空であれば「タスクが無いことを通知する」。そうでなければ「条件に一致したタスク情報一覧を通知する」ようにしています。

f:id:iyemon018:20200913173159p:plain

条件式は、具体的には以下のような式になっています。

empty(variables('task_list'))

task_listは「③期限であるタスク一覧を通知するためのメッセージ」が入っています。 この値が空である(empty(variables('task_list'))trueである)ということは「今日が期限のタスクが1つも無い」ということになります。 逆にこの値に何か入っている(empty(variables('task_list'))falseである)ということは「今日が期限のタスクが少なくとも1つはある」ということになります。

条件式がtrueの場合とfalseの場合とでそれぞれ通知したいメッセージを作ります。 タスクがない場合は通知しないという選択肢もありますが、フローが失敗している場合も通知はされないため、「フローが成功してかつ、今日が期限のタスクがない」ということを共有したかったので、タスクがないときも通知は実施しています。

このあたりはフローの目的やフローをどこに通知するか等によって決めておくべきでしょう。

7. チャットに新しいメッセージを追加する

ここは説明するまでもないですが、メッセージを特定のチャットルームに通知しています。 できれば、どのフローから通知されているかもメッセージに含めておくと良いでしょう。

iyemon018.hatenablog.com

期限を変えてみる

フローが作成できたので、他の期限を設定します。 フローを別名保存しておきましょう。

ここで大事なのが、期限ごとのフローで同じタスクを通知しないというところです。 制御するためにはa.通知すべきタスクかどうかを判断するの条件を変えてやればOKです。

その週が期限のタスク一覧を通知する

条件は単純です。「通知の翌日からその週の最終日まで」とすれば良いのです。 具体的には、次のとおりです。

  • <empty(items('タスク一覧を収集してメッセージを整形する')?['dueDateTime'])>次の値に等しい<false>(変更なし)
  • <値 達成率>次の値未満<100>(変更なし)
  • <ticks(items('タスク一覧を収集してメッセージを整形する')?['dueDateTime']) >次の値以上<ticks(addDays(utcNow(), 1))
  • <ticks(items('タスク一覧を収集してメッセージを整形する')?['dueDateTime'])>次の値未満<ticks(addDays(utcNow(), 6))

太字にした箇所を UTC 現在日時の1日後~6日後で期限の日付を比較しています。ここでticks(addDays(utcNow(), 0))としてしまうと、今日が期限のタスクも取得できてしまいます。

遅延しているタスク一覧を通知する

こちらは更に単純です。

  • <empty(items('タスク一覧を収集してメッセージを整形する')?['dueDateTime'])>次の値に等しい<false>(変更なし)
  • <値 達成率>次の値未満<100>(変更なし)
  • <ticks(items('タスク一覧を収集してメッセージを整形する')?['dueDateTime']) >次の値以下ticks(addDays(utcNow(), 0))

タスクの期限が UTC の現在日時よりも過去の日時かどうかを判断しているだけです。


Planner は通知機能が弱いので Power Automate で良い感じに通知してあげるとかなり使い勝手が良くなります。 もっと良い方法をご存じの方は是非コメントください!