技術情報ブログ
Power Platform
2023.12.20

Power Automate で時間外の通知は行わない! やさしい通知のススメ

Power Automate で時間外の通知は行わない! やさしい通知のススメ
みやみや

こんにちは、みやみやです。

普段は「バス予報」という弊社サービスのシステム開発や運用周りのマネジメントをしているのですが、時々現実逃避して別の技術を触って遊んでいて、本記事も業務では使っていない技術を試してみた系の記事になります

さて、「共有メールボックスにメールが届いたら Teams で通知する」「Power Automate の承認フローが回ってきたら Teams で通知する」というような仕組みってよくあると思いますが、どんな時間でも通知しているフローって心づかいや優しさが足りないと思いませんか?w

色々と手法はあると思いますが、私が組んでみた方法を紹介しますね

 

基本的な設計

早速、雑ですが、当初こういうのを想像しました

Power Automate フローの設計
Power Automate フローの設計
  • イベントが発生した時

  • 就業時間内(平日の 9 時 ~ 18 時)か判定

  • 就業時間外時は、次の営業日の就業時間内になるまで待機

  • Teams に投稿

本記事を書きながらできたフローは下図の通りです

Power Automate フロー図
Power Automate フロー図
みやみや

早速作ってみましょう!

 

 

1. イベントの発生

イベントについて、「共有メールボックスにメールが届いた時」「SharePoint リストが追加された時」など何でもいいと思いますが、今回は便宜上、今回は手動フローにします

Power Automate ホームを開き、マイフロー+ 新しいフローインスタント クラウド フローを選択

Power Automateインスタント クラウド フローの作成

フロー名を入力、トリガーをフローを手動でトリガーするを選択し、[ 作成 ] をクリック

Power Automateフローを手動でトリガーするを作成

今回は検証しやすくするために、トリガーのボタンを下図のようにして、試行できるようにしました

Power Automat手動でフローをトリガーします

 

2. 変数の初期化処理など

Power Automate では、変数を初期化する必要があり、初期化の処理はまとめている方が見やすいです

変数の初期化は+ 新しいステップ組み込み変数変数を初期化するを選択することで追加することができます

ここでは 4 つの変数を定義・初期化します

 

2-1. イベント発生日時

本来は「メールが届いた時」のような時間を使いますが、それだと検証するために時間外労働をすることになるという、本末転倒になってしまうので、今回はフローの実行時に日時を入力するようにしています

値に入っている式は次のようになっています

concat(triggerBody()['date'], 'T', formatNumber(triggerBody()['number'], '00'), ':00:00')
Power Automatイベント発生日時

※注意事項

ここでは入力値を日本時間(JST)として扱っていますが、
例えばSharePoint などから日時を取得すると、協定世界時(UTC)となります!
UTC の値を使うときには、一度下記のようにしてJSTに変換してください

例. 手動でフローをトリガーした時間を使う時

convertFromUtc(triggerOutputs()['headers']['x-ms-user-timestamp'], 'Tokyo Standard Time','yyyy-MM-ddTHH:mm:ss')

 

2-2. Teams に投稿する日時

このあとの処理で Teams に投稿する日時を割り出し、それを保持する変数です

Power Automat Teamsに投稿する日時用変数(TeamsPostDatetime)を初期化する

 

2-3. ループカウント用変数

このあとの処理でループ処理があり、そのカウンター変数です

Power Automat ループカウント用変数(Count)を初期化する

 

2-4. 祝日用変数

一般的に祝日マスタと呼ばれるデータを配列で作っています

Power Automat 祝日用変数(Holiday)を初期化する

本格的にするのなら、別で祝日マスタリストなどをつくり、祝日の追加を各フローごとに行わないようにするなどの方法が考えられますね

ちなみに、今回はこのようなデータを用意しました

[
  "2023-01-01",
  "2023-01-02",
  "2023-01-03",
  "2023-02-11",
  "2023-02-23",
  "2023-03-21",
  "2023-04-29",
  "2023-05-03",
  "2023-05-04",
  "2023-05-05",
  "2023-07-17",
  "2023-08-11",
  "2023-09-18",
  "2023-09-23",
  "2023-10-09",
  "2023-11-03",
  "2023-11-23",
  "2023-12-29",
  "2023-12-30",
  "2023-12-31",
  "2024-01-01",
  "2024-01-02",
  "2024-01-03",
  "2024-01-08",
  "2024-02-11",
  "2024-02-12",
  "2024-02-23",
  "2024-03-20",
  "2024-04-29",
  "2024-05-03",
  "2024-05-04",
  "2024-05-05",
  "2024-05-06",
  "2024-07-15",
  "2024-08-11",
  "2024-08-12",
  "2024-09-16",
  "2024-09-22",
  "2024-09-23",
  "2024-10-14",
  "2024-11-03",
  "2024-11-04",
  "2024-11-23",
  "2024-12-29",
  "2024-12-30",
  "2024-12-31"
]

 

3. 判定処理

次は判定処理に入ります

 

3-1 イベント発生時間は 18 時を越えているか

イベントが発生した時間が 18 時を越えていたら、次の日から営業日確認を開始するので、
+ 新しいステップコントロール条件を選択します

Power Automat イベント発生時間は 18 時を越えているか

最初の条件式の左辺は下記のようになっています

int(formatDateTime(variables('EventDatetime'),'HH'))

説明ですが、イベント発生日時の時間の部分だけ取得して数値型に変換して、その時間が 18 時以上かどうかを判定して下記のように変数に値をセットしています

  • 18 時を越えていたらループカウントを1 からスタート

  • 18 時より前のときにはループカウントを0 からスタート

このあとの処理でループカウント分日付を進めて、営業日かどうかを判定していくので、18 時を越えたら 1 からスタートさせているということは、イベント発生日の翌日から判定をスタートさせていくということになります

 

3-2 営業日確認

営業日の確認は、ループをしながら日付を進めていき、土日、または、2-4. 祝日用変数 で用意した変数に日付が含まれていると、ループカウントを進めて次の日を確認するという方法です

最初にループ処理をDo untilを使って作ります

+ 新しいステップコントロールDo untilを選択します

Power Automat 営業日確認ループ

左辺の条件式は下記のようになっています

empty(variables('TeamsPostDatetime'))

投稿する日時を保持する変数TeamsPostDatetimeに値がセットされたら、ループを抜けるという記述です

また、念のためにループの制限回数を 60 から 14 に変更しています

 

続いて、+ 新しいステップコントロール条件を選択します

Power Automat 営業日確認ループ
  • 条件文の最初と 2 番目の左辺の式は下記のようになっています

    dayOfWeek(addDays(variables('EventDatetime'), variables('Count')))

    イベントが発生した日付にループカウント分の日数を足した日付の曜日を求めています こちらは日曜日を 0土曜日を 6として返ってきます

  • 条件文の最後の左辺の式は下記のようになっています

    contains(variables('Holiday'), formatDateTime(addDays(variables('EventDatetime'), variables('Count')), 'yyyy-MM-dd'))

    イベントが発生した日付にループカウント分の日数を足した日付が、祝日用変数(Holiday)の 値に一致するのがあるか確認しています(あればtrueが返ってきます)

    これで、日曜日ではなく , 土曜日ではなく , 祝日ではない という条件式になります

  • 条件を満たす時(はいの場合)は、当該日付をTeamsPostDatetimeにセットし、その式は下記のようになります

    formatDateTime(addDays(variables('EventDatetime'), variables('Count')), 'yyyy-MM-ddT09:00:00')

条件分のあとは、忘れずに、アクションの追加から 変数の値を増やす を追加して、ループカウンターを加算します

Power Automat ループカウント用変数をカウントアップする

これにより、条件を満たさなかった時は、TeamsPostDatetimeが空で、ループカウンターが 1 進むので、日付が 1 日進んでループが続くことになります

 

4. Teams への投稿

最後の Teams への投稿です

Power Automate でフローを組むとあっという間にできるのですが、ブログとして書くと長い道のりですねー

+ 新しいステップ組み込みスケジュール延期期限を選択します

Power Automat 延期期限

タイムスタンプには下記のように値をセットします

convertToUtc(variables('TeamsPostDatetime'), 'Tokyo Standard Time')

ここまで日本時間(JST)として計算してきたのですが、Power Automate では協定世界時(UTC)が使われるので、変換しています

最後に、+ 新しいステップMicrosoft Teamsチャットまたはチャネルでメッセージを投稿するを選択して、投稿者、投稿先、Team、Channel、Message を適宜設定して完成です

Power Automat 延期期限

 

検証

  • 検証 1

    • イベント発生: JST で 2023/10/06 (金) 09:00

    • 期待値: UTC で 2023/10/06 (金) 00:00 (JST で 2023/10/06 (金) 09:00)

    • 結果

      Power Automate で時間外の通知は行わない 検証1
  • 検証 2

    • イベント発生: JST で 2023/10/06 (金) 19:00

    • 期待値: UTC で 2023/10/10 (火) 00:00 (JST で 2023/10/10 (火) 09:00)

    • 結果

      Power Automate で時間外の通知は行わない 検証2
  • 検証 3

    • イベント発生: JST で 2023/10/07 (土) 09:00

    • 期待値: UTC で 2023/10/10 (火) 00:00 (JST で 2023/10/10 (火) 09:00)

    • 結果

      Power Automate で時間外の通知は行わない 検証3

想定通りの待機時間となることが判ります

 

考察

弊社では、仕事を楽にしたり、ミスを減らすために、Power Platform で改善している方が多いのですが、例えば私は、「共有メールボックスにメールが届いたら、Planner に登録、送信者から Teams のチャネルを振り分け、担当者にメンションをつけて投稿する」というフローがあり、そちらでも本記事に似た仕組みが動いています

●実行履歴例

Power Automate で時間外の通知は行わない 検証3
みやみや

人に優しい設計を心がけたいですねw

miyamiya

みやみや

ビジュアル系プログラマー、ビジュアル系 PM を自称して 20 年近くが経ちました

弊社 MaaS 製品全般で、開発・運用側のマネジメントをしながら、時々開発もしています

シェアする
記事カテゴリ
最新記事
2024.04.17

Power Apps・Power Automateの勉強方法(1)

2024.04.03

非エンジニア【(元)自治体職員】が半年間ローコード開発をしてみたら

2024.03.27

Power Automateのベストプラクティス・アンチパターン(5)【Apply to each×コンカレンシー×変数の設定はNG】

2024.03.20

Power Apps×Teams:Teams上からPower Appsを実行する方法

2024.03.13

Power Apps:SharePointリストと連携したカレンダーアプリを自作してみよう

モデル駆動型アプリPower AppsPower PlatformSharePointExcelPower AutomateC#attributevalidationローコードAngularAccessInfoPathMatTableAngular Materialデータ構造SortByColumns関数TypeScriptHTMLEF CoreマイグレーションFramework CoreAttribute directivesO/Rマッパーazure sql databaseCase式HTTP RequestCSSxUnit.Net Core 3.1VSCode.Net Core Test ExplorerDataverse for Teamsitem関数Google MapsMarker ClustererRANK()関数Dynamics 365 SalesMicrosoft TranslatorマーカークラスタリングライブラリtailwindcssマルチテナントドロップダウンメニューBreakpointObserverメディアクエリスマホPCレスポンシブ入門初心者中級者キャンバスアプリDatePickerDropdownviewビューアクセス制限承認リマインドSetForAllUpdateContextロードマップ技術It情報技術メッセージIDメールfirst()関数nest入れ子動的リストcollectionコレクション複数の添付ファイル承認フローformエクスポートインポートカスタマイズcomponentダイアログコンポーネントdialogTips新機能変数検索Microsoft 365グループセキュリティグループ送信元メールの送信差出人インスタントクラウドフロー自動化したクラウドフロー委任VBAエラーエクセルerror復元restorePower BI個人列ユーザー列SharePoint Onlineリスト非表示アプリ[市民開発者構築自動化したクラウド フローフローの種類インスタント クラウド フロースケジュール済みクラウド フローレスポンシブ レイアウトresponsive layoutデータ行の制限引き継ぎ退職所有者を変更異動LoopMicrosoftdesignJSONデザインtemplateテンプレート運用選択肢列参照列ChatGPTOpenAIオープンAIチャットGPTgalleryギャラリースクロールコンテナショートカットキーshortcut keyconcat関数文字制限フロー実行開発環境環境本番環境ライセンス環境構築手順pipelineCI/CDパイプラインDevOpsMicrosoft 365簡易在庫管理時間外通知ファイルフィルター クエリドキュメント ライブラリfilter querysortソートmultiple item複数項目シェアポイント便利機能カレンダーCalendarTeamsローコード開発非エンジニア体験談勉強内製化
PageTop
ページトップに戻る