Power AutomateのTeams投稿でAdaptive Cardを使ってみた

MicrosoftのOutlookやTeamsでは、「Adaptive Card」と呼ばれるテンプレートな仕組みが用意されており、システムからの通知などで通常では投稿できない「キレイなカード形式の情報」を投稿する事が可能です。

ただ単純にキレイなカード形式で配信するというだけでなく、結構奥が深い。以前もGoogle Apps ScriptでTeams投稿するエントリーで利用していますが、今回はPower Automateでの活用をまとめてみたいと思います。

Google Apps ScriptとMicrosoft Graph APIの連携 – Teams投稿編【GAS】

今回使用するサービス

Adaptive CardはJSONな形式でテンプレートが構築されていますが、Designerを利用する事で大まかな外観を作ることができ、また予め用意されてるテンプレートを基に作成する事が可能となっているので、初心者であっても取り組みやすくなっています。

Power Automateでの使い方

Teamsで利用する

これまで、Power AutomateにてTeamsに通知を投稿する場合、「チャットまたはチャンネルでメッセージを投稿する」を選んでフローを作成していました。しかしこれは人間が手打ちで投稿するものと変わらず、また基本的に文章なのでレイアウトの自由もないため、デザイン的には少々不格好な投稿になってしまいます。今回は、「チャットやチャンネルにアダプティブカードを投稿する」を選んで投稿することになります。

  1. 予め、投稿する内容の基になるデータ(Formsからのデータや、Excel Onlineのデータ等)をフローで用意しておく。今回はBoxのWebhook v2を受け取って作成しています(インスタントクラウドフロー
  2. 新しいステップをクリックする
  3. teamsと検索窓に入力し、「チャットまたはチャンネルでメッセージを投稿する」を選択する
  4. 投稿者、投稿先、チーム名、チャンネル名を選択し、件名を入力する
  5. 次項のDesignerでカードを作成するの作業をして、「アダプティブカード」の欄に入力する

次項でDesignerで作ったJSONを貼り付けたら、1.のデータ項目をJSONの各項目に差し込んで体裁を整えて完成となりますので、行ったり来たりをする必要があります。

図:フローの全体図

Boxファイル監視をPower AutomateでExcelに書込み – Webhook v2編

Designerでカードを作成する

いきなり、JSON形式でゴリゴリ作るというのは面倒な上に現実的ではないので、Adaptive Card Desingerを使って作成します。

  1. Adaptive Card Desingerを開く
  2. New Cardをクリックして、「Restaurant」というデザインを今回の土台として選択しました。
  3. Select Host Appでは、「Microsoft Teams Light」を選びます。他にもOutlook等がありますが、現状あまり使う機会はないでしょう。
  4. 自動的にTarget Versionは1.4になります(現時点でTeamsの場合は、Adaptive Card 1.4までしか対応していません)
  5. CARD PAYLOAD EDITORにテンプレートが生成されます。
  6. テンプレート内の「${url}」といったような$の付いたものは、変数なので削除してしまって構いません。後で、Power Automate上で置き換えたり、直接書き換えてしまいます。
  7. actionsのセクションがボタンに対する動作を定義しています。今回はBoxのURLを割り当ててファイルを直接開くコマンドと、投稿した人に対して問い合わせするTeamsのURL Schemeを割り当てています。
  8. 何かパーツを足す場合には、左サイドバーのCARD ELEMENTをダブルクリックすると、Bodyの一番下に追加されます。但し、次のElementが無いのに「カンマ」が残っているとエラーになるので注意。
  9. 直接5.の内容を書き換えるのも良いのですが、右サイドバーのCARD STRUCTUREで要素を選び、ELEMENT PROPERTIESで対象のパーツのプロパティを変更します。例えばImageならば、URLを指定して画像を指定する等。
  10. Target Versionによっては使えない・反映されないプロパティもあります。
  11. 5.のBody項目内のtextやActionのURL内容等は、Power Automate側に貼り付けてから、データの要素を追加して手直しします。

Adaptive Card内では、通常の投稿で利用できるHTMLが一部しか利用できないので、要注意です。

図:アダプティブカードを貼り付けて調整中

図:Designerでの作成中の様子

自分が今回作成したカードのソース

貼り付けてそのまま使えるわけではないですが、作成事例としてこんな感じで作っていますというものです。Power Automate上に貼りつけて、データ項目を差し込んで調整したものになります。

注意点ですが、TeamsではactionsのAction.openUrlでは、httpsから始まるURL Schemeおよびmailto:については利用可能ですが、特殊なURL Scheme(例:msnweather://)は、セキュリティの観点から指定しても開けません。

{
    "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
    "type": "AdaptiveCard",
    "version": "1.4",
    "body": [
        {
            "speak": "Box編集通知",
            "type": "ColumnSet",
            "columns": [
                {
                    "type": "Column",
                    "width": 2,
                    "items": [
                        {
                            "type": "TextBlock",
                            "text": "@{body('JSON_の解析')?['source']?['name']}",
                            "wrap": true
                        },
                        {
                            "type": "TextBlock",
                            "text": "@{body('JSON_の解析')?['source']?['modified_by']?['name']}",
                            "weight": "Bolder",
                            "size": "ExtraLarge",
                            "spacing": "None",
                            "wrap": true
                        },
                        {
                            "type": "TextBlock",
                            "text": "@{body('タイム_ゾーンの変換')} - @{body('JSON_の解析')?['trigger']}",
                            "isSubtle": true,
                            "spacing": "None",
                            "wrap": true
                        },
                        {
                            "type": "TextBlock",
                            "text": "[@{body('JSON_の解析')?['source']?['modified_by']?['login']}](mailto:@{body('JSON_の解析')?['source']?['modified_by']?['login']})",
                            "isSubtle": true,
                            "spacing": "None",
                            "wrap": true
                        },
                        {
                            "type": "TextBlock",
                            "text": "@{body('JSON_の解析')?['source']?['modified_by']?['name']}によってファイルが編集されました。内容を確認しましょう。",
                            "size": "Small",
                            "wrap": true,
                            "maxLines": 3
                        }
                    ]
                },
                {
                    "type": "Column",
                    "width": 1,
                    "items": [
                        {
                            "type": "Image",
                            "url": "https://icons.iconarchive.com/icons/designbolts/seo/128/Upload-Information-icon.png"
                        }
                    ]
                }
            ]
        }
    ],
    "actions": [
        {
            "type": "Action.OpenUrl",
            "title": "ファイルを開く",
            "url": "https://app.box.com/file/@{body('JSON_の解析')?['source']?['id']}",
            "style": "positive"
        },
        {
            "type": "Action.OpenUrl",
            "title": "問い合わせ",
            "url": "https://teams.microsoft.com/l/chat/0/0?users=@{body('JSON_の解析')?['source']?['modified_by']?['login']}",
            "style": "destructive"
        }
    ]
}

図:実際に送信した完成図

ちょっとしたテクニック

カードをフルサイズにする

通常、Target Version 1.4のTeams宛に作ったJSON内容であれば、フルサイズが初期で表示されるはずなのですが、そうではない場合には、以下のエントリーをBodyと同じレベルの場所に追加する事で、Teamsの場合はフルサイズ表示となるよう指定が可能です。

"msteams": {
    "width": "Full"
}

テキストボックスにハイパーリンクを貼る

テキストボックスのプロパティ項目には、ハイパーリンクのプロパティがありません。しかし、Markdownを利用する事で、ハイパーリンクを貼る事が可能になっています。例えば、特定の文字列にmailtoのハイパーリンクを貼る場合は以下のように記述します。

[title](url)の形式で記述するので、titleの部分にPower Automate上の要素、urlの部分にmailto:に続けてメアドを指定すれば、クリックするとメーラーが起動するハイパーリンクを指定可能。応用すれば、URL Schemeを使って別のアプリを起動して・・・といった事も可能になります。

{
    "type": "TextBlock",
    "text": "[@{body('JSON_の解析')?['source']?['modified_by']?['login']}](mailto:@{body('JSON_の解析')?['source']?['modified_by']?['login']})",
    "isSubtle": true,
    "spacing": "None",
    "wrap": true
}

ユーザへのメンションを付ける

Graph APIでは、チャンネルメンション等が利用できますが、Adaptive Cardを使った手法の場合、現時点ではまだユーザとタグへのメンションしか行う事ができません(HTTPコネクタを利用してチャンネルに対してのメンションをPOSTで力技で送ってる人はいるようです)。

bodyの対象の人の名前を<at>で括り、msteamsセクションでメンションの為のユーザのID等を指定する事で可能になるため、Power Automateのフローで事前にユーザのMicrosoft365上でのユーザIDを取得しておく必要があります。

以下のコードに於ける「29:123124124124」の部分であるユーザのIDの取り方は、Power AutomateでTeamsコネクタの「ユーザの@mentionトークンを取得する」にて、対象のメアドを入れる事で取得可能です。メンションは複数指定する事が可能です。

図:メンショントークンでIDを取得出来る

"body": [
    {
      "type": "TextBlock",
      "text": "Hi <at>John Doe</at>"
    }
]
"msteams": {
    "entities": [
        {
            "type": "mention",
            "text": "<at>John Doe</at>",
            "mentioned": {
                "id": "29:123124124124",
                "name": "John Doe"
            }
        }
    ]
}

条件判定をする

カードに含ませる情報に応じて、条件判定をしてボタンなどのプロパティをオンオフしたりする事が可能です。以下の事例は単純に値が0以上ならばgreen、そうでなければattentionというカラースタイルに変更する条件になります。

要素名の場所に数値の値をPower Automate上で割り当てて判定させます。

{
    "type": "TextBlock",
    "text": "現在の値は 要素名 です",
    "color": "${if(要素名 >= 0, 'good', 'attention')}",
    "spacing": "None",
    "wrap": true
}

フォーム送信出来るカードを作る

Adaptive Cardには一方的に送信するだけでなく、フォームを構築してユーザが送信した内容を取得して処理をする仕組みも用意されています。このタイプのカードを送信したい場合には、Power AutomateのTeamsコネクタは「アダプティブカードを投稿して応答を待機する」を選択して処理を作る事になります。但し、現時点では送信者についてはユーザが選択できず、「フローボット」「Power Virtual Agent」の2つしか利用できず、この操作を制限してる組織では利用できません。

更新メッセージは相手が応答した時に表示するメッセージになります。

図:ユーザが返信できるコネクタはこれを使う

図:送信されたフォームなカードと応答

図:デザイナ上での選択肢の作成

{
    "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
    "type": "AdaptiveCard",
    "version": "1.4",
    "speak": "値選択サンプル",
    "body": [
        {
            "type": "Input.ChoiceSet",
            "id": "selectman",
            "label": "項目を選択してください。",
            "value": "値を選択",
            "choices": [
                {
                    "title": "はい",
                    "value": "true"
                },
                {
                    "title": "いいえ",
                    "value": "false"
                }
            ]
        }
    ],
    "actions": [
        {
            "type": "Action.Submit",
            "title": "データ送信",
            "style": "positive"
        }
    ]
}
  • Input.ChoiceSetにて項目を作ると、プルダウンメニューとなり選択する事が出来るようになります
  • Choicesに選択項目を用意する。デザイナ上からも準備する事が可能です
  • actionsのtypeはAction.SubmitにするとFormのSubmitと同じ動作になります。
  • 送信されると、コネクタにID:selectmanの選択項目がJSONレスポンスとして送信されるので、これを受け取ります。
  • 送信された内容は他のコネクタで拾う事が可能なので、これを元にExcel Onlineに書き込んだりすればデータを自動で蓄積する事が可能です。以下の図の場合、「はい」を選択して送信すると、メールにはtrueだけが送られます。

図:送信内容は他のコネクタで拾う事が可能

JSONデータの繰り返し処理

Node.js等のプログラムから利用する場合のAdaptive Cardの場合、Adaptive Card Designer上では、$dataを用意し、それに接続して連想配列のデータを取得し、繰り返し処理で1枚のカードに出力する事が出来るのですが、Power Automate上のTeamsのAdaptive Cardでは現在この処理はサポートされていません

そうなると、Teamsコネクタ外で処理をしてJSON配列のリストから一塊にしたデータを挿入して送信するような手法を取る必要があります。似たような処理はこちらのサイトでも公開されています。以下の手順で実現可能です。

  1. データ操作で検索してから、「作成」を選択する
  2. 以下のデータを入れる(これが繰り返し処理対象のデータとなる)
    {
      "expenses": [
        {
          "expense_id": "16367000000083065",
          "description": "とまと",
          "created_time": "2019-06-19T18:33:12+0800"
        },
        {
          "expense_id": "16367000000083065",
          "description": "しいたけ",
          "created_time": "2019-06-19T18:33:12+0800"
        },
        {
          "expense_id": "16367000000083065",
          "description": "カニ味噌",
          "created_time": "2019-06-21T18:33:12+0800"
        }
      ]
    }
  3. 次にデータ操作で検索してから、「JSONの解析」を選択する
  4. コンテンツに直前に作った「作成」⇒「出力」を選択する
  5. スキーマの下にあるサンプルから生成をクリックして、2.の内容を入れて完了をクリックすると、スキーマが自動で作成されます。
  6. 次にデータ操作で検索してから、「選択」を選択し、名前をSelectに変更します。
  7. 開始には選択項目から、expensesを選択する
  8. マップには1行目は、キーにtype, 値にTextBlockを入力する
  9. マップの2行目には、キーにtext, 値にdescriptionを選択して入れる
  10. Teamsコネクタの「チャットやチャンネルにアダプティブカードを投稿する」を追加し、アダプティブカードには以下のようなものを記述する
    {
        "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
        "type": "AdaptiveCard",
        "version": "1.4",
        "body": [
            {
                "type": "Container",
                "items":   @{body('Select')
            }
        ]
    }

    ※itemsには、数式として以下のような数式をいれる。なぜか直前の選択の要素が取得出来ないので、手動で入れる(バグらしい)

    body('Select')

これで、送信すると、2. の中身をひとつずつ拾って、1つの塊にしてくれます。

図:選択コネクタの指定

図:実際に送信した結果

Teams上でダイアログとして呼び出し

Power Automateで作成したアダプティブカードな内容をチャットの投稿ではなく、入力ダイアログとして利用し、Power AutomateへTeamsから投げるといったような用途が実現出来ます。作り方は以下の通り

  1. 予め、TeamsのチャンネルにはPower Automateアプリを追加しておく
  2. Power Automateを開き、新規にインスタントクラウドフローを作成する(アダプティブテストと命名した)
  3. Teamsで検索して、「作成ボックスから(V2)」を選択する
  4. アダプティブカードの作成をクリックする
  5. Adaptive Card Designerが起動するので、下のCard Payload Editorの+ボタンをクリックする
  6. New CardをクリックしてもBlankしか無いので、Adaptive Card Designerのサイトへ行って作り、JSONをコピーして貼り付ける(但しこちらは、Card Versionは1.2までしかサポートされていない)。今回は以下のようなカードを作成
    {
        "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
        "type": "AdaptiveCard",
        "version": "1.2",
        "speak": "選択",
        "body": [
            {
                "type": "TextBlock",
                "text": "何食べたい?",
                "size": "Large",
                "weight": "Bolder",
                "style": "heading"
            },
            {
                "type": "TextBlock",
                "text": "ランチミーティング",
                "isSubtle": true
            },
            {
                "type": "TextBlock",
                "text": "12:00 - 13:00",
                "isSubtle": true,
                "spacing": "None"
            },
            {
                "type": "Input.ChoiceSet",
                "id": "food",
                "label": "昼食のメニューを選択",
                "value": "",
                "choices": [
                    {
                        "title": "ラーメン",
                        "value": "1"
                    },
                    {
                        "title": "ビフテキ",
                        "value": "2"
                    },
                    {
                        "title": "お寿司",
                        "value": "3"
                    }
                ]
            }
        ],
        "actions": [
            {
                "type": "Action.Submit",
                "title": "送信"
            }
        ]
    }
  7. カードの保存をクリック
  8. 続けて、プロフィールで検索して「マイプロフィール(V2)」を追加する
  9. 続けて、Teamsで検索して「チャットまたはチャンネルでメッセージを投稿する」を追加する
  10. 投稿者はフローボット、投稿先は「フローボットとチャットする」を選択
  11. Recipientにはプロフィールから、メールを選択する
  12. メッセージには、ユーザが選んだ内容をオウム返しする。作成ボックスV2の出力の中のcardOutputsに値が入ってるので、これを取り出して使うので以下のような数式を入れる
    triggerBody()?['entity']?['cardOutputs']?['food']

    これで、IDがfoodの内容が取れるようになります。

  13. 必要に応じて、12.につづけて処理をつなげる
  14. 保存をする

すると、Teams側に通知が飛んでいき、このフローが使えるようになります。続けて

  1. 左サイドバーの「…」をクリックして、Power Automateを開く
  2. チャットタブを開きます。
  3. チャット入力欄の下にあるメニューから「workflow」のボタンをクリックする
  4. すると、ダイアログで作成したアダプティブカードが表示される。

ただ、送信しても受け取る手段がわからないのと、一度利用可能になってからPower Automateを編集した時に、送信がエラーになる現象が出てたりとまだまだバギーな印象(その場合1から作り直すことになる)。

図:作成ボックスを選んでスタート

図:フローを呼び出す

図:アダプティブカードが出てきた

今回のフローのサンプル

フローサンプルダウンロード

上記のファイルはZIPで固められています。インポートする為には解凍せずそのままインポートすればOKです。このサンプルでTeamsにアダプティブカードを送ると以下のようなスタイルのものが送信されます。

図:送信されるカードデザインのサンプル

フローのインポート方法

フローのサンプルはZIPで固められています。このファイルを自分の環境にインポートする事で、今回のフローを復元する事が出来ます。但し、利用するExcelファイルへのパスであったり、送信先Teamsチャンネル、利用するアカウント等の手修正は必要です。インポートする手順は以下のとおりです。

  1. Power Automateを開き、マイフローを開く
  2. 上記にある「インポート」をクリック
  3. アップロードボタンをクリックして、ZIPファイルを指定する
  4. インポートオプションは「新しく作成する」を選択する
  5. 関連リソースは自身のアカウントを選択し保存をクリックします
  6. インポートボタンが押せるようになるので、クリックする
  7. 完了してマイフローを開いても何故か出てこないので、ページをリロードする
  8. 対象のフローは無効化された状態になってるので、編集をクリックする
  9. 色々手直しをして保存する(ファイルパスやアカウント、送信先Teamsチャンネル等)
  10. フローチェッカーをクリックして、このフローをオンにするをクリックする

これで、利用できるようになります。

図:インポートをする画面

図:フローをオンにしないと利用できない

Workflows, Actions and "From the compose box" trigger in Microsoft Teams

関連リンク

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)