index.htmlだけでMicrosoft TeamsのAdaptive Cards
Microsoft TeamsのワークフローでおなじみAdaptive Cards(アダプティブカード)を書く必要性が出たので、CDNのjsDelivrを使い、index.htmlだけで書けるようにしたいと思います。
まずindex.htmlを作成し、npmの例をコピペして動かしてみます。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" />
<title>Adaptive Cards</title>
<meta name="description" content="Zenn" />
</head>
<body>
<script src="https://cdn.jsdelivr.net/npm/adaptivecards/dist/adaptivecards.min.js"></script>
<script>
var card = {
"type": "AdaptiveCard",
"version": "1.0",
"body": [
{
"type": "Image",
"url": "http://adaptivecards.io/content/adaptive-card-50.png"
},
{
"type": "TextBlock",
"text": "Hello **Adaptive Cards!**"
}
],
"actions": [
{
"type": "Action.OpenUrl",
"title": "Learn more",
"url": "http://adaptivecards.io"
},
{
"type": "Action.OpenUrl",
"title": "GitHub",
"url": "http://github.com/Microsoft/AdaptiveCards"
}
]
};
var adaptiveCard = new AdaptiveCards.AdaptiveCard();
adaptiveCard.hostConfig = new AdaptiveCards.HostConfig({
fontFamily: "Segoe UI, Helvetica Neue, sans-serif"
});
adaptiveCard.onExecuteAction = function(action) { alert("Ow!"); }
adaptiveCard.parse(card);
var renderedCard = adaptiveCard.render();
document.body.appendChild(renderedCard);
</script>
</body>
</html>
MarkdownがHTMLでレンダリングされないのはいいとして、スタイルが全く適用されていません。
npmのバージョン情報を確認してみると、latestはv1参照しているので、新しいバージョンにすることでjsDelivrからデフォルトのCSSを取得できるようになり、スタイルを適用することができるようです。
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/adaptivecards@3.0.4/dist/adaptivecards.css" />
- <script src="https://cdn.jsdelivr.net/npm/adaptivecards/dist/adaptivecards.min.js"></script>
+ <script src="https://cdn.jsdelivr.net/npm/adaptivecards@3.0.4/dist/adaptivecards.min.js"></script>
例もvarを使っていたり、スキーマがなかったり、バージョンが古かったり、ボタンを押してもOw!と表示されるだけでURLを開くアクションをしてくれなかったり、JSONではなく連想配列の変数をそのまま使っていたり、色々古い情報が放置されたままになっているので、ドキュメントを見ながらちゃんとしたコードに修正して動かしてみます。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" />
<title>Adaptive Cards</title>
<meta name="description" content="Zenn" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/adaptivecards@3.0.4/dist/adaptivecards.css" />
<script id="content" type="application/json">
{
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"version": "1.5",
"body": [
{
"type": "Image",
"url": "http://adaptivecards.io/content/adaptive-card-50.png"
},
{
"type": "TextBlock",
"text": "Hello **Adaptive Cards!**"
}
],
"actions": [
{
"type": "Action.OpenUrl",
"title": "Learn more",
"url": "http://adaptivecards.io"
},
{
"type": "Action.OpenUrl",
"title": "GitHub",
"url": "http://github.com/Microsoft/AdaptiveCards"
}
]
}
</script>
</head>
<body>
<div id="container" style="max-width: 320px">
</div>
<script src="https://cdn.jsdelivr.net/npm/adaptivecards@3.0.4/dist/adaptivecards.min.js"></script>
<script>
const card = new AdaptiveCards.AdaptiveCard();
card.hostConfig = new AdaptiveCards.HostConfig({
fontFamily: "Segoe UI, Helvetica Neue, sans-serif",
});
card.onExecuteAction = function(action) {
window.open(action.url, "_blank");
};
card.parse(JSON.parse(document.getElementById("content").textContent));
document.getElementById("container").appendChild(card.render());
</script>
</body>
</html>
新しいバージョンで配布されているデフォルトのCSSを適用することで、おおむね期待通りのAdaptive Cardsを表示することができました。
ではMarkdownがHTMLでレンダリングされていないので、README.mdで紹介されているようにMarkdown itを追加したいと思います。
<script src="https://cdn.jsdelivr.net/npm/adaptivecards@3.0.4/dist/adaptivecards.min.js"></script>
+ <script src="https://cdn.jsdelivr.net/npm/markdown-it@14.1.0/dist/markdown-it.min.js"></script>
<script>
期待通りのAdaptive Cardsを表示することができました。
ただ私はMicrosoft TeamsのAdaptive Cardsを書きたいので、Microsoft Teamsと同じスタイルを適用したいところです。
Adaptive CardsのDesignerではMicrosoft Teamsと同じスタイルで表示できているし、実現できそうなので。
もしかしてnpmでCSSを配布しているのではないかと思い、ソースコードを確認したところ、ありました。
ダークモード用のCSSも配布しているみたいですが、文字の色を自動的に反転してくれないみたいなので、ライトモードで妥協します。
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/adaptivecards@3.0.4/dist/adaptivecards.css" />
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/adaptivecards-designer@2.4.4/dist/containers/teams-container-light.css" />
まずはCSSをadaptivecardsパッケージで配布しているデフォルトのものではなく、adaptivecards-designerパッケージで配布しているMicrosoft Teamsのものに変更します。
-document.getElementById("container").appendChild(card.render());
+const outerFrame = document.createElement("div");
+outerFrame.classList.add("teams-frame");
+const innerFrame = document.createElement("div");
+innerFrame.classList.add("teams-inner-frame");
+const teams = document.createElement("div");
+teams.classList.add("teams-card");
+
+teams.appendChild(card.render());
+innerFrame.appendChild(teams);
+outerFrame.appendChild(innerFrame);
+document.getElementById("container").appendChild(outerFrame);
Microsoft TeamsのCSSはデフォルトのCSSと異なり、別途適用する必要のあるスタイルがあるため、クラスを追加したdiv要素を作ってあげます。
完成したものがこちら。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" />
<title>Adaptive Cards</title>
<meta name="description" content="Zenn" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/adaptivecards-designer@2.4.4/dist/containers/teams-container-light.css" />
<script id="content" type="application/json">
{
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"version": "1.5",
"body": [
{
"type": "Image",
"url": "http://adaptivecards.io/content/adaptive-card-50.png"
},
{
"type": "TextBlock",
"text": "Hello **Adaptive Cards!**"
}
],
"actions": [
{
"type": "Action.OpenUrl",
"title": "Learn more",
"url": "http://adaptivecards.io"
},
{
"type": "Action.OpenUrl",
"title": "GitHub",
"url": "http://github.com/Microsoft/AdaptiveCards"
}
]
}
</script>
</head>
<body>
<div id="container" style="max-width: 320px">
</div>
<script src="https://cdn.jsdelivr.net/npm/adaptivecards@3.0.4/dist/adaptivecards.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/markdown-it@14.1.0/dist/markdown-it.min.js"></script>
<script>
const card = new AdaptiveCards.AdaptiveCard();
card.hostConfig = new AdaptiveCards.HostConfig({
fontFamily: "Segoe UI, Helvetica Neue, sans-serif",
});
card.onExecuteAction = function(action) {
window.open(action.url, "_blank");
};
card.parse(JSON.parse(document.getElementById("content").textContent));
const outerFrame = document.createElement("div");
outerFrame.classList.add("teams-frame");
const innerFrame = document.createElement("div");
innerFrame.classList.add("teams-inner-frame");
const teams = document.createElement("div");
teams.classList.add("teams-card");
teams.appendChild(card.render());
innerFrame.appendChild(teams);
outerFrame.appendChild(innerFrame);
document.getElementById("container").appendChild(outerFrame);
</script>
</body>
</html>
index.htmlだけでMicrosoft TeamsのAdaptive Cardsを表示することができました。
ちなみに以下のように変更するとOutlook Actionable Messagesの表示にもできます。
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/adaptivecards@3.0.4/dist/adaptivecards.css" />
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/adaptivecards-designer@2.4.4/dist/containers/outlook-container.css" />
-document.getElementById("container").appendChild(card.render());
+const outlook = document.createElement("div");
+outlook.classList.add("outlook-frame");
+
+outlook.appendChild(card.render());
+document.getElementById("container").appendChild(outlook);
Discussion