MoreBeerMorePower

Power Platform中心だけど、ノーコード/ローコード系を書いてます。

Adaptive Cards Templating SDK を Azure Functionで利用して自前のTemplating APIを作る

Adaptive Cards のTemplatingとは?

端的に言えば、Adaptive Cardsのレイアウトとそこに表示するデータの分離です。

レイアウト側に ${title}のような文字を入れておいて、データ側で {"title":"This is title"}のように指定すると、生成されたカードには This is titleと表示されるようになります。

または同じレイアウトで、データを{"title":"Hello world"} とすれば、${title}で指定される部分にはHello worldが表示されるといった具合です。

Adaptive Cardsデザイナーを利用したことがあれば、このTemplatingはすでに目にしているはずで、 デザイナーの下半分がちょうど、レイアウトとデータの分離を表しています。

f:id:mofumofu_dance:20200623230627p:plain

Templating の詳細は以下の公式ドキュメントを参照してください。

Templating Overview - Adaptive Cards | Microsoft Docs

なぜTemplating API??

Power AutomateでTeamsにAdaptive Cardsを送信するとき、一度Adaptive Cardsデザイナーで作るんですが、Template化されるのでそのままコピー&ペーストすると手で書き換えが発生するのですよね。

あるいはPower Automate上でうまく、データとレイアウト (Card payload)を合わせたようなJSONを作って、Teamsのアクションに設定するといった面倒さがあります。

Templatingは非常に強力で、手作業でのデータ挿入を行うことなく、レイアウトとデータを別々に管理できるのがメリットなのにこれではあまり恩恵にあずかれていません。

f:id:mofumofu_dance:20200623231307p:plain

こんな具合に。

このような勿体なさを解消するために、Azure Functionsを利用して、分離されたレイアウトとデータからデータを挿入した (そのままTeamsで送れる) Adaptive CardsのJSONを返すAPIを作成しました。

ありがたいことに公式でTemplating SDKが提供されていて、JavaScriptでも利用可能ということでしたので、Azure FunctionsではNode.jsでHTTP Triggerにしています。

Azure Functions

Templating SDKはnpmでインストール可能です。 Function Appのリソースを追加したら、Overviewのところで、Consoleを表示します。

Consoleが表示されたら、以下のコマンドを実行するだけです。(参考:Azure Functions (Node.js) で npm パッケージを追加して利用する方法 (コンソール利用) - Qiita )

f:id:mofumofu_dance:20200624001907p:plain

> npm init --yes
> npm install adaptivecards-templating

準備はこれで終わり。あとはとても簡単に、requestのbodyに含まれるレイアウトとデータをうまく使って、SDKに含まれる処理を実行するだけです。

const adaptiveTemp = require('adaptivecards-templating');

module.exports = async function (context, req) {
    context.log('JavaScript HTTP trigger function processed a request.');
    var templatePayload = req.body.struct;
    var template = new adaptiveTemp.Template(templatePayload);

    var cardPayload = template.expand({
        $root: req.body.data
    });
    context.res = {
        // status: 200, /* Defaults to 200 */
        body: cardPayload
    };
}

大変ローコード。

前提として、ここではリクエストのbodyに以下のようなJSONが受け渡されることを想定しています。

{
  "struct" : ここにAdaptive Cardsのレイアウト部分,
  "data" : ここにデータ部分
}

Power Automateで使ってみる

さっそくPower Automateから作ったFunctionを呼び出して、Teamsに投稿してみます。

目標とするのは下図のような、配列を利用したFactSetのカードです。 f:id:mofumofu_dance:20200623233055p:plain

  1. まずは作成アクションで、カードのレイアウトとデータをそれぞれ、Adaptive Cardsデザイナーからコピーしてきて貼り付けます
  2. 次にそれをまとめて、Azure Function実行時のBodyにセットします
  3. 得られた結果をTeamsにFlow botとして送信

f:id:mofumofu_dance:20200623233754p:plain

めでたく期待されるAdaptive Cardsが送信されました。

まとめ・活用

Adaptive CardsのTemplating SDKとAzure Functionsを利用することで、非常に簡単にAdaptive Cardsのレイアウトとデータの分離をPower Automateでも実現できることを紹介しました。

レイアウトがデータから切り離されたので、あとは利用するフロー側で汎用化する仕組み、例えばjsonファイルをドキュメントライブラリに置いておいて、それを読み込み、他サービスから取得したデータと合わせる ということが可能になります。

Templating、ぜひ活用してみてください。

f:id:mofumofu_dance:20200623234923p:plain