Cloudflare Workerで構築するTelegramボット:サーバーレスメッセージング基盤の設計と実装

API,JavaScript,インフラ,コミュニケーション,セキュリティ

お疲れ様です!IT業界で働くアライグマです!

「Telegramボットを作りたいけど、サーバーの管理は面倒だな…」

チーム内の通知自動化やタスク管理のために、Telegramボットを導入したいと考えるエンジニアは多いのではないでしょうか。
しかし、従来のサーバー運用では、インフラの管理コストやスケーリングの問題がつきまといます。

そこで注目したいのが、Cloudflare Workersを使ったサーバーレスアプローチです。
Cloudflare Workersは、エッジコンピューティングを活用した超低レイテンシのサーバーレスプラットフォームで、コールドスタートがほぼゼロという特徴があります。

私自身、PjMとしてチームの通知基盤を構築する際に、Cloudflare Workers + Telegramの組み合わせを採用しました。
運用コストを大幅に削減しながら、高速で安定したメッセージング基盤を実現できています。

この記事では、Cloudflare WorkerでTelegramボットを構築する方法を、設計から実装まで解説します。

Cloudflare Workersの特徴とTelegram連携のメリット

Cloudflare Workersは、Cloudflareのエッジネットワーク上でJavaScriptを実行できるサーバーレスプラットフォームです。
従来のサーバーレスサービスと比較して、圧倒的に高速なレスポンスを実現できる点が最大の特徴です。

なぜCloudflare Workersなのか

サーバーレスプラットフォームを選ぶ際、以下のポイントで比較することが重要です。

  • コールドスタート時間:リクエスト処理開始までの遅延
  • グローバル展開:世界中のユーザーへの応答速度
  • 料金体系:リクエスト数やCPU時間に基づく課金
  • 開発体験:デプロイの容易さやデバッグ環境

Cloudflare Workersは、これらすべての点で優れたバランスを持っています。
特に、コールドスタートがほぼゼロという点は、リアルタイム性が求められるメッセージングボットにとって大きなメリットです。

Supabase Edge Functionsで構築するサーバーレスAPI設計パターンでも解説していますが、エッジコンピューティングを活用したサーバーレス設計は、現代のアプリケーション開発において重要な選択肢となっています。

分散システムデザインパターン ―コンテナを使ったスケーラブルなサービスの設計でも述べられているように、分散システムの設計では「レイテンシの最小化」が重要な要素です。
Cloudflare Workersは、この点で非常に優れた選択肢と言えます。

A modern server room featuring network equipment with blue illumination. Ideal for technology themes.

サーバーレスプラットフォームの比較

Telegramボットを構築する際、どのサーバーレスプラットフォームを選ぶべきか迷うことがあります。
ここでは、主要なプラットフォームを比較し、Cloudflare Workersの優位性を確認します。

以下では、各プラットフォームの特徴を詳しく見ていきます。

各プラットフォームの特徴

  • Cloudflare Workers:コールドスタート約5ms、グローバルエッジ展開、無料枠10万リクエスト/日
  • AWS Lambda:コールドスタート100〜200ms、豊富なAWSサービス連携、従量課金
  • Vercel Edge Functions:コールドスタート約25ms、Next.jsとの親和性、Hobbyプラン無料
  • Deno Deploy:コールドスタート約15ms、TypeScriptネイティブ、無料枠あり

Telegramボットのようなリアルタイム性が求められるアプリケーションでは、コールドスタートの速さが直接ユーザー体験に影響します。
この点で、Cloudflare Workersは最適な選択肢と言えます。

AWS Lambdaのコールドスタート最適化ガイドでも解説していますが、コールドスタートの問題は多くのサーバーレスアプリケーションで課題となっています。

ソフトウェアアーキテクチャの基礎でも述べられているように、アーキテクチャ選定では「トレードオフ」を理解することが重要です。
Cloudflare Workersは、レイテンシを最優先する場合に最適な選択肢です。

以下のグラフは、各プラットフォームのコールドスタート時間を比較したものです。
Cloudflare Workersは、他のプラットフォームと比較して圧倒的に高速であることがわかります。

サーバーレスプラットフォーム比較:コールドスタート時間

Telegramボットの基本実装

ここからは、実際にCloudflare WorkerでTelegramボットを実装する手順を解説します。
Telegram Bot APIのWebhookを使って、メッセージを受信・処理する基本的な構成を作成します。

プロジェクトのセットアップ

まず、Wranglerを使ってCloudflare Workerプロジェクトを作成します。

# Wranglerのインストール
npm install -g wrangler

# プロジェクト作成
wrangler init telegram-bot
cd telegram-bot

# TypeScriptテンプレートを選択

Telegram Bot Tokenの取得

Telegramの@BotFatherにメッセージを送り、新しいボットを作成します。
取得したBot Tokenは、Cloudflare Workersの環境変数として設定します。

# シークレットとして設定
wrangler secret put TELEGRAM_BOT_TOKEN

Webhookハンドラーの実装

Telegramからのメッセージを受信し、応答を返す基本的なハンドラーを実装します。

export interface Env {
  TELEGRAM_BOT_TOKEN: string;
}

interface TelegramUpdate {
  message?: {
    chat: { id: number };
    text?: string;
  };
}

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    if (request.method !== 'POST') {
      return new Response('Method not allowed', { status: 405 });
    }

    const update: TelegramUpdate = await request.json();
    
    if (update.message?.text) {
      const chatId = update.message.chat.id;
      const text = update.message.text;
      
      // エコーボット:受信したメッセージをそのまま返す
      await sendMessage(env.TELEGRAM_BOT_TOKEN, chatId, `受信: ${text}`);
    }

    return new Response('OK');
  },
};

async function sendMessage(token: string, chatId: number, text: string) {
  await fetch(`https://api.telegram.org/bot${token}/sendMessage`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ chat_id: chatId, text }),
  });
}

私がPjMとして関わったプロジェクトでは、この基本構成をベースに、チームの日報通知やタスクリマインダーを実装しました。
リモートチームのコミュニケーション設計でも解説していますが、非同期コミュニケーションの自動化は、チームの生産性向上に大きく貢献します。

Clean Architecture 達人に学ぶソフトウェアの構造と設計でも強調されているように、コードは「変更に強い構造」で設計することが重要です。
上記のコードは、メッセージ処理のロジックを分離しやすい構成になっています。

Focused detail of a modern server rack with blue LED indicators in a data center.

発展的な活用パターン

基本的なエコーボットができたら、より実用的な機能を追加していきましょう。
ここでは、実際のプロジェクトで役立つ発展的なパターンを紹介します。

コマンドルーティングの実装

複数のコマンドを処理するために、ルーティング機能を追加します。

type CommandHandler = (chatId: number, args: string[]) => Promise<string>;

const commands: Record<string, CommandHandler> = {
  '/start': async () => 'ボットが起動しました!',
  '/help': async () => '利用可能なコマンド:\n/start - 起動\n/status - ステータス確認',
  '/status': async () => `稼働中 - ${new Date().toISOString()}`,
};

function parseCommand(text: string): { command: string; args: string[] } {
  const parts = text.split(' ');
  return { command: parts[0], args: parts.slice(1) };
}

// メインハンドラー内で使用
const { command, args } = parseCommand(text);
const handler = commands[command];
if (handler) {
  const response = await handler(chatId, args);
  await sendMessage(token, chatId, response);
}

KVストレージとの連携

Cloudflare Workers KVを使って、ユーザーの設定や状態を永続化できます。

export interface Env {
  TELEGRAM_BOT_TOKEN: string;
  USER_SETTINGS: KVNamespace;
}

// ユーザー設定の保存
await env.USER_SETTINGS.put(`user:${chatId}`, JSON.stringify({
  notifications: true,
  timezone: 'Asia/Tokyo',
}));

// ユーザー設定の取得
const settings = await env.USER_SETTINGS.get(`user:${chatId}`, 'json');

私がPjMとして運用しているボットでは、KVストレージを使ってユーザーごとの通知設定を管理しています。
これにより、各メンバーが自分に合った通知頻度を設定できるようになりました。

Cloudflare D1でサーバーレスSQLiteを活用する方法でも解説していますが、Cloudflareのストレージサービスは、サーバーレスアプリケーションとの相性が非常に良いです。

ゼロトラストネットワーク[実践]入門でも述べられているように、セキュリティを考慮した設計は重要です。
Bot Tokenは必ず環境変数として管理し、コードにハードコードしないようにしましょう。

Closeup of many cables with blue wires plugged in modern switch with similar adapters on blurred background in modern studio

まとめ

Cloudflare Workerを使ったTelegramボットの構築方法を解説しました。

この記事で解説した内容を振り返ると、以下のポイントが重要です。

  • Cloudflare Workersの優位性:コールドスタートがほぼゼロで、リアルタイム性が求められるボットに最適
  • 基本実装:Webhook方式でメッセージを受信し、Telegram Bot APIで応答を返す
  • コマンドルーティング:複数のコマンドを処理するためのルーティング機能を実装
  • KVストレージ連携:ユーザー設定や状態を永続化してパーソナライズを実現

まずは基本的なエコーボットから始めて、徐々に機能を追加していくのがおすすめです。
Cloudflare Workersの無料枠は1日10万リクエストと十分な量があるので、個人プロジェクトやチーム内ツールとして気軽に試せます。

厳しめIT女子 アラ美による解説ショート動画はこちら