開発
Webex TeamsとAdaptive Cardsで名言集ボットを作る
shimizu

今回は「アダプティブカード」という仕組みと、それを使ったチャットボットの作例を紹介します。
アダプティブカードとは、カードの形の小さなUIコンテンツを様々なプラットフォーム間でやりとりできるようにフォーマットを定義したもので、PCやモバイル、ネイティブアプリやWebアプリを問わずデータの受け手の環境に応じて情報が適切に表示されることを目指した規格です。
例えばチャットボットに話しかけたときの応答メッセージでテキスト、画像、入力フォームなどをカード状のレイアウトに配置し、単純なテキストメッセージにとどまらないリッチなUIを提供することができます。
このアダプティブカードは、弊社がスタッフ間のコミュニケーションツールとして用いているWebex Teamsにも組み込まれており、チャットボットから送信するメッセージで利用することができます。ここでは、Webex Teams向けのボットをGoogle Apps Scriptで作成し、実際にアダプティブカードの送信と表示を試してみます。
今回は、「著名人が残した名言を投稿してくれるボット」を題材として進めていきます。
Webex for Developersサイトでボットを作成する
Cisco Webex for Developersを開きます。

画面上部の「Documentation」から「Bots」を開き、「Create a Bot」ボタンを押します。

ここでサインインを求められた場合は、Webex Teamsのアカウントでログインします。
次にボットの作成画面では、ボットの情報を記入します。ここでは以下のように記入しました。
- Bot Name: ためになる名言集ボット
- Bot Username: meigen-bot
- Icon: Default 1
- Description: ためになる名言をつぶやきます。
記入したら画面下の「Add Bot」ボタンを押します。

ボット登録が作成されると、ボットアクセストークンが表示されます。この値は後で使用しますのでコピーして控えておきます。

ボットをスペースに追加する
それでは、作成したボットがメッセージを投稿するスペースにこのボットを招待しましょう。
Webex Teamsのクライアントアプリでスペースを開き、「ユーザー」タブから「ユーザーの追加」を行い、先ほど記入した「Bot Username」を指定してメンバーに追加します。

これでボットがスペースのメンバーとして登録され、このスペースに対してメッセージを投稿することができるようになりました。

名言を投稿するスペースのIDを調べる
さて、このスペースにメッセージを送る際に、宛先としてこのスペースのIDを知っておく必要があります。スペースIDは「List Rooms」APIを使うと調べられます。
(ちなみに日本語版では「スペース」ですが、英語版表記では「Room」となりますので、両者は同じものを指しています)
List Rooms APIのリファレンスページを開くと、ここで実際にAPIをリクエストして結果を見ることができますので、「Run」ボタンを押して実行します。

すると下側に実行結果が表示されるので、その中からスペース名が一致する項目を探し、その項目のID値(スペースID)をコピーして控えておきます。

Google Apps Scriptを記述する
ここからは、コードを記述していきます。Google Apps Scriptを作成して、以下のコードをセットします。
「ボットアクセストークン(変数 botAccessToken)」と「スペースID(roomId)」には、これまでの作業で控えておいた値を入れてください。
function postByMessagesAPI() {
// ボットアクセストークン
var botAccessToken = "ボットアクセストークンの値を記入する"
// スペースID
var roomId = "スペースIDの値を記入する"
//
// 「名言教えるよ!API」からランダムに名言を取得する
//
// APIから返戻されるXMLを解釈して、名言の文章と作者名を抽出する
var quoteXml = UrlFetchApp.fetch("https://meigen.doodlenote.net/api/").getContentText()
var xmlDoc = XmlService.parse(quoteXml)
var data = xmlDoc.getRootElement().getChild('data')
var meigen = data.getChildText('meigen')
var author = data.getChildText('auther')
//
// 「Unsplash Source」からランダムに画像を取得する
//
// 一旦リダイレクトを挟むため、レスポンスに含まれるLocationヘッダーからURLを取得する
var response = UrlFetchApp.fetch("https://source.unsplash.com/featured/480x320?nature", { followRedirects: false })
var imageUrl = response.getHeaders().Location
//
// アダプティブカードの内容を作成する
//
var data = {
"roomId": roomId,
"markdown": meigen + " - " + author, // カード表示を行えないクライアントでのフォールバック表示用テキスト
"attachments": {
"contentType": "application/vnd.microsoft.card.adaptive",
"content": {
"type": "AdaptiveCard",
"version": "1.2",
// カード表示内容の定義
"body": [
// 画像表示部
{
"type": "Image",
"url": imageUrl,
"size": "Stretch"
},
// 名言文表示部
{
"type": "TextBlock",
"text": meigen,
"horizontalAlignment": "Center",
"size": "Large",
"weight": "Bolder",
"color": "Accent"
},
// 作者名表示部
{
"type": "TextBlock",
"text": author,
"horizontalAlignment": "Center"
},
],
// 末尾のアクションボタン
"actions": [
{
"type": "Action.OpenUrl",
"url": "https://meigen.doodlenote.net/",
"title": "出典:名言教えるよ!API"
}
]
}
}
}
//
// Webex Teamsのスペースにメッセージを投稿する
//
var url = "https://webexapis.com/v1/messages"
var options = {
"method": "post",
"headers": {
"Content-Type": "application/json",
"Authorization": "Bearer " + botAccessToken
},
"payload": JSON.stringify(data)
}
UrlFetchApp.fetch(url, options)
}
実行結果を確認する
このスクリプトを実行すると、このようなメッセージが投稿され、名言がカードで表示されます。トリガーを設定してタイマー実行させると、定期的に投稿されるようにすることもできますね。

表示する名言の取得には、「名言教えるよ!」のAPIを利用させていただきました。また、カードに表示する写真は「Unsplash Source」の素材を使用しています。
コードの中ほどでアダプティブカードを定義していますが、JSONデータのフォーマットでカードに表示する内容を指定することができます。また、カードのデザインツールが用意されており、スマホアプリ画面のレイアウトビルダーのようなGUIでカードを作ることができます。
アダプティブカードの仕様の詳細については、こちらの公式ドキュメントも参考にしてください。
おわりに
このアダプティブカードをサポートしているシステムの一覧によれば、(若干情報が古いですが)主にマイクロソフトの自社サービスで採用されており、それ以外ではWebex Teamsだけとなっています。今後他のサービスにも広がることで相互運用性が高まれば、開発者にとっても便利な規格になっていくはずです。
なお、チャットサービス大手のSlackはアダプティブカードはサポートせず「Block Kit」という同様の機能を持った独自の仕組みを用意しています。どのような違いがあるのか、こちらも気になるところです。
2024/09/13
2024/05/17
2024/05/10
2024/01/05
2023/08/18
2023/07/14
2023/05/12