カテゴリー別アーカイブ: Office 365

[Power Automate] Graphを使って(IDではなく)名前でグループを取得する

Power Automate の中でMicrosoft Graph を使って名前をキーにグループを取得するやり方を紹介します。

はじめに:なぜこれをやりたいのか

Office365 グループ(Teams のチーム) の場合、その名前でグループを取得(検索)するアクションが用意されています。

[グループ メンバーの一覧表示]アクション。「グループID」とあるが実際には自身が所有している(オーナーになっている) グループが選択できるので、IDを知っている必要はない

しかしこれが従来のセキュリティ グループの場合、名前で検索することができません
(Azure AD のコネクタに、グループを取得するアクションはあるのですが、IDを指定しなければなりません)

Azure AD の[グループ の取得] アクション(画像は英語版)。グループ名が指定できない

そこで代わりにMicrosoft Graph API を使用すると、グループ名をキーにして取得することができます。

事前準備:Azure ADへのアプリケーション登録とアクセス許可の設定

実際にMicrosoft Graph API を使用してグループを取得する前に、事前準備が必要です。
こちらのドキュメントを参考に実施しておいてください。
(事前と書きましたが実際にはフローを実行する前に済ませておけばOKです)

Azure AD アプリ登録を作成する

【補足】
上記ページの後半、「[ API アクセス許可の要求] ブレードで、・・・」で始まる記載の個所は今回以下のようにしています。
・ [委任されたアクセス許可] → [アプリケーションの許可]
・ [すべてのグループの読み取りと書き込み] アクセス許可 → [Group.Read.All]
※今回は取得なので、必要最低限の権限という意味で読み取りのみとしています

また、ページ中段、「MS Graph バッチアプリブレードで、・・・」で始まる記載の個所で説明されているアプリケーション (クライアント) IDと、
ページ下段、「MS Graph バッチアプリブレードの [管理] セクションで、・・・」で始まる記載の個所で説明されている新しいキーの値をコピーしておきます(後で使います)

グループを取得するためのHTTP アクションの追加

準備ができたら、グループを取得するためにMicrosoft Graph API を呼び出すアクションを追加します。”HTTP” と検索して その名の通りHTTPというアクションを追加します。

【重要】
下の画像にもあるように、このHTTPアクションはプレミアム コネクタに分類されていて、利用にはスタンドアロンの Power Automate ライセンスが必要です。Office365 のプラン(E1, E3等)に含まれるライセンスでは利用できませんので、ご注意ください。
Power Apps と Power Automate のライセンスに関するよくあるご質問 – Power Platform Admin center | Microsoft Docs

Microsoft Graph API を呼び出すには、HTTP アクションを追加する

追加したHTTPアクション内に、グループを取得するGraph API を呼び出す設定を入れていきます。

グループを取得するGraph API を呼び出すためのHTTPアクションの設定。赤枠が今回必要な設定
  • Method: [GET] を選択
  • URI: https://graph.microsoft.com/v1.0/groups?$filter=startswith(displayName,'<取得したいグループの表示名>') ※名前をシングルクオーテーションで挟むのを忘れずに
  • Headers: 以下のように入力
    • Enter key と表示されているところに Content-type
    • Enter value と表示されているところに application/json
  • Authentication: [Active Directory OAuth] を選択
  • Tenant: 取得したいグループが登録されているOffice 365 (Azure AD) のテナント名(xxxxx.onmicrosoft.com)
  • Audience: https://graph.microsoft.com
  • Client ID: 上記の [事前準備] でコピーしておいたアプリケーション (クライアント) IDを貼り付けます
  • Credential Type: [Secret] を選択
  • Secret: 上記の [事前準備] でコピーしておいたキー値を貼り付けます

【補足】上記の例では、URI は文字通り”startswith” (前方一致) で検索するようフィルターの指定をしています。この場合一致しているものが複数あれば結果が複数になりますので、完全一致にしたい場合は “eq” とします。このあたりのフィルターのパターンについては以下が参考になります。

クエリ パラメーターを使用して応答をカスタマイズする – Microsoft Graph | Microsoft Docs

ここまでできたらフローを保存して、実際にグループが取得できるかテストしてみましょう。Status code が200になっていれば、期待通りにグループが取得できているはずです。

HTTPアクションの実行結果。Status code が200 になっていて、Body に指定したグループの情報が表示されていれば成功

取得できていたら、Body の内容を丸ごとコピーしておきます。この後で取得結果を処理する際に使います。

取得したグループの情報を次の処理で利用する

これで名前をキーにしてグループを取得(検索)することができました。最後に、この取得結果を受け取ってオブジェクトIDを知る方法を紹介します。

[JSONの変換 (Parse JSON)] というアクションを使用すると、HTTPアクションの結果を受け取ることができます。
(アクションの追加でjson と入力すると見つかります)

JSONの変換 (Parse JSON)アクションを使用してHTTPアクションの結果を受け取る

アクションを追加したら、コンテンツ(Content) に先ほど取得したHTTPアクションの結果(Body)をセットします。

JSONの変換 (Parse JSON)アクションのコンテンツにHTTPアクションの結果(Body)を指定

次のスキーマ(Schema) ですが、[Generate from sample] ボタンを押して、 先ほどコピーしておいたテスト結果のBody を貼り付けます。

[Insert a sample JSON Payload] というポップアップが表示されたら、先ほどコピーしたテスト結果のBody を貼り付ける

するとスキーマ(Schema) の欄に、テスト結果のBody から抽出されたスキーマ定義がセットされます。

テスト結果のBody をサンプルとして貼り付けることで、JSONの変換を行うためのスキーマ情報を抽出できる

これで取得したグループ情報を取り出す準備ができました。あとは後続のアクションで使いたいグループ情報を参照します。

JSONの変換 (Parse JSON)アクションを使うことで取得したグループの情報を取り出せる。画像はグループのIDを変数にセットする例

この記事の冒頭で書いたように、Power Automate でグループに対して何か処理を行いたい時に、このグループIDを指定しなければならないケースがありますが
このテクニックを使うことで、グループ名さえ分かればIDが取り出せるので、対応できるようになります。

[Power Automate] 月末(の最終営業日)にリマインダーを送る

前回の記事で、Power Automate で月末の日付を取得するTips を紹介しました。
今回はこれを応用して、月末の最終営業日(平日)にリマインダーを送るための方法を紹介します。

ロジック

Power Automate でどうやるか?の前に、まず今回やりたいことを実現するには どうしたらよいかを整理しました。Power Automate でどうやるの?を知りたいという方は、飛ばして[実装]の方を見てください。
私はこんな風に日本語で書きだしてみました。

  • 毎月26日になったら(これがトリガー。フローの開始・起点)
  • 月末の日付を知る(月によって28,29,30,31 のいずれか)
  • その日の曜日を取得
    • 月末が週末なら金曜にリマインドを出したいので、
      • 土曜→前日にリマインド
      • 日曜→2日前にリマインド
        • 28の月→26(そのままリマインドを出す)
        • 29の月→27(1日待ってからリマインドを出す)
        • 30の月→28(2日待機)
        • 31の月→29(3日待機)

といった感じです。これを何月に実行しても同じように月末最終営業日(平日)に動くようにするにはどうしたらいいかを考えていきました。

はじめに26日を起点としているのは、1年で最も短い月である2月を考慮すると2/28が日曜だった場合2/26の金曜にリマインドを出すことになるからです。
なのでフロー自体は毎月26日に開始するようにしておき、実行する月に応じて その月の日数や曜日から最終営業日(平日) を取得します。

月末が週末の場合、直前の金曜にリマインドするには
・ 土曜なら、-1日
・ 日曜なら、-2日
すればいいので、例えば
・4/30 が土曜 -> 4/29 (4/30-1日) の金曜にリマインド = 4/26 を起点とすると+3日
・5/31が土曜 -> 5/30 (5/31-1日)の金曜にリマインド = 5/26 を起点とすると+4日
になりますね。

これを汎用的に、必ずその月の最終営業日(平日)に実行されるようにするには
フローの開始日である26日から、
[その月の日数(月末の日付)] - 26 - 1(月末が土曜の場合) or 2(月末が日曜の場合)
日後を取得すれば良いことになります。

上記の例でいえば、
4/30 (土曜) :[30] – 26 – 1 = 3 なので、26 の3日後、29日(金) となります。
5/31 (土曜) :[31] – 26 – 1 = 4 なので、26 の4日後、30日(金) となります。
もし6/30 が日曜だった場合は、
[30] – 26 – 2 = 2 なので、26の2日後、28日(金) になりますね。

これが分かれば、あとはこれをPower Automate で実装していけば良いわけです。

実装

毎月26日に実行する(トリガー、フローの開始・起点)

まず前述の、
「毎月26日になったら(トリガー。フローの開始・起点)」
ですが、以下のようにします。

毎月26日にフローを実行するための条件

「xx日に実行する」というのを指定する箇所がありませんが、代わりに[開始時刻]で指定した日付・時刻で毎月実行されるようです。
※このあたりの指定の仕方は以下を参考にしてください。
Azure Logic Apps での定期的に実行されるタスクとワークフローのスケジュール設定 | Microsoft Docs

時刻は多少ずれることもあるようですし、後続の処理に時間がかかる可能性も考慮すると、「9:00(もしくはそれより前)にリマインダーを送っておきたい」といった場合は上記の時刻の部分は9:00より前にセットしておくのが無難かもしれません。
※試した時は8:59に実行開始されていました

月末の日付を知る

続いて、月末の日付(その月の日数)を取得します。

月末の日付(その月の日数)を取得するための関数
月末の日付(その月の日数)を取得するための関数


冒頭で紹介した前回記事の通り、実際に[値]のところには以下の関数を入れています。

addDays(startOfMonth(addDays(startOfMonth(convertFromUtc(utcNow(), 'Tokyo Standard Time')), 32)), -1)

結果、変数 targetDate にはこのような値が入ります。

2020-04-30T00:00:00.0000000

4月に実行したので、ちゃんと その月の月末、30日になっていますね。

その月の最終営業日(平日)を知る

次に、その月の最終営業日(平日)を取得します。
これは「実行日である26日から、何日後にリマインダーを送るべきか」を計算するためです。
まずsub 関数を使って、いま取得した月末の日付(その月の日数) から現在の日付(26)を引きます。

月末の日付から現在の日付を引く
月末の日付から現在の日付を引く

sub(dayOfMonth(variables('targetDate')),dayOfMonth(convertFromUtc(utcNow(),'Tokyo Standard Time')))

月末の日付(その月の日数) が dayOfMonth(variables(‘targetDate’))
現在の日付が dayOfMonth(convertFromUtc(utcNow(),’Tokyo Standard Time’))
です。
現在の日付は実行日が26日固定であれば、このように関数で表す必要はなく26と書いても同じ動きになりますが、テストや例外的に手動で実行したい場合など26日以外の日に動かす可能性も考慮すると、こうしておいた方が無難です(その都度書き換える必要がないので)

結果、変数 days2wait には4月であれば 30 – 26 = 4 が入ります。
(もし23日に実行すれば、 30 – 23 = 7 になります)

このままでは月末が週末の場合、その月の最終営業日(平日)になっていませんので
直前の金曜にリマインドするために この数字から
土曜なら -1日
日曜なら -2日
します。

まず曜日を取得します。以下のようにします。

その日の曜日を知るには、dayOfWeek 関数を使う

これによって変数 targetDate (例では2020-04-30) の曜日が youbi という変数(安直・・・) に入ります。ただしここでの曜日は日曜日は 0、月曜日は 1、といったように整数となります。

続いて曜日の判定。以下のようにします。

スイッチを使って曜日を判定する
スイッチを使って曜日を判定する

スイッチというアクションを使うと、複数の結果が想定されるケースで それぞれの結果に応じた処理を行うことができます。今回は月末が土曜か日曜かを知りたかったので、先ほど取得したyoubi という変数の値を元に処理を分けています。

「日曜日」「土曜日」と書いてあるのは見た目に分かりやすくするためで、実際には youbi が 「0 (日曜) か 6 (土曜) か それ以外か」で分岐するようにしています。

また、日曜・土曜の場合に行っているのは以下の [変数の値を減らす]というアクションで、指定した数を元の変数から減らします(そのままですね)。

[変数の値を減らす] アクションを使うと、指定した数を元の変数から減らすことができる

金曜にリマインドする、という目的のため、元の変数 days2wait からそれぞれ-2 (日曜), -1 (土曜) しているわけです。
※[変数の設定] アクションでsub 関数で引き算しても同じ結果は得られますが、整数型の変数であれば これを使った方が関数を書かなくて済むのでラクですね

これで、その月の最終営業日(平日)を知ることができました。その日にリマインダーを送れるよう、求めた日数(days2wait の値) まで待機します。

例えば4/26 に実行して、30日が日曜だった場合には 28日の金曜に送りたいので
26日からみて (30 – 26 – 2 = ) 2日待ってから送ることになります。

待機するには以下のようにします。

[遅延]アクションを使うと、指定した期間フローを待機(一時停止)させることができる

※私もよく忘れてしまいますが、このアクションを追加する時は「遅延」と検索すると出てきます。上図では[待ち時間] となっていますが「待機」や「待ち」では見つからないのでご注意を・・・

[遅延]アクションの検索

リマインダーを送る

ここまで来れば後はリマインダーを送るだけです。今回は「その月の最終営業日(平日)を知る」ための手順を紹介したかったので、具体的なリマインダーの送り方については詳しく触れません。メールなりTeams のチャネルに投稿するなり、好きな方法でリマインダーを送れます。

ちなみにTeams で、(チャネルではなく) 複数の人に個別かつ一斉にAdaptive Card を送付する方法については、Hiroさんの記事が大変参考になりますので、ぜひ見てみてください。
PowerApps365/健康状況報告フロー.pdf at master · mofumofu-dance/PowerApps365 · GitHub

補足として、Teams でチームのメンバー宛に送付するには
Office 365 グループの [グループ メンバーの一覧表示] というアクションを使います。
(2020.4時点ではTeams 関連のアクションにはメンバーの取得・表示アクションが無いようです)

[グループ メンバーの一覧表示] アクションで自分が所有するチームのメンバーを取得できる
[グループ メンバーの一覧表示] アクションでTeams のメンバーを取得できる

ただし、このアクションで指定できるグループ(Teams のチーム) は自分が所有者になっているチームだけのようです。
(チャネルへの投稿であれば自分がメンバーになっているチームも指定できます)

また、取得するメンバーの数は既定で100となっていますので、メンバーが100人以上いる場合は明示的に指定するのを忘れないようにしましょう。

取得するメンバーの数は既定で100

もう1点、Teams のAdaptive Card などを使ってメンバーから何かしらのリアクションを得る場合は、並列処理(同時実行)数の指定も忘れないようにしてください。
これを入れておかないと、順次実行になり 一人目が回答しないと次の人にリマインダーが飛ばなくなるので、一斉送信になりません。

リマインダーを受け取った人からのリアクションを受ける場合、[Apply to each] の設定メニューから並列処理数を指定する

ただしこの並列処理の数はMAX50なので、メンバーが50人以上いる場合は1~50人目の誰かがリアクションしないと51人目以降の人には送られないことになります。
スルーされる(リアクションが得られない) ことも想定するなら別の処理を検討した方が良いでしょう。


[Power Automate] その月の日数を知る

2月は28日(今年はうるう年なので29日)、3月は31日、4月は30日、、、といったように

「その月が何日まであるのか」を知りたくなって調べていたら

Power Automate Community の投稿で、一発で取得する関数を教えてくれている人がいたので共有だけ。英語なので日本語で検索してる人向けに・・・

Solved: Re: Scheduled flow to check for last day of the mo… – Power Platform Community

今日の日付に32を足す→今日が何日でも翌月の日付になる

→翌月の月初(1日)から1日引く→今月の月末の日付になる

というロジック。賢いわ~(笑)

ちなみに addDays 関数の戻り値(結果) はタイムスタンプ型
(例:”2018-03-25T00:00:0000000Z”)
なので、その月の日数(月末の日付)だけ欲しい場合は

dayOfMonth(addDays(…))

のようにdayOfMonth 関数で挟んであげれば取れます。

addDays や dayOfMonth 関数の使い方やサンプルはこちらに。

式関数のリァレンス ガイド | Microsoft Docs

どんな結果が返ってくるかも載っているので、どれを使えば自分がやりたいことに一番近いか、判断しやすいです。