3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

なんとなく難しそうだから避けてきたアダプティブカードをCopilotに手伝ってもらうことで使ってみる

Last updated at Posted at 2025-08-15

Copilot登場前に挫折経験ありです

皆さんアダプティブカードつかってますか? 私は使ってませんw。実は以前に利用しようとチャレンジしたのですがあきらめました。 

アダプティブカードって、かっこいいビジュアルのカードをTeamsで送りつけて、インタラクティブにお返事もらえたりするんでしょう?

たとえば、こんな感じのカードを送ることができます。
image.png

Power Automateから簡単に利用できるはず

Power Automateからは「チャットやチャネルにカードを投稿する」アクションで利用することができます。
image.png

クラウドフローに慣れた方なら、JSONで表示したい内容やボタンの配置を指定するのね?とイメージは湧くのですが、なんか大変そうだなぁ・・・ という印象は拭えません。

こちらがアダプティブカードのマニュアル

Microsoft Learn ではこちらが説明ページになってます。いろいろなサンプルJSONが載ってます。

数年前にチャレンジしたときにもあったのですが、アダプティブカードのUI開発ツールというのも公開されています。こちらを使って素敵なUIを組み立てると、利用できるJSONが生成されるというわけです。
image.png

ですが、Copilot登場以前の私にはハードルが高すぎました。

そして今Copilotという相棒を手に入れた!

そう。当時は誰も教えてくれる人がいなかったのですが、いまなら彼がいるじゃないですか? Copilotくんです。
まずは、サンプルとして利用できるJSONを提供してくれるようにお願いしてみました。
image.png

先生さすがです!

JSON
{
  "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
  "type": "AdaptiveCard",
  "version": "1.5",
  "body": [
    {
      "type": "TextBlock",
      "text": "こんにちは、mocabrown daddyさん!",
      "weight": "Bolder",
      "size": "Medium"
    },
    {
      "type": "TextBlock",
      "text": "これはアダプティブカードのサンプルです。",
      "wrap": true
    },
    {
      "type": "Image",
      "url": "https://adaptivecards.io/content/cats/1.png",
      "size": "Medium",
      "style": "Person"
    },
    {
      "type": "TextBlock",
      "text": "以下のボタンをクリックしてください:",
      "wrap": true
    }
  ],
  "actions": [
    {
      "type": "Action.OpenUrl",
      "title": "詳細を見る",
      "url": "https://adaptivecards.io"
    },
    {
      "type": "Action.Submit",
      "title": "送信",
      "data": {
        "action": "submitForm"
      }
    }
  ]
}

これを、さきほどの「チャットやチャネルにカードを投稿する」アクションに貼り付けてやると、こんな感じのカードを投稿することができました!
image.png

アレンジしてみる

以前にどこかで毎朝自動的に社員にアダプティブカードを送信して、出勤、在宅のどちらかを尋ねる仕組みが紹介されているのを見かけたことがあります。真似してみます。

image.png

JSON
{
  "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
  "type": "AdaptiveCard",
  "version": "1.5",
  "body": [
    {
      "type": "TextBlock",
      "text": "本日の勤務形態を選択してください",
      "weight": "Bolder",
      "size": "Medium"
    },
    {
      "type": "Input.ChoiceSet",
      "id": "workLocation",
      "style": "expanded",
      "choices": [
        {
          "title": "出勤",
          "value": "office"
        },
        {
          "title": "在宅勤務",
          "value": "remote"
        }
      ],
      "isMultiSelect": false
    }
  ],
  "actions": [
    {
      "type": "Action.Submit",
      "title": "送信",
      "data": {
        "action": "submitWorkLocation"
      }
    }
  ]
}


テスト実行してみると、あら素敵! さっそく回答してみます。
image.png

なんですと? アプリに接続できません??
image.png

質問するならカード用のアクションは待機しないといけない

Power Automateでカード関連のアクションを検索してみると、投稿するだけではなくて結果を待つためのアクションが必要なようです。
image.png

「アダプティブカードを投稿して応答を待機する」を使ってみます。
image.png

こんどは質問に回答することで、ありがとうメッセージが表示されました。このありがとうの部分の文字列も、先程のアクションの中で指定できます。
image.png

待機中だったアクションが回答を受けると終了します。一般的なアクションと同じように結果はJSONで返ってきます。そのなかのdataという項目にアダプティブカードで選択された選択肢が返ってきていました。
image.png

アダプティブカードでは以下のように指定していたのでこのチョイスが返ってきているんですね。
image.png

結果をSharePointリストに登録するならこんな感じで。
image.png

リストには登録日時が自動で記録されるし、これでいいのでは?
image.png

もっとリッチな感じにしたいよ!

もっとかっこよく、当日の天気も表示させたいです先生!
こんなサンプルがありました。

image.png

現段階ではサンプルの気温などが文字列として入っていますが、仕組みがイメージできそうなJSONを返してくれました。

JSON
{
  "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
  "type": "AdaptiveCard",
  "version": "1.5",
  "backgroundImage": {
    "url": "https://adaptivecards.io/content/cloud-background.png"
  },
  "body": [
    {
      "type": "ColumnSet",
      "columns": [
        {
          "type": "Column",
          "width": "auto",
          "items": [
            {
              "type": "Image",
              "url": "https://adaptivecards.io/content/weather-sunny.png",
              "size": "Large",
              "altText": "Sunny"
            }
          ]
        },
        {
          "type": "Column",
          "width": "stretch",
          "items": [
            {
              "type": "TextBlock",
              "text": "大阪市",
              "weight": "Bolder",
              "size": "ExtraLarge",
              "color": "Light"
            },
            {
              "type": "TextBlock",
              "text": "晴れ時々曇り",
              "size": "Medium",
              "color": "Light"
            },
            {
              "type": "TextBlock",
              "text": "33℃ / 28℃",
              "size": "Large",
              "weight": "Bolder",
              "color": "Light"
            }
          ]
        }
      ]
    },
    {
      "type": "FactSet",
      "facts": [
        {
          "title": "湿度:",
          "value": "89%"
        },
        {
          "title": "風速:",
          "value": "南西 3m/s"
        },
        {
          "title": "降水確率:",
          "value": "20%"
        }
      ]
    },
    {
      "type": "TextBlock",
      "text": "本日の勤務形態を選択してください",
      "weight": "Bolder",
      "size": "Medium",
      "separator": true
    },
    {
      "type": "Input.ChoiceSet",
      "id": "workLocation",
      "style": "expanded",
      "choices": [
        {
          "title": "出勤",
          "value": "office"
        },
        {
          "title": "在宅勤務",
          "value": "remote"
        }
      ],
      "isMultiSelect": false
    }
  ],
  "actions": [
    {
      "type": "Action.Submit",
      "title": "送信",
      "data": {
        "action": "submitWorkLocation"
      }
    }
  ]
}

ふたたびJSONを差し替えて実行してみると、残念ながら、お天気アイコンがリンク切れしてますね。アイコンのURLをブラウザで開いてみてもやはりリンク切れでした。結構前のサンプルらしいのでしかたなし。
image.png

実際の天気を取得したいので、MSN天気アクションを使います。
実行結果のJSONを覗いてみると、天気条件は英語で出ます。こりゃあ、「いらすとや」とかでお天気アイコンを用意して、条件わけして表示させるしかないのかなぁ?いくつパターンがあるのかわからず、アイコンは別に用意するにしてもどうやって紐付けようかなぁと悩みながら、戻り値のJSONを見ているとなにやら画像のURLが・・・。これはもしかして。

image.png

感動しちゃった!
image.png

MSN天気のアクション名を「現在の天気取得」としていた場合、続くアクションのなかでアイコンのURLを取得するには以下のような形で式を作ります。以下の文字列をそのまま貼り付けてもらえば使えるはずです。

@{outputs('現在の天気取得')?['body/responses/weather/current/urlIcon']}

この取得の方法をいちどCopilot先生に教えたうえで、「現在の天気取得」が返してきたJSONを貼り付けてCopilotにどうすればよいかたずねました。(JSON長過ぎるので、関係がありそうなBody以下の部分だけ貼ってみました。)
image.png

すると、アダプティブカードに設定するべきJSONを返してくれます。
image.png

はい。結果はこのとおり!参考の式をもとに、JSONから適切な項目に適切な式を使って値を抜き出してくれています。このあたり賢いですよね! 人間だとひとつひとつ確認しながら当てはめていく、一番ミスを起こしそうな作業です。

image.png

以下がアダプティブカードに設定したJSONです。例を与えると、きっちり答えてくれるところが賢いですね。

JSON
{
  "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
  "type": "AdaptiveCard",
  "version": "1.5",
  "body": [
    {
      "type": "ColumnSet",
      "columns": [
        {
          "type": "Column",
          "width": "auto",
          "items": [
            {
              "type": "Image",
              "url": "@{outputs('現在の天気取得')?['body/responses/weather/current/urlIcon']}",
              "size": "Large",
              "altText": "@{outputs('現在の天気取得')?['body/responses/weather/current/cap']}"
            }
          ]
        },
        {
          "type": "Column",
          "width": "stretch",
          "items": [
            {
              "type": "TextBlock",
              "text": "大阪市",
              "weight": "Bolder",
              "size": "ExtraLarge"
            },
            {
              "type": "TextBlock",
              "text": "@{outputs('現在の天気取得')?['body/responses/weather/current/cap']}",
              "size": "Medium"
            },
            {
              "type": "TextBlock",
              "text": "@{outputs('現在の天気取得')?['body/responses/weather/current/temp']}℃(体感 @{outputs('現在の天気取得')?['body/responses/weather/current/feels']}℃)",
              "size": "Large",
              "weight": "Bolder"
            }
          ]
        }
      ]
    },
    {
      "type": "FactSet",
      "facts": [
        {
          "title": "湿度:",
          "value": "@{outputs('現在の天気取得')?['body/responses/weather/current/rh']}%"
        },
        {
          "title": "風速:",
          "value": "@{outputs('現在の天気取得')?['body/responses/weather/current/windSpd']} km/h"
        },
        {
          "title": "UV指数:",
          "value": "@{outputs('現在の天気取得')?['body/responses/weather/current/uv']}(@{outputs('現在の天気取得')?['body/responses/weather/current/uvDesc']})"
        },
        {
          "title": "空の状態:",
          "value": "@{outputs('現在の天気取得')?['body/responses/weather/current/sky']}"
        }
      ]
    },
    {
      "type": "TextBlock",
      "text": "本日の勤務形態を選択してください",
      "weight": "Bolder",
      "size": "Medium",
      "separator": true
    },
    {
      "type": "Input.ChoiceSet",
      "id": "workLocation",
      "style": "expanded",
      "choices": [
        {
          "title": "出勤",
          "value": "office"
        },
        {
          "title": "在宅勤務",
          "value": "remote"
        }
      ],
      "isMultiSelect": false
    }
  ],
  "actions": [
    {
      "type": "Action.Submit",
      "title": "送信",
      "data": {
        "action": "submitWorkLocation"
      }
    }
  ]
}

今回のポイント

  • MSN天気アクションは天気アイコン画像のURLを持っている
  • アダプティブカードなどは、サンプルJSONが掲載されているURLをCopilotに与えると参考にしてくれる
  • JSONから抜き出したい項目を取得する式をひとつ作ったら、元になるJSONと式のサンプルを与えることで、ぴったりの回答を作ってくれる
  • アダプティブカードで返事が欲しいときには「アダプティブカードを投稿して応答を待機する」をつかう
3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?