なぜこれをつくったか
会議の予定を入っても気づかない事ってありませんか? 私はイベント開始前の通知で「ええーっ そんな会議いつの間にはいってたんだい!?」と慌てるケースが稀に起きます。 そこでExchange Online 予定表でイベントに招待されたらTeamsチャットで通知するようにPower Automate クラウドフローで対策をしてみました。
前提条件
Microsoft365 の Exchange Online, Teams, PowerAutomate が利用できるライセンス
Microsoft365 E3 と E5の環境で動作確認しています。
実行結果イメージ
Teams チャットで通知
[詳細]ボタンでイベント詳細
フロー全体
フロー詳細
トリガー
Office 365 Outlook - イベントが追加、更新、または削除されたとき (V3))
トリガーの設定
トリガーの条件3つがポイントです。
- @equals(triggerOutputs()?['body/ActionType'],'added')
今回のフローは新規イベントのみを取り扱います(割り切り その1)。 新規イベントは(ActionType='added')で識別できます。 - @not(equals(triggerOutputs()?['body/organizer'],'自分のメールアドレス'))
自分で登録したイベントは通知は必要ないので除外します。 - @equals(triggerOutputs()?['body/recurrence'],'none')
繰り返しイベントを除外しています。繰り返しイベントが追加された際には繰り返しの数だけトリガーが発火する動作になります。ひたすらチャットに通知が飛ぶことは望ましくないので、思い切ってバッサリ諦めています。(割り切りその2)
アダプティブカードで扱う画像
ちょっと見た目を良くするために画像を使いたくてこちらの記事を参考にさせていただきました。
@kura_yu さん 【PowerAutomate】AdaptiveCardでユーザーのプロフィール画像を送信しよう!
日付の処理
データ操作 - 作成 アクション 終日のイベントかそうでないかで日時の表現を変えています。
if ( bool(triggerOutputs()?['body/isAllDay']), concat( convertFromUtc(concat(triggerOutputs()?['body/start'], 'Z'), 'Tokyo Standard Time', 'yyyy-MM-dd'), '@終日' ) , concat( convertFromUtc(concat(triggerOutputs()?['body/start'], 'Z'), 'Tokyo Standard Time', 'yyyy-MM-dd hh:mm'), ' ~ ', convertFromUtc(concat(triggerOutputs()?['body/end'], 'Z'), 'Tokyo Standard Time', 'yyyy-MM-dd hh:mm') ) )
Teams チャット でアダプティブカードを送信
Microsoft Teams - チャットやチャネルにアダプティブ カードを投稿する
Adaptive Card Designer のサンプルほぼそのまま。ちょっと調整しただけのものです。
{ "type": "AdaptiveCard", "body": [ { "type": "TextBlock", "size": "Medium", "weight": "Bolder", "text": "イベントに招待されました" }, { "type": "ColumnSet", "columns": [ { "type": "Column", "width": "auto", "items": [ { "type": "Image", "style": "Person", "url": "@{variables('ImageUrl')}", "size": "Medium" } ] }, { "type": "Column", "width": "stretch", "items": [ { "type": "TextBlock", "weight": "Bolder", "text": "@{triggerOutputs()?['body/subject']}", "wrap": true } ] } ] }, { "type": "ColumnSet", "columns": [ { "type": "Column", "width": "auto", "items": [ { "type": "TextBlock", "text": "日時", "wrap": true }, { "type": "TextBlock", "text": "場所", "wrap": true }, { "type": "TextBlock", "text": "開催者", "wrap": true }, { "type": "TextBlock", "text": "繰返し", "wrap": true } ] }, { "type": "Column", "width": "stretch", "items": [ { "type": "TextBlock", "text": "@{outputs('作成-日付テキスト')}", "wrap": true }, { "type": "TextBlock", "text": "@{triggerOutputs()?['body/location']} ", "wrap": true }, { "type": "TextBlock", "text": "@{triggerOutputs()?['body/organizer']} ", "wrap": true }, { "type": "TextBlock", "text": "@{triggerOutputs()?['body/recurrence']} ", "wrap": true } ] } ], "separator": true, "style": "accent" } ], "actions": [ { "type": "Action.OpenUrl", "title": "詳細", "url": "@{triggerOutputs()?['body/webLink']}" } ], "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", "version": "1.4" }
制限事項(割り切り)
- イベント作成後に出席者に追加された場合には対応していません
その場合はすでに作成されているイベントに自分が追加された形になるので発火するトリガーはActionType:update
となり、ActionType:added
のトリガー発火がありません。 イベントの更新なのか、自分が追加で招待されたイベントなのかを判定するには、別途イベント管理マスタを用意する等の煩雑な手法しか思いつかなかったので除外しています。ActionType:update
は闇が深い...Exchange 予定表 自体の仕様の闇が深い... - 繰り返しイベントには対応していません
トリガー設定の箇所に記載した理由によりあえて対応していません。
今後改良したいところ
- イベント削除の通知
- 日時・場所など特定の条件が更新された場合だけ通知
- 繰り返しのイベントの初回だけ通知・・・できたらいいな
最後に
気ままに勉強会 #49 の やま (Yama) さんのお話にインスパイアされて完成に辿り着きました。 やま (Yama) さんと運営の皆さんに感謝です!!