Power Automate で Microsoft Teams の予約投稿を試した

経緯

定時後にふと「○○さんにメンションして連絡入れておきたい」ってなったらどうします?

「夜中でもなんでもメンションして送ってよし!相手は受信して反応しなければいいだけ」
とか、「定時後に連絡するな」とか、色々と意見は分かれると思いますが、
私は Microsoft Teams での投稿を予約したくて、Power Apps で作っていました

※PowerApps で作りかけていたやつ(返答ができてなかった)

別のことを調べている時に、Power Automate でやってのけている方がいたので、
それをインスパイヤーしながら、自分で使うように作ってみました

参考サイト:Microsoft Teams への予約投稿を Power Automate と Adaptive Cards でつくる

ハッキリ言って長いですが、作るとそんなに時間かからないです
(記事書くのは数日かかってますが…)

前準備

Microsoft 365 の環境はあるものとします

下記のような Teams を作成しました

Power Automate の構築

アダプティブカードでの投稿作成画面

  1. [ マイフロー ] -> [ + 新しいフロー ] -> [ インスタントクラウドフロー ] を選択

  2. フロー名を入力し、トリガーに Microsoft Teams の [選択したメッセージに対して ] を選択して、[ 作成 ] をクリック

  3. [ アダプティブカードの作成 ] をクリック

  4. [ New card ] -> [ Blank card ] をクリック

  5. TextBlock を AdaptiveCard にドラッグ・アンド・ドロップし、Text に説明を入力します

  6. Input.ChoiceSet を AdaptiveCard にドラッグ・アンド・ドロップし

    • Id に postType と入力
    • Placeholder を にする
    • Compact style の チェックを外す
    • Default value に reply と入力
    • Choices に下記の Label , Value を入力
      • 選択した投稿に返答する , reply
      • 同チャネルに新規投稿する , new
  7. TextBlock を AdaptiveCard にドラッグアンドロップし、Text に説明を入力します

  8. Input.Text を AdaptiveCard にドラッグ・アンド・ドロップし

    • Id に title と入力
    • Placeholder に タイトルを入力してください と入力
  9. TextBlock を AdaptiveCard にドラッグアンドロップし、Text に説明を入力します

  10. Input.Text を AdaptiveCard にドラッグ・アンド・ドロップし

    • Id に body と入力
    • Placeholder に 本文を入力してください と入力
    • Multi-line にチェックを入れる
  11. TextBlock を AdaptiveCard にドラッグアンドロップし、Text に説明を入力します

  12. Input.ChoiceSet を AdaptiveCard にドラッグ・アンド・ドロップし

    • Id に mention と入力
    • Placeholder に 通知する相手を選択してください と入力
    • Allow multi selection にチェックを入れる外す
    • Choices に下記の Label , Value を入力
      • テストユーザー 01 , <テストユーザー 01 のメールアドレス>
      • テストユーザー 02 , <テストユーザー 02 のメールアドレス>
      • テストユーザー 03 , <テストユーザー 03 のメールアドレス>
  13. TextBlock を AdaptiveCard にドラッグアンドロップし、Text に説明を入力します

  14. ColumnSet を AdaptiveCard にドラッグ・アンド・ドロップし、[ Add a column ] を 2 回クリック

  15. Input.Date を AdaptiveCard にドラッグ・アンド・ドロップし

    • Id に reserveDate と入力
  16. Input.Time を AdaptiveCard にドラッグ・アンド・ドロップし

    • Id に reserveTime と入力
  17. [ カードの保存 ] をクリック

以上がアダプティブカードでの登録画面でした

※アダプティブカードでの投稿作成画面での妥協点

  • 投稿タイプが変更のときだけタイトルの入力を表示したかった
  • 本文の入力はリッチテキストがよかったな…
  • 必須入力が設定できない
    • 恐らく AdaptiveCard Ver1.3 からしかできない
  • 通知先はチームに参加している人を動的にとりたい
    • とりあえずアドレス帳として Input.ChoiceSet に登録する方法で逃げた
  • 予約日時に動的に初期値を入れたかった
    • formatDateTime(convertTimeZone(utcNow(),'UTC','Tokyo Standard Time'),'yyyy-MM-dd') と入れて初期値がセットできるかと思ったんだけど…

もっといい方法ないかな…

変数の初期化

アダプティブカードで入力した値が、判定などで使えなかったりしたので、
必要に応じて変数に移す

  1. [ + 新しいステップ ] -> [ 組み込み ] タブ -> [ 変数 ] -> [ 変数を初期化する ] を選択し

    • ステップ名を 変数 Title を初期化する と入力
    • 名前に Title と入力
    • 種類は 文字列 を選択
    • 値は動的なコンテンツから title を選択
  2. 同様にして body, mention を変数に移す

  3. mention でチェックを入れたメールアドレスを <at></at> で囲んだ文字列としてセットするための変数を初期化する

    • ステップ名を 変数 PostMention を初期化する と入力
    • メモに メールアドレスを <at></at> で囲んで送信用の文字列とする と入力
    • 名前に PostMention と入力
    • 種類は 文字列 を選択
    • 初期値は空とする

変数の初期化フェーズはここまでとなります

通知先が設定されているときの処理

通知先が設定されているとき、各アドレスを <at>~</at> で囲む必要があります

変数 Mention に値が入っていたら、各アドレスを <at>~</at> で囲み、
変数 PostMention にセットします

※Input.ChoiceSet で複数選択されているとき、各値は半角カンマで区切られています

  1. [ + 新しいステップ ] -> [ 組み込み ] タブ -> [ コントロール ] -> [ 条件 ] を選択

    • ステップ名を Mention に値が入っているか確認 と入力
  2. 左辺の 値の選択 にカーソルを移し、表示される タブをクリック

    • empty() と入力
  3. empty() のカッコの中にカーソルを持ってきて、動的なコンテンツ タブをクリックし、変数 Mention をクリックして、 [ OK ] をクリック

  4. 右辺の 値の選択 にカーソルを移し、表示される タブをクリック、false と入力して [ OK ] をクリック

  5. はいの場合 の [ アクションの追加 ] -> [ 組み込み ] タブ -> [ 変数 ] -> [ 変数の設定 ] を選択し

    • ステップ名を PostMention にメンション用タグを設定 と入力
    • メモに Mention の各メールアドレスを <at></at> で囲んで PostMention に設定する と入力
    • 名前に PostMention を選択
    • 種類は 文字列 を選択
    • 値に <at></at><br> と入力
  6. 値の入力欄の <at></at> のタグ間にカーソルを移動し

    • タブをクリック
    • replace() と入力
    • カッコの中にカーソルを持ってきて、 ,',','</at> <at>' と入力する
      • 第一引数は空
      • 第二引数は ,
      • 第三引数を </at> <at>
  7. replace() のカッコ内の先頭部分(第一引数部分)にカーソルを持ってきて、動的なコンテンツ タブをクリックし、変数 Mention をクリックして、 [ OK ] をクリック

これで通知先にチェックが入れられているとき、変数 PostMention にメンション用のタグがセットされました

予約した時間まで処理を待機させる

アダプティブカードで設定した予約日時まで、処理を待機させます

  1. [ + 新しいステップ ] -> [ 組み込み ] タブ -> [ 日時 ] -> [ タイムゾーンの変換 ] を選択

    • 基準時間を動的なコンテンツから、reserveDatereserveTime を選択して、 間に半角スペース を入れる
    • 変換元のタイムゾーンは (UTC+09:00) 大阪、札幌、東京 を選択
    • 変換先のタイムゾーンは (UTC) 協定世界時 を選択
    • 書式設定文字列は カスタム値の入力 を選択して、 yyyy-MM-ddTHH:mm:ssZ と入力
  2. [ + 新しいステップ ] -> [ 組み込み ] タブ -> [ スケジュール ] -> [ 延期期限 ] を選択

    • タイムスタンプに動的コンテンツから、 変換後の時間 を選択

これで設定した時間まで待機するようになります

返信、または、新規投稿を行います

最後に投稿を行います

  1. [ + 新しいステップ ] -> [ 組み込み ] タブ -> [ コントロール ] -> [ 条件 ] を選択

    • ステップ名を 返信か新規投稿か判断 と入力
    • 左辺は動的なコンテンツから postType を選択
    • 右辺を reply と入力
  2. はいの場合 の [ アクションの追加 ] -> [ 標準 ] タブ -> [ Microsoft Teams ] -> [ メッセージの返信の投稿(V2) ] を選択し

    • チームは カスタム値の入力 を選択して、動的なコンテンツから チームID を選択
    • チャネルは カスタム値の入力 を選択して、動的なコンテンツから チャネルID を選択
    • メッセージは動的なコンテンツから メッセージID を選択
    • 返信は動的なコンテンツから PostMention を選択
  3. 返信に選択した PostMention の後ろにカーソルを持っていき

    • タブで replace() と入力
    • カッコの中にカーソルを持ってきて、動的なコンテンツから変数の Body を選択
    • 続けて ,decodeUriComponent('%0A'),'<br>' と入力
    • [ OK ] をクリック
  4. いいえの場合 の [ アクションの追加 ] -> [ 標準 ] タブ -> [ Microsoft Teams ] -> [ メッセージを投稿する(V3) ] を選択し、[ 詳細オプションを表示する ] をクリック

    • チームは カスタム値の入力 を選択して、動的なコンテンツから チームID を選択
    • チャネルは カスタム値の入力 を選択して、動的なコンテンツから チャネルID を選択
    • メッセージは動的なコンテンツから PostMention を選択
    • 34 と同じ手順で Body を追加
    • 件名は動的コンテンツから Title を選択

利用方法

スレッドの最初の投稿の右にある ・・・ をクリックし、[ その他の操作 ] にマウスカーソルを当てると、作成したフローが出てくるのでクリックする

アダプティブカードが表示されるので、適宜入力して [ Submit ] をクリックすると予約完了

今の所の問題点

  • 返答するときには、必ずスレッドの最初の投稿に返答する必要がある
    理由不明だが、親ではない投稿に返答するとエラーになる…

考察

Power Automate で Adaptive Cards を使って作ってみて、
PowerApps で作ると構築に手間は掛かりそうだけど、メリットはこういうのがありそう

  • Team に参加している人リストを動的に作れる (メンション用)
  • リッチテキストが使える