MoreBeerMorePower

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

HTML上で Adaptive Card を表示する - (3) アクションへの対応

f:id:mofumofu_dance:20210510234111p:plain

前回: https://mofumofupower.hatenablog.com/entry/adaptivecard-rendering-html2

前回までで、単純なカードの表示とスタイルの設定を行いました。

<html>
<head>
    <link rel="stylesheet" href="ここにCSSファイルのパス" />
    <script type="text/javascript" src="https://unpkg.com/adaptivecards/dist/adaptivecards.js"></script>
    <script type="text/javascript" src="https://unpkg.com/markdown-it/dist/markdown-it.min.js"></script>
</head>
<body>
    <script type="text/javascript">
        // Set card json
        const card = {ここにカードのJSON};
        // Create an AdaptiveCard instance
        let adaptiveCard = new AdaptiveCards.AdaptiveCard();
        // Host Config defines the style and behavior of a card
        const hostcfg = {ここにHostConfigのJSON};
        adaptiveCard.hostConfig = new AdaptiveCards.HostConfig(hostcfg);
       // Parse the card payload
        adaptiveCard.parse(card);
        // Render the card to an HTML element
        var renderedCard = adaptiveCard.render();
        // And finally insert it in the page
        document.body.appendChild(renderedCard);
    </script>
</body>
</html>

余談ですが、ファイル置き場はBlobストレージにしています。とくにCSSファイルですが、GithubにおいておいたらCORB (クロスオリジンリソースブロッキング) というやつに出くわしてスタイルが読み込まれなかったので、Azure Blobストレージにしました。

Adaptive Card のいいところといえば、JSONで書ける!ということのほかに、アクションができるというのもありますね。

今回は Adaptive Card を利用する場合のメインのアクション、 Action.Submit と Action.OpenUrl への対応を紹介します。

なお、ドキュメントとしては 以下に簡単に書かれています。

docs.microsoft.com

1. アクションへの対応 (scriptの追加)

Adaptive Cardのアクションの中でも、表示切替をするような Action.ShowCard なんかは特に対応の必要がないのですが、SubmitはそうもいかずデータをSubmitする先のURLを指定したりする必要があります。

これを実現するためにスクリプトの最後に以下を追加します。

<script>
....
        // Set the adaptive card's event handlers. 
        adaptiveCard.onExecuteAction = function (action) {
            console.info(action._propertyBag);
            if (action instanceof AdaptiveCards.SubmitAction) {
                let xhr = new XMLHttpRequest();
                xhr.onreadystatechange = function () {
                    if (this.readyState != 4) return;
                    if (this.status == 200) {
                        const data = JSON.parse(this.responseText);
                        // Parse the card payload
                        adaptiveCard.parse(data);
                        // Render the card to an HTML element:
                        let renderedCard = adaptiveCard.render();
                        //Remove original card elements
                        const ss = document.getElementsByTagName("div")[0];
                        document.body.removeChild(ss);
                        // And finally insert it somewhere in your page:
                        document.body.appendChild(renderedCard);
                    }
                };
                xhr.open("POST", "ここに送信先のURL", true);
                xhr.setRequestHeader('Content-Type', 'application/json');
                xhr.send(JSON.stringify({
                    value: action.data
                }));
            } else if (action instanceof AdaptiveCards.OpenUrlAction) {
                window.open(action._propertyBag.url, '_blank');
            };
        }
</script>

これで送信先のURLに対して、JSON形式でAdaptive Cardのデータが送信されます。

なお、ここでは送信 (POST) が成功したら、応答としてAdaptive CardのJSONが送られてきて、そのカードで全体を上書きするようにしています。

もし、レスポンスを使わずに固定のカードで更新する場合には

const data = JSON.parse(this.responseText); の部分を const data = {更新用カードのJSON}; で書き換えればOKです。

2. 受け側の用意

やっと Power Platformがここで出てきます。受け側 (データを送る先) には Power Automate の 「HTTP要求の受信時」のトリガーを使うと便利です。

基本はトリガーのあとに「応答」アクションを入れて、更新用のカードのJSONを返しているだけです。

f:id:mofumofu_dance:20210510232646p:plain

受信したデータをどこかに登録したい場合には、間に何らか登録処理を入れてください。

まとめ

今回のアクションへの対応を含めて、HTMLは以下のように書けます。

<html>
<head>
    <link rel="stylesheet" href="ここにCSSファイルのパス" />
    <script type="text/javascript" src="https://unpkg.com/adaptivecards/dist/adaptivecards.js"></script>
    <script type="text/javascript" src="https://unpkg.com/markdown-it/dist/markdown-it.min.js"></script>
</head>
<body>
    <script type="text/javascript">
        // Set card json
        const card = {ここにカードのJSON};
        // Create an AdaptiveCard instance
        let adaptiveCard = new AdaptiveCards.AdaptiveCard();
        // Host Config defines the style and behavior of a card
        const hostcfg = {ここにHostConfigのJSON};
        adaptiveCard.hostConfig = new AdaptiveCards.HostConfig(hostcfg);
       // Parse the card payload
        adaptiveCard.parse(card);
        // Render the card to an HTML element
        var renderedCard = adaptiveCard.render();
        // And finally insert it in the page
        document.body.appendChild(renderedCard);

        // Set the adaptive card's event handlers. 
        adaptiveCard.onExecuteAction = function (action) {
            console.info(action._propertyBag);
            if (action instanceof AdaptiveCards.SubmitAction) {
                let xhr = new XMLHttpRequest();
                xhr.onreadystatechange = function () {
                    if (this.readyState != 4) return;
                    if (this.status == 200) {
                        const data = JSON.parse(this.responseText);
                        // Parse the card payload
                        adaptiveCard.parse(data);
                        // Render the card to an HTML element:
                        let renderedCard = adaptiveCard.render();
                        //Remove original card elements
                        const ss = document.getElementsByTagName("div")[0];
                        document.body.removeChild(ss);
                        // And finally insert it somewhere in your page:
                        document.body.appendChild(renderedCard);
                    }
                };
                xhr.open("POST", "ここに送信先のURL", true);
                xhr.setRequestHeader('Content-Type', 'application/json');
                xhr.send(JSON.stringify({
                    value: action.data
                }));
            } else if (action instanceof AdaptiveCards.OpenUrlAction) {
                window.open(action._propertyBag.url, '_blank');
            };
        }
    </script>
</body>
</html>

まだギリギリローコードなはず・・。

動作は以下のようになります。スタイルを入れて、Submitアクションにも対応させているので、送信後にカードが書き換わっているのがわかるかと思います。

f:id:mofumofu_dance:20210510233234g:plain

次回は活用とか応用とかそういったところをご紹介します。