前回試した新手順でアダプティブカードという形式でメッセージ送信をしていました。
Webhookの投稿者を指定することができなさそう?な雰囲気だったのですが、アイコンの設定などをある程度自由にやりたいなと思ってのメモです。
こんな雰囲気の投稿を作ります。
Adaptive Cardの設定
この辺りを参考にしつつ
作ったJSONオブジェクト
const payload = {
"attachments": [
{
"contentType": "application/vnd.microsoft.card.adaptive",
"content": {
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"version": "1.5",
"body": [
{
"type": "ColumnSet",
"columns": [
{
"type": "Column",
"items": [
{
"type": "Image",
"style": "Person",
"url": "https://avatars.githubusercontent.com/u/2968926?v=4",
"size": "Small"
}
],
"width": "auto"
},
{
"type": "Column",
"spacing": "medium",
"verticalContentAlignment": "center",
"items": [
{
"type": "TextBlock",
"weight": "Bolder",
"text": "のびすけ",
"wrap": true
}
],
"width": "auto"
},
{
"type": "Column",
"spacing": "medium",
"items": [
{
"type": "TextBlock",
"text": "xxxxの質問",
"isSubtle": true,
"wrap": true
}
],
"width": "stretch",
"verticalContentAlignment": "center"
}
]
},
{
"type": "TextBlock",
"text": "## Workflow経由のTeamsへの通知テストです。\n\n* 通知の詳細1です。\n* 通知の詳細2です。",
"wrap": true,
"markdown": true
}
],
"actions": [
{
"type": "Action.OpenUrl",
"title": "質問ページを見てみる",
"url": "https://github.com/your-repo/issues/1",
"iconUrl": "icon:People,filled"
}
]
}
}
]
};
使ってるツール
- 画像
画像はtypeにImageを指定してurlに画像URLを指定します。
{
"type": "Image",
"style": "Person",
"url": "https://hogehoge.com/hoge.png",
"size": "Small"
}
- レイアウト
CulumnSetを指定して使います。何もしないと下の段(行)に要素が描画されますが、このCulumnSetを使うと横に並べることができます。
"(画像)"、"n0bisukeさんのコメント"、"PEO/PEH/PMV/PERクラス質問場所コメント25件"の3つの要素が横に並んでます。
{
"type": "ColumnSet",
"columns": [
{
1列目の要素
},
{
2列目の要素
},
{
3列目の要素
}
]
}
- アクション
先ほどの画像で下の段に"質問ページを見てみる"というボタンがありますがこれの作り方です。
"actions": [
{
"type": "Action.OpenUrl",
"title": "質問ページを見てみる",
"url": target_url,
"iconUrl": "icon:People,filled"
}
]
ユーザーに何かしらアクションさせるボタンを作る機能みたいですね。
旧バージョンからのマイグレーション
これらを踏まえて旧バージョンとの比較です。
const postData = {
'@type': 'MessageCard',
themeColor: '0076D7',
summary: 'ディスカッション',
sections: [{
activityTitle: title,
activitySubtitle: discussion.title,
facts: [{
name: '投稿者',
value: sender.login
}, {
name: 'URL',
value: target_url
}, {
name: '本文',
value: description
}],
markdown: true
}]
}
従来はfactsって要素の配列に色々入れてた模様です。
アダプティブカード形式にしてみる
以前書いた記事にある記載がこちらです。
const payload = {
attachments: [
{
contentType: 'application/vnd.microsoft.card.adaptive',
content: {
$schema: 'http://adaptivecards.io/schemas/adaptive-card.json',
type: 'AdaptiveCard',
version: '1.2',
body: [
{
type: 'TextBlock',
text: '## Workflow経由のTeamsへの通知テストです。\n\n* 通知の詳細1です。\n* 通知の詳細2です。',
wrap: true,
markdown: true
}
]
}
}
]
};
従来は{}
の中にキーを色々書いてましたが、{attachments:[]}
に全て入れ込むっぽいですね。
真似してみる
const postData = {
"attachments": [
{
"contentType": "application/vnd.microsoft.card.adaptive",
"content": {
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"version": "1.5",
"body": [
{
"type": "ColumnSet",
"columns": [
{
"type": "Column",
"items": [
{
"type": "Image",
"style": "Person",
"url": sender.avatar_url,
"size": "Small"
}
],
"width": "auto"
},
{
"type": "Column",
"spacing": "medium",
"verticalContentAlignment": "center",
"items": [
{
"type": "TextBlock",
"weight": "Bolder",
"text": `${sender.login}さんのコメント`,
"wrap": true
}
],
"width": "auto"
},
{
"type": "Column",
"spacing": "medium",
"items": [
{
"type": "TextBlock",
"text": `${categoryName} ${commentCount}`,
"isSubtle": true,
"wrap": true
}
],
"width": "stretch",
"verticalContentAlignment": "center"
}
]
},
{
"type": "TextBlock",
"text": `[${firstLabel}] ${description}`,
"wrap": true,
"markdown": true
}
],
"actions": [
{
"type": "Action.OpenUrl",
"title": "質問ページを見てみる",
"url": target_url,
"iconUrl": "icon:People,filled"
}
]
}
}
]
};
こんな感じでうまくいきました。
おまけ: Fetchで出たエラー
昔のコードがaxiosを使ってましたが、Fetchに切り替えた際エラーが発生していました。
Error: Error: SyntaxError: Unexpected end of JSON input
at module.exports (/Users/n0bisuke/ds/3_project/protobot/server/github/discussion/qa.js:51:19)
at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
at async module.exports (/Users/n0bisuke/ds/3_project/protobot/server/github/discussion/index.js:70:13)
以下のように書いていたのですが、TeamsのAPIはレスポンスが何もないっぽい雰囲気で実行後のresponse.json()
でパースエラーが発生してしまう模様でした。
try {
const response = await fetch(webhook_url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(postData)
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json();
} catch (error) {
throw new Error(error);
}
response.json()
をresponse.text()
に書き換えたらエラー解消されました。
try {
const response = await fetch(webhook_url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(postData)
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const text = await response.text();
console.log(`Teamsへの送信に成功しました: ${text}`);
return text;
} catch (error) {
throw new Error(error);
}