【Python】Webhookで簡単にGoogle Chatにメッセージを送る

技術

Webhookって?

Webhookとはアプリケーションで発生したイベントをリアルタイムに外部へ通知する概念のことです。

Google ChatにはIncomming Webhookと呼ばれる、URLを公開して外部からメッセージが投稿できる仕組みがあります。

ただ、残念ながら無料のGoogleアカウントでは使えないみたいですね。有料のGoogle Workspaceアカウントでないと使えないらしいです。

Webhookが使えないとなると、SDKを使うか、Rest APIを使うことになるわけですが、どちらにしてもGoogle Cloud Platformにサービスアカウントを事前に作っておく必要があってちょっと面倒です。

Webhookが使えれば非常に簡単にメッセージを投稿できます。
簡単すぎて拍子抜けするほどかも(^^;)

まずはWebhook URLを作る

Google Chatへアクセスして、メッセージを投稿したいスペース、または会話を開きます。
https://mail.google.com/chat/

ページ左上のスペース名(または会話相手のユーザー名)のところをクリックして、「Webhookを管理」を選択します。
※無料のGoogleアカウントだとこの「Webhookを管理」というメニューがありません。

Webhookの名前を適当に決めて[保存]したら、WebhookのURLが表示されるのでコピーしておきます。

CURLで投稿してみる

windows10 以降なら標準でインストールされているcurlを使ってGoogle Chatへ投稿してみます。

curl -X POST -H "Content-Type: application/json" -d "{'text':'hello webhook!'}" {Webhook URL}

メッセージは{Webhook URL}へ[JSON]を[POST]することで投稿できます。

curlでPOSTする場合-X POSTを付けます。
POSTするデータをJSONにする場合は
-H "Content-Type: application/json" -d "{JSON}"
で指定します。

これだけでメッセージを投稿できちゃいます。
簡単ですね・・・と思ったら。
あら、失敗しちゃいました。

{
  "error": {
    "code": 403,
    "message": "The API is called without a valid token. Instructions on how to use incoming webhooks can be found at https://developers.google.com/chat/how-tos/webhooks",
    "status": "PERMISSION_DENIED"
  }
}

こちらの記事に解決方法が書いていました。
https://kntmr.hatenablog.com/entry/2020/03/11/140000

よく見るとWebhook URLにCMDとして意味のある「&」「%」が含まれていたんですね。

https://chat.googleapis.com/v1/spaces/{space id}/messages?key={key}&token=aKs3qXN・・・5ByM-U6%3D

&token=は2つ目のクエリパラメータ「token」を指定するためのもので「^&token=」とすることでエスケープできます。
%3Dはtokenの値に含まれる「=」がURLエンコードされたもので「%%3D」とすることでエスケープできます。

エスケープして実行しなおしてみると、無事投稿できました。

Pythonで投稿してみる

次はPythonでメッセージを投稿してみます。

Pythonのバージョンは 3.9.6 です。3系ならOKでしょう。
Requests を使うので入ってなければ入れます。

pip install requests

pythonなので、投稿するコードを書くだけじゃなくてクラスを作ってみました。

import requests

class GoogleChat:
    def __init__(self, url) -> None:
        self.chatUrl = url

    def postText(self, text):
        requests.post(self.chatUrl, json = { 'text': text })

    def postCard(self, title, widgets):
        requests.post(
            self.chatUrl,
            json = {
                'cards': [
                    {
                        'header': {
                            'title': title,
                            # 'subtitle': subtitle,
                        },
                        'sections': [{'widgets': widgets}],
                    }
                ]
            }
        )

GoogleChatクラスのコンストラクタで{Webhook URL}を受け取っています。
メソッドはpostTextpostCardという2つ。

postTextの方はcurlでやったのと同じことをpythonで実行しているだけです。
postCardはカード形式のメッセージを投稿するもので、より複雑なUIのメッセージが投稿できます。

カード形式についてはこちらでもっと詳しく知ることができます。

GoogleChatクラスの使い方はこんな感じ。

from google_chat import GoogleChat

# {Webhook URL}を指定してGoogleChatインスタンスを生成
chat = GoogleChat("https://chat.googleapis.com/v1/spaces/XXXXXXXXX/messages?key=XXXXXXXXXXX&token=XXXXXXXXXXXXX")

# テキストメッセージを投稿
chat.postText("Webhook hello!")

# Widgetを投稿
widgets = [
  {
    'textParagraph': { 'text': "<a href='https://www.google.co.jp/'>Google</a>" }
  }
]
chat.postCard("Webhook hello!", widgets)

postCardメソッドにはWidgetという形でオブジェクトを指定しています。

今回はシンプルなTextParagraphウィジェットを投稿するように実装してみました。
TextParagraphはhtmlタグを含めたテキストを投稿できるウィジェットです。

何も問題なく投稿できちゃいました。

ということで・・・

今回はGoogle ChatへIncoming Webhookの仕組みを使ってメッセージを投稿してみました。
複雑な認証も必要なくてあっけないくらいに簡単にできてしまいました。

無料のGoogleアカウントでは使えないというのが残念ですが、Google Workspaceを使っている方はぜひやってみてください。

最近は Slack やら ChatWork やら、その他グループウェアが乱立していて、しかも相手に合わせて使い分けないといけないことが多いです。
Webhookの仕組みを利用してGoogle Chatに情報を集約させたら、ちょっと便利になるかもしれません。

コメント

タイトルとURLをコピーしました