mcpField
G
google-chat-messages

google-chat-messages

github.com/jezweb生産性1.1k1.3k 回インストール3 週間前に更新
リポジトリ

google-chat-messages について

google-chat-messagesは、Google Chatの受信Webhook経由で通知や構造化された更新を送るスキルです。テキスト、cardsV2カード、スレッド返信に対応し、メッセージの作成と送信に使えるTypeScriptユーティリティを備えています。

主な機能

  1. 01書式付きテキストメッセージの送信
  2. 02cardsV2リッチカードの作成
  3. 03スレッド返信の送信
  4. 04TypeScript Webhookユーティリティの利用

活用シーン

  1. 01デプロイ状況の通知
  2. 02週次ダイジェストカードの送信
  3. 03スレッド内でのアラート更新

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/jezweb/claude-skills --skill google-chat-messages

インストール後、Claude Code で/google-chat-messagesを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

assets/
card-builder.ts
types.ts
webhook-sender.ts

詳細

Google Chat メッセージ

受信 Webhook を通じて Google Chat のスペースにメッセージを送信します。テキストメッセージ、リッチカード(cardsV2)、スレッド返信を作成できます。

作成できるもの

  • Google Chat の書式設定に対応したテキストメッセージ
  • ヘッダー、セクション、ウィジェットを含むリッチカードメッセージ(cardsV2)
  • スレッド形式の会話
  • 再利用可能な Webhook 送信ユーティリティ

ワークフロー

ステップ 1:Webhook URL を取得する

Google Chat で:

  1. スペースを開き、スペース名をクリックして、Webhook を管理を選択します
  2. Webhook を作成します(名前を付け、必要に応じてアバター URL を追加します)
  3. Webhook URL をコピーします

URL は環境変数またはシークレットマネージャーに保存し、ハードコードしないでください。

ステップ 2:メッセージの種類を選ぶ
必要なもの種類複雑さ
シンプルな通知テキストメッセージ低
構造化された情報(ステータス、ダイジェスト)カードメッセージ(cardsV2)中
継続的な更新スレッド返信中
アクションボタン(URL を開く)buttonList を含むカード中
ステップ 3:メッセージを送信する

送信ユーティリティには assets/webhook-sender.ts を使用します。構造化カードの作成には assets/card-builder.ts を使用します。

テキストの書式設定

Google Chat では標準の Markdown は使用されません。

書式構文例
太字*text**important*
斜体_text__emphasis_
取り消し線~text~~removed~
等幅`text``code`
コードブロック```text```複数行のコード
リンク<url|text><https://example.com|こちらをクリック>
ユーザーへのメンション<users/USER_ID><users/123456>
全員へのメンション<users/all><users/all>

サポート対象外:**double asterisks**、見出し(###)、引用、表、インライン画像。

テキストメッセージの例
await sendText(webhookUrl, '*Build Complete*\n\nBranch: `main`\nStatus: Passed\n<https://ci.example.com/123|View Build>');

cardsV2 の構造

カードには cardsV2 形式を使用します(従来のカード形式より推奨)。

const message = {
  cardsV2: [{
    cardId: 'unique-id',
    card: {
      header: {
        title: 'Card Title',
        subtitle: 'Optional subtitle',
        imageUrl: 'https://example.com/icon.png',
        imageType: 'CIRCLE'  // or 'SQUARE'
      },
      sections: [{
        header: 'Section Title',  // optional
        widgets: [
          // widgets go here
        ]
      }]
    }
  }]
};

ウィジェットのリファレンス

cardsV2 のセクションで使用できるすべてのウィジェットタイプです。

textParagraph

書式設定されたテキストブロックです。Google Chat の書式設定(*bold*、_italic_、<url|text>)に対応しています。

{
  textParagraph: {
    text: '*Status*: All systems operational\n_Last checked_: 5 minutes ago'
  }
}
decoratedText

アイコンを任意で付けられるラベル付きの値です。キーと値のデータに最も汎用的なウィジェットです。

基本:

{
  decoratedText: {
    topLabel: 'Environment',
    text: 'Production',
    bottomLabel: 'Last deployed 2h ago'
  }
}

開始アイコン付き:

{
  decoratedText: {
    topLabel: 'Status',
    text: 'Healthy',
    startIcon: { knownIcon: 'STAR' }
  }
}

カスタムアイコン URL 付き:

{
  decoratedText: {
    topLabel: 'GitHub',
    text: 'PR #142 merged',
    startIcon: {
      iconUrl: 'https://github.githubassets.com/favicons/favicon.svg',
      altText: 'GitHub'
    }
  }
}

ボタン付き:

{
  decoratedText: {
    topLabel: 'Alert',
    text: 'CPU at 95%',
    button: {
      text: 'View',
      onClick: { openLink: { url: 'https://monitoring.example.com' } }
    }
  }
}

クリック可能(ウィジェット全体):

{
  decoratedText: {
    text: 'View full report',
    wrapText: true,
    onClick: { openLink: { url: 'https://reports.example.com' } }
  }
}

テキストの折り返し付き:

{
  decoratedText: {
    topLabel: 'Description',
    text: 'This is a longer description that should wrap to multiple lines instead of being truncated',
    wrapText: true
  }
}
buttonList

1 つ以上のアクションボタンです。ボタンを使用すると URL を開いたり、アクションを実行したりできます。

単一のボタン:

{
  buttonList: {
    buttons: [{
      text: 'Open Dashboard',
      onClick: { openLink: { url: 'https://dashboard.example.com' } }
    }]
  }
}

複数のボタン:

{
  buttonList: {
    buttons: [
      {
        text: 'Approve',
        onClick: { openLink: { url: 'https://app.example.com/approve/123' } },
        color: { red: 0, green: 0.5, blue: 0, alpha: 1 }
      },
      {
        text: 'Reject',
        onClick: { openLink: { url: 'https://app.example.com/reject/123' } }
      }
    ]
  }
}

アイコン付きボタン:

{
  buttonList: {
    buttons: [{
      text: 'View on GitHub',
      icon: { knownIcon: 'BOOKMARK' },
      onClick: { openLink: { url: 'https://github.com/org/repo/pull/42' } }
    }]
  }
}
image

単独で表示する画像ウィジェットです。

{
  image: {
    imageUrl: 'https://example.com/chart.png',
    altText: 'Monthly usage chart'
  }
}
divider

ウィジェット間に水平の区切り線を表示します。

{ divider: {} }
折りたたみ可能なセクション

セクションは折りたたんで、最初の N 個のウィジェットだけを表示できます。

{
  header: 'Details',
  collapsible: true,
  uncollapsibleWidgetsCount: 2,  // Show first 2, collapse rest
  widgets: [
    { decoratedText: { topLabel: 'Status', text: 'Active' } },
    { decoratedText: { topLabel: 'Region', text: 'AU' } },
    // These start collapsed
    { decoratedText: { topLabel: 'Instance', text: 'prod-01' } },
    { decoratedText: { topLabel: 'Memory', text: '2.1 GB' } },
    { decoratedText: { topLabel: 'CPU', text: '45%' } }
  ]
}

既知のアイコン

decoratedText と button ウィジェットで knownIcon を通じて使用できるアイコンです。

{ startIcon: { knownIcon: 'STAR' } }
// or
{ icon: { knownIcon: 'EMAIL' } }
アイコン名用途
AIRPLANE旅行、フライト
BOOKMARK保存、参照、リンク
BUS交通機関、公共交通
CAR運転、交通機関
CLOCK時刻、所要時間、スケジュール
CONFIRMATION_NUMBER_ICONチケット、予約
DESCRIPTIONドキュメント、ファイル
DOLLAR金銭、価格、費用
EMAILメール、メッセージ
INVITE招待
MAP_PIN場所、住所
MEMBERSHIPメンバー、ユーザー
MULTIPLE_PEOPLEチーム、グループ
OFFERセール、プロモーション
PERSON個人ユーザー
PHONE電話番号、通話
SHOPPING_CART商取引、購入
STAR評価、お気に入り、重要
STORE店舗、小売
TICKETチケット、イベント
VIDEO_CAMERA動画、会議

一覧にないアイコンには、一般公開されている任意の画像を iconUrl で使用します(正方形で、24x24 または 48x48 ピクセルが理想的です)。

スレッド

threadKey を使ってメッセージをスレッドにまとめます。

// First message — creates thread
const response = await sendCard(webhookUrl, card, {
  threadKey: 'deploy-2026-02-16'
});

// Reply to thread — append &messageReplyOption=REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD
const threadUrl = `${webhookUrl}&messageReplyOption=REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD`;
await sendCard(threadUrl, replyCard, {
  threadKey: 'deploy-2026-02-16'
});

threadKey はクライアントが割り当てる文字列です。関連するメッセージには一貫したキーを使用します(例:deploy-{date}、alert-{id})。

よく使うパターン

通知カード
import { buildCard, sendCard } from './assets/card-builder';
import { sendWebhook } from './assets/webhook-sender';

const card = buildCard({
  cardId: 'deploy-notification',
  title: 'Deployment Complete',
  subtitle: 'production - v2.1.0',
  imageUrl: 'https://example.com/your-icon.png',
  sections: [{
    widgets: [
      { decoratedText: { topLabel: 'Environment', text: 'Production' } },
      { decoratedText: { topLabel: 'Version', text: 'v2.1.0' } },
      { decoratedText: { topLabel: 'Status', text: '*Healthy*', startIcon: { knownIcon: 'STAR' } } },
      { buttonList: { buttons: [{ text: 'View Deployment', onClick: { openLink: { url: 'https://dash.example.com' } } }] } }
    ]
  }]
});
ダイジェストカード(週次サマリー)
const digest = buildCard({
  cardId: 'weekly-digest',
  title: 'Weekly Summary',
  subtitle: `${count} updates this week`,
  sections: [
    {
      header: 'Highlights',
      widgets: items.map(item => ({
        decoratedText: { text: item.title, bottomLabel: item.date }
      }))
    },
    {
      widgets: [{
        buttonList: {
          buttons: [{ text: 'View All', onClick: { openLink: { url: dashboardUrl } } }]
        }
      }]
    }
  ]
});

エラーの防止

間違い修正方法
テキスト内の **bold***bold*(アスタリスク1つ)を使用します
[text](url) 形式のリンク<url|text> 形式を使用します
cardsV2 ラッパーがないカードを { cardsV2: [{ cardId, card }] } でラップします
スレッドへの返信がスレッド化されないWebhook URL に &messageReplyOption=REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD を追加します
Webhook が 400 を返すJSON 構造を確認します。よくある原因は、トップレベルに text または cardsV2 がないことです
カードが表示されないsections にウィジェットが少なくとも1つ含まれていることを確認します

アセットファイル

ファイル用途
assets/types.tscardsV2 の TypeScript 型定義
assets/card-builder.tsカードメッセージを作成するユーティリティ
assets/webhook-sender.tsエラー処理付きで Webhook に POST します

コメント