コルネの進捗や備忘録が記されたなにか

進捗や成果物や備忘録てきななにかを雑に更新していきます。

Plannerの内容をPower Automateで通知する


スポンサードリンク

はじめに

私のマシュマロにて以下のような質問をいただいたので今回はこちらの回答 + α について纏めたいと思います。

f:id:koruneko:20220227153013p:plain

関連記事

私が以前書いた記事で「Power Automate でPlanner の情報を取得する」というものがあります。

koruneko.hatenablog.com

この記事では

  • タスクの内容
  • タスクのメモ
  • タスクのコメント

を取得する方法について記載されています。
今回の記事ではそこまで掘り下げては記載しないので、気になる方は上記記事をご覧になってください。

フローを作成する

スケジュールを設定する

質問者さんは、「毎日9時に実行」という設定はできているようですが、こちらの設定方法も記載しておきます。

「毎日9時に実行」なので「スケジュール」コネクタをトリガーに設定します。
また、フローを実行したいのは平日かな?と思いましたので、月~金のみ実行するようにします。

上記を設定すると以下のようになります。

f:id:koruneko:20220227155016p:plain

プレビューでいつ実行されるのか記載してくれているのでわかりやすいですね。

Plannerの情報を取得する

続いてPlannerのタスクを一覧で取得します。

ちなみに今回取得するプランには以下のようなタスクが登録されています。

f:id:koruneko:20220227155424p:plain

ここに登録されているタスクを取得するにはPlannerコネクタの「タスクを一覧表示します」を使用します。

取得したい対象の対象のプランを選択するだけです。

f:id:koruneko:20220227155612p:plain

このアクションにより以下のような情報が取得できます。

key 説明
@@odata.etag 識別子
planId 対象のタスクが登録されているプランのID
bucketId 対象のタスクが登録されているバケットのID
title 対象のタスクのタイトル
orderHint リストビューでこのタイプの項目を順番に並べるためのヒント(参考)
assigneePriority リストビューでこのタイプの項目を順番に並べるためのヒント(参考)
percentComplete タスクの完了の割合(100に設定すると完成とみなされる)
startDateTime タスクの開始日時 ※UTC
createdDateTime タスクが作成された日時 ※UTC
dueDateTime タスクの期限日時 ※UTC
hasDescription タスクに詳細が設定されている場合はtrueそうでない場合はfalse
previewType タスクに表示されるプレビューの種類
使用可能な値: automatic, noPreview checklist, description, reference
referenceCount タスクに存在している外部参照の数
checklistItemCount タスクに存在するチェックリストの数
activeChecklistItemCount チェックリストの項目数
値がfalseである場合は、不完全な項目が存在している
id 対象のタスクのID
createdBy 対象のタスクを作成したユーザのID
appliedCategories 対象のタスクが適用されているカテゴリ(詳細は「適用されるカテゴリ参照」)
assignments タスクが割り当てられている担当者
_assignments ????

参考文献
Planner - Connectors | Microsoft Docs
plannerTask のリソースの種類 - Microsoft Graph v1.0 | Microsoft Docs

_assignmentsがいまいちわからなかった。
なんだこいつ

これでタスク一覧が取得できました。
だいたい欲しい情報はこれで取得できたかと思います。

より細かい情報が欲しい場合は、「タスクの詳細を取得する」アクションで取得を行ってください。
使い方については冒頭で紹介した記事を参照してください。

条件を設定する

Apply to eachを使用するやり方

まず最初に紹介するのは、おそらく一番簡単な方法で「条件」アクションを使用する方法です。

こちらはプログラムが少しわかる方向けに説明するとif分岐ですね。

条件にて条件式を記載して、はい(true)の場合 / いいえ(false)の場合の処理をそれぞれ記載します。

今回は、

  • 期限
  • タイトル

の2つを条件に設定します。
また、質問者さんの書き方からしてこれら2つの条件すべてに一致した場合~だと思いますので、条件はAndとします。

実際に設定すると以下のようになります。

f:id:koruneko:20220227173341p:plain

Apply to eachは「タスクを一覧表示します」の値を設定した際に自動で作成されます。
これは「タスクを一覧表示します」で取得した結果がアレイ型であるからです。

Apply to eachはループ処理だと思ってください。

期日の条件は1段目で、条件は適当に期日が本日以前だった場合。としています。
その際の式は以下です。

左辺

formatDateTime(addHours(items('Apply_to_each')?['dueDateTime'], 9) 'yyyy/MM/dd')

右辺

formatDateTime(addHours(utcNow(), 9) 'yyyy/MM/dd')

リファレンスにも合った通り、時間はUTCでとれますのでJSTに変換して計算しています。
また、みたいのは日にちのみで時間はみなくともよいので、formatDateTime 関数で時間のフォーマットをしています。

その他の時間フォーマットはこちらをご参照ください。
koruneko.hatenablog.com

タイトルの条件は2段目で、右辺の文字に一致する場合。としています。

もし部分一致にしたい場合はindexOf 関数を利用します。

この関数は第一引数に設定した特定の文字列内に、第二引数で設定した特定の文字列が何番目の文字列で登場するか?を返します。
このカウントは0から始まり、また見つからなかった場合は-1を返します。

なので以下のように記載します。

左辺

indexOf(items('Apply_to_each')?['title'], 'todo')

条件

次の値より大きい

右辺

-1

なおindexOf 関数は大文字小文字を区別しないので注意してください。

Apply to eachを使用しないやり方

次にApply to eachを(極力)使用しないやり方です。
私はこちらを推奨し、またApply to eachを使用しないでいいやり方がある場合は極力そちらを推奨します。(もちろんメンバのレベルに合わせた運用にすることも大事です。)

なぜわざわざApply to eachを使用しないことを推奨するかというと、性能の問題です。
詳しくはHiroさんのこちらの記事が参考になると思います。

mofumofupower.hatenablog.com

また、極力と記載したのは後続処理でどうしても使わなくてはならない場面が出てくるからです。

さて、Apply to eachを使わないやり方ですが、これには「アレイのフィルター処理」を利用します。

翻訳がいまいちいけてないですが「差出人」には処理を行う配列を設定します。
今回ですと「タスクを一覧表示します」で得られた結果ですね。

差出人

@outputs('タスクを一覧表示します')?['body/value']

余談ですが、この「差出人」は英語ですと「From」です。

次にフィルタ条件を2段目に記載するわけですが、ここで先ほどと同じ条件で結果をフィルタするには大きく2パターン存在します。

1つ目は無理やりこの関数バーに書く方法です。
デフォルトの基本モードでは、複雑な式を記載することができないので、「詳細モードで編集」で式を記載します。

先ほどの条件に記載した式たちを1つの式に纏めると以下のようになります。

@and(
   equals(item()?['title'], 'ToDo'), 
   lessOrEquals(addHours(formatDateTime(item()?['dueDateTime'], 9) 'yyyy/MM/dd'), formatDateTime(addHours(utcNow(), 9), 'yyyy/MM/dd'))
)

この式を設定した状態で基本モードに戻すことはできません。

f:id:koruneko:20220227233555p:plain

また、このやり方ですと式を記載している途中にオートコンプリートも表示されませんし(作成難易度が高い)、設定されている式を確認するのがちょっと見ずらいので運用面であまりよくありません。

ではどうするか?というと「アレイのフィルター処理」を2つに分けます。

具体的には以下のようにします。

f:id:koruneko:20220227235252p:plain

このようにそれぞれのフィルタ条件ごとにアクションを追加します。

「アレイのフィルター処理(期日のフィルタ)」では「アレイのフィルター処理(タスク名のフィルタ)」で得られた結果を設定しています。

差出人

@body('アレイのフィルター処理(タスク名のフィルタ)')

フィルタ条件の箇所に記載している式は「条件」で設定した式とほぼ同じ(items('Apply_to_each')item()になっている)ぐらいですので、説明は割愛します。

これでフィルタの条件が整いました。

いったんこの記事では一応質問者さんが知りたかった?タイトルと期日でのフィルタができるようになったのでこれで一区切りにします。

おわりに

これで一区切りにする。
とは言いましたが、フローとしてはまだ完成していないので、また続きを書いていきたいと思います。

質問者さんの文面では、「特定の担当者に」と記載されているので固定のユーザ(マネージャー?)の可能性もありますが、せっかくですのでタスクに割り当てられたユーザに対してメールを送るようにしたいと思っています。

タスクに割り当てられたユーザは"assignments"に設定されていました。
ただ、取得結果をみるに、

{
  "XXX-XXX-XXXX": {
    "@odata.type": "#microsoft.graph.plannerAssignment",
    "assignedDateTime": "2022-02-27T03:46:06.6898942Z",
    "orderHint": "",
    "assignedBy": {
      "user": {
        "displayName": null,
        "id": ""
      }
    }
  },
  "YYY-YYY-YYYY": {
    "@odata.type": "#microsoft.graph.plannerAssignment",
    "assignedDateTime": "2022-02-27T15:31:41.0967091Z",
    "orderHint": "",
    "assignedBy": {
      "user": {
        "displayName": null,
        "id": ""
      }
    }
  }
}

のように
キー値 = ID
で記載されているんですよね。。。
くそですね

これどうやって取得すればいいんだ。。。 またなにか良い案思いついたら記事にします。

ちなみに今後の説明では最後に説明した、アレイのフィルタを2つ使うやり方で実施していきます。


スポンサードリンク