Microsoft Teams の Adaptive Card を投稿前に検証する CLI `msac` を作った
はじめに
Microsoft Teams の Workflows 経由で Adaptive Card を投稿する機能を作っていた。実装中、Teams 側に Could not display とだけ表示されることがあった。
JSON を見直せば原因はわかるものの、カードが大きくなると問題のある場所を探すのがつらい。また、修正を環境にデプロイして確認するには、時間がかかるのもネックだった。
というわけで、Adaptive Card をローカルで検証する Go 製 CLI msac を作った。
msac check で投稿前に検証する
インストールは go install で。
go install github.com/Konboi/go-ms-adaptive-card-validator/cmd/msac@latest
カード単体を検証する場合はこんな感じ。
msac check -mode card card.json
たとえば TextBlock.wrap に boolean ではなく文字列を渡すと、JSON Pointer と問題のあるオブジェクトを表示する。
ERROR /body/0/wrap: expected boolean, but got string (in TextBlock)
{
"type": "TextBlock",
"text": "wrap は boolean にする",
"wrap": "true" <<< ERROR: expected boolean, but got string (in TextBlock)
}
エラーのパスだけでなく、周辺の JSON と問題のあるメンバーに印を付けた。大きなカードでも、どこを直せばよいか見つけやすい。
Teams Workflows の Webhook ペイロード全体も検証できる。
msac check -mode webhook payload.json
-mode auto がデフォルトで、ルートの type が message なら Webhook、それ以外はカード単体として扱う。標準入力にも対応している。
cat card.json | msac check -strict -
公式スキーマを切り替える
Microsoft の公式 Adaptive Card JSON Schema 1.1〜1.6 をバイナリに同梱した。検証時のネットワークアクセスは不要で、デフォルトは 1.6 にした。
古いバージョンを対象にする場合は -schema-version で切り替えられる。
msac check -schema-version 1.5 card.json
1.6 の metadata を含むカードを 1.5 として検証すると、以下のようになる。
ERROR /metadata: "metadata" is not an allowed property on AdaptiveCard
{
"webUrl": "https://example.com/deployments/123"
}
ERROR /version: card version 1.6 exceeds selected schema 1.5
実装ではスキーマを go:embed で埋め込み、santhosh-tekuri/jsonschemaで検証している。公式スキーマによる型や必須プロパティの検証に加えて、Input の重複 ID や Webhook の添付形式なども確認する。
text/template にダミーデータを渡す
今回の用途では、Go の text/template から生成した JSON を確認したかった。そのため msac render も追加した。
テンプレート内では json 関数を使って値を埋め込む。
{
"type": "AdaptiveCard",
"version": "1.6",
"body": [
{
"type": "TextBlock",
"text": {{json .message}},
"wrap": true
}
]
}
ダミーデータを渡して、そのまま check にパイプできる。
set -o pipefail
msac render \
-template card.json.tmpl \
-data dummy.json \
| msac check -strict -
実際の生成結果も確認できる。
$ msac render \
-template examples/card.json.tmpl \
-data examples/dummy.json \
| jq '.body[0]'
{
"type": "TextBlock",
"text": "テスト環境のデプロイ完了\n担当: \"山田\"",
"wrap": true
}
msac preview で HTML を生成する
スキーマ検証だけでは、レイアウトが意図どおりかまではわからない。そこで、ブラウザで確認するための preview コマンドも追加した。
$ msac preview card.json -o preview.html
$ test -s preview.html && echo 'preview.html was generated'
preview.html was generated
生成した HTML では light/dark と desktop/mobile 幅を切り替えられる。カード単体だけでなく、Webhook の attachments[].content も順番に表示する。
render から直接つなぐ場合は以下。
msac render -template card.json.tmpl -data dummy.json \
| msac preview -o preview.html -
HTML はAdaptive Cards の公式 JavaScript SDKを利用して描画する。カードの JSON は Base64 で HTML 内に埋め込み、Action とリンクは実行しないようにしている。
ただし、これはあくまで近似表示になる。Adaptive Card は HostConfig やクライアントによって描画が変わるため、Teams 上の表示と完全には一致しない。最終確認は実際の Teams で行う必要がある。
また、生成した HTML は JavaScript SDK と Markdown processor を CDN から読み込むため、開くときにネットワーク接続が必要になる。
さいごに
個人的には、エラー箇所を JSON Pointer と周辺のオブジェクトで表示する機能が一番便利だった。Teams に実際に投稿して確認する回数を減らせるので、同じように Workflows 経由でカードを投稿している人に使ってもらえたらうれしい。
今後は実際に運用しつつ、Teams 固有の制約で拾えるものがあれば追加していきたい。