AIイノベーションズ ブログ

TelegramでWebhookを受け取る方法

最終更新日:
阿部隼也
阿部 隼也
AIイノベーションズ 代表取締役社長 | x.com/ai_abe_shunya
リアルタイムアンケートツール: LiveQ

お悩み相談AIチャット: AI相談.com

Telegramは、メッセージングアプリとしてだけでなく、Botを活用した自動化ツールとしても人気があります。

日本ではTelegramは犯罪に使われるものというイメージが先行してしまいましたが、個人的にはLINEよりも圧倒的に使いやすいうえに、SlackよりもWebhook通知がカンタンなので気に入っています。

特にWebhookを使うと、外部のアプリからTelegramにリアルタイムで通知を送れるので、開発者にとって便利です。

たとえば、重要な操作の通知や、エラーログの通知を即座に共有したいときに便利です。

この記事では、TelegramのBotを作成し、Webhookを設定してメッセージを受け取る基本的な流れを一緒に確認していきましょう。

実際に手を動かしながら進められるように、具体的な手順を詳しく説明します。準備はTelegramアプリとブラウザがあればOKです。

Botを作成する

まずは、Telegram上でBotを作成する必要があります。

TelegramでWebhookを受け取るためには、Botを作成して、そのBotに、指定したチャットルームでメッセージを投稿させるという流れが必要になるからです。

Telegramには「BotFather」という専用の公式アカウントがあるので、これを使って新しいBotを簡単に作れます。God Fatherから来たのでしょうが、公式とは思えない名前なので最初は困惑しますが。

とはいえBotFatherはBotの管理を一手に引き受けてくれる頼もしい存在です。

BotFather

手順はシンプルです。Telegramアプリを開いて、検索バーに「BotFather」と入力して探します。

公式のBotFather(@BotFather)を選んで、スタートメッセージを送りましょう。すると、コマンド一覧が表示されます。

(ここからはTelegramのデスクトップアプリであれば Open というボタンをクリックするともっとラクにBotが作成できたりしますが、ここではBotとの対話を通してBotを作成します。)

ここで/newbotコマンドを入力します。Botの名前を尋ねられるので、たとえば「MyNotificationBot」のように、わかりやすい名前を付けます。

次に、Botのユーザー名(Twitterでいうハンドル名)を決めます。

これは「@」で始まり、「bot」で終わるものにしなければなりません。例えば「@my_notification_bot」といった感じです。

これでBotが作成され、APIトークンが発行されてメッセージで送られてきます。

このトークンはBotを制御するための鍵のようなもので、絶対に他人に漏らさないように注意してください。

トークンはコピーして、安全な場所に保存しましょう。以降、このトークンを使ってBotにメッセージを送ったり、Webhookを設定したりします。

チャットグループを作成する

Botができたところで、次はWebhookで受け取ったメッセージを投稿するための場所を用意します。

ここでは、「チャットグループ」を作成するのがおすすめです。

チャットグループとは、LINEのトークルームのようなものです。

Telegramで新しいグループを作るには、アプリのメニューから「New Group」もしくは「新しいグループ」を選択します。

参加者を追加して、グループ名を決めましょう。

たとえば「Webhook」という名前にしても良いでしょう。

グループを作成したら、Botを招待します。グループのメンバーリストからBot名で検索先ほど作成したBotのユーザー名(@my_notification_botなど)を検索して追加してください。

これでBotがグループに参加しました。

Webhookを受け取る(あなたのアプリから送信する)方法

これで基盤が整いました。

最後に、あなたのアプリからWebhookを送信して、Telegramにメッセージを届ける方法です。

Webhookとは、HTTPリクエストを使って外部サービスに通知を送る仕組みで、ここではTelegramのBot APIを利用します。

まず、TelegramのBot APIドキュメントを参考に、sendMessageエンドポイントを使います。

URLは https://api.telegram.org/bot<YOUR_BOT_TOKEN>/sendMessage となります。

<YOUR_BOT_TOKEN>には先ほど取得したトークンを入れます。その前にはbotというprefixが必要です。

リクエストボディには、JSON形式でchat_idtextを指定します(必須パラメータ)。

chat_id はチャットグループのIDですが、取得方法はちょっとだけ面倒です。

chat_id の取得方法

chat_idはグループのIDで、たいていチャットグループのIDには - が付きます。 たとえば -100123456789 のように。

chat_id を取得するには、Botをグループに追加した後、そのグループに1件メッセージを送ると、getUpdates APIで取得できます。これにはBotのAPIトークンが必要となります。

URLは https://api.telegram.org/bot<YOUR_BOT_TOKEN>/getUpdates となります。

<YOUR_BOT_TOKEN>には先ほど取得したトークンを入れます。その前にはbotというprefixが必要です。

普通にブラウザでURLにアクセスしても良いです。そのなかの chat -> id を探してコピーしてください。

curlコマンドであれば以下のように実行すると、chat id だけ取得できてラクです。

curl -s -X POST https://api.telegram.org/bot<YOUR_BOT_TOKEN>/getUpdates \
  | jq -r '.result[] | (.message.chat.id // .my_chat_member.chat.id // empty)' \
  | sort -u

ブラウザの閲覧履歴などにAPIトークンが残ってしまうので、本来は上記のようにPOSTリクエストするほうが安全でしょう。

Webhook送信の実装例

あなたのアプリ側の実装例として、Node.jsを使ってみましょう。以下のようなコードでHTTPリクエストを送れます。

async function sendToTelegram(message) {
  const token = 'YOUR_BOT_TOKEN';
  const chatId = 'YOUR_CHAT_ID';
  const url = `https://api.telegram.org/bot${token}/sendMessage`;
 
  try {
    const response = await fetch(url, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        chat_id: chatId,
        text: message
      })
    });
 
    if (!response.ok) {
      throw new Error(`HTTPエラー: ${response.status}`);
    }
 
    console.log('メッセージを送信しました');
  } catch (error) {
    console.error('送信エラー:', error);
  }
}
 
// 使用例
sendToTelegram('こんにちは!Botからのメッセージです!');

このコードをアプリに組み込めば、イベントが発生したときにsendToTelegramを呼び出せます。たとえば、Webhookを受け取るサーバー側でエラーが起きたら、自動で通知を送る、といった使い方が可能です。

最初はAPIのレスポンスを確認しながら調整すると安心です。うまくいけば、アプリとTelegramが連携して、リアルタイム通知が実現します。

Node.js での補足

Node.jsでfetchメソッドを使う場合、以下のように IPv4 を固定接続しないとローカルでTelegramに拒否される可能性があります。

ただの 500 Server Error で返ってくるので、何なのか分かりませんでしたが、調べると同様の人がいたので何とか解決しました。

ちなみに私はWindowsのWSL2で開発しているときに、このエラーが発生していました。

もしエラーばかり発生する場合にはこれを試してみてください。

import dns from "node:dns";
import { Agent, setGlobalDispatcher } from "undici";
 
// IPv4 固定接続のための undici エージェント。
const TELEGRAM_FETCH_AGENT = new Agent({
  connect: {
    lookup(hostname, options, callback) {
      return dns.lookup(hostname, { ...options, family: 4 }, callback);
    },
  },
});
 
setGlobalDispatcher(TELEGRAM_FETCH_AGENT);

ローカルで送れてもデプロイ後はダメ、ということもありましたので、ちゃんと慎重にチェックする必要があります。私はリトライ処理を追加しています。

まとめ

TelegramのWebhookを設定するのは、最初は手順が多くて悩みますが、一度覚えてしまえばあとはラクです。

Slackだと個人用に課金したくないなどの悩みがあったり、LINEではこういうサービスはどんどん縮小傾向にありますから、Telegramはこういうのがあって便利ですね。

リアルタイムアンケートツール: LiveQ

お悩み相談AIチャット: AI相談.com