Web開発
Telegram Serverless
Telegram Serverless (core.telegram.org)
要約
Telegramは、ボットやミニアプリのバックエンドコードをTelegramインフラストラクチャ上で直接実行できる「Telegram Serverless」を発表しました。これにより、サーバーのプロビジョニング、コンテナの維持、スケーリングの心配が不要になります。開発者はプレーンなJavaScriptモジュールを記述し、単一コマンドでデプロイするだけで、Telegramが高速で隔離されたV8サンドボックス内でコードを実行します。データベースやBot APIへのアクセスも組み込まれており、開発ワークフローを大幅に簡素化します。
全文翻訳
Telegram Serverless
Telegram Serverlessを使用すると、ボットやミニアプリのバックエンドコードをTelegramのインフラストラクチャ上で直接実行できます。サーバーのプロビジョニング、コンテナの維持、スケーリングの心配は一切不要です。プレーンなJavaScriptモジュールを記述し、単一のコマンドでデプロイするだけで、Telegramは高速で隔離されたV8サンドボックス内でコードを実行します。このサンドボックスは、Bot APIと組み込みデータベースのすぐ隣に配置されています。もし、/startに応答するためだけにボットをVPS、クラウドファンクション、またはホスティングパネルに接続したことがあるなら、それはもう不要になります。
このページについて
なぜサーバーレスなのか
はじめに
AIとの連携
BotFatherとの連携
プロジェクトとモジュール
データベース
SDK
CLIリファレンス
なぜサーバーレスなのか
Telegramボットは、本質的にはアップデートに反応するプログラムです。従来は、そのプログラムを常に稼働しており、到達可能で、安全な場所にホストし、それを維持する必要がありました。Telegram Serverlessはこのレイヤーを完全に削除します。
インフラストラクチャ不要。
レンタル、パッチ適用、監視が必要なマシンはありません。コードはオンデマンドで実行され、ボットのトラフィックに合わせて自動的にスケーリングします。
バッテリー付属。
Telegram Bot API、SQLiteベースのデータベース、およびアウトバウンドHTTPは、すべてのモジュールで標準で利用可能です。インストールするものはなく、接続する認証情報もありません。
高速で隔離された実行。
各呼び出しは軽量なV8アイソレートで実行され、Telegram自身のシステムに近い位置にあるため、Bot APIやデータベースへの呼び出しは迅速かつ信頼性が高くなります。
真の開発ワークフロー。
プロジェクトは、バージョン管理下にあるローカルマシン上のフォルダに存在します。ファイルを編集し、変更された内容を正確に確認し、アトミックにデプロイし、レビュー済みのマイグレーションでデータベーススキーマを前方展開します。これは、他のすべてで既に行っている方法です。
メンタルモデル
3つの場所で作業し、それらは互いにきれいにマッピングされます。
場所
そこにあるもの
プロジェクトフォルダ
JavaScriptモジュール — スキーマ、共有コード、アップデートハンドラー
クラウド
モジュールのデプロイされたコピー、およびボットのデータベース
tgcloud CLI
ブリッジ — 違いを表示し、同期します
SSHで何かに接続することはありません。ローカルでファイルを編集し、npx tgcloud push を実行すると、プラットフォームがそれ以降を処理します。ボットのトラフィックはデプロイされたモジュールによって処理され、データベースは呼び出し間で永続化されます。
プロジェクトには3種類のコードしかありません。
handlers/ # エントリーポイント — Telegramアップデートタイプごとに1つのファイル
lib/ # どこからでもインポートする共有モジュール
schema.js # データベーステーブル
アップデート(メッセージ、ボタンのプレス、インラインクエリ)が到着すると、Telegramはそれを一致するハンドラー(handlers/message.js, handlers/callback_query.js, …)にルーティングし、そのデフォルトエクスポートを呼び出します。その関数はSDKを通じてBot APIとデータベースと通信し、値を返します。それが全体のループです。一致するハンドラーのないアップデートは単に無視されるため、必要なハンドラーのみを追加します。
クイックデモ
以下は、完全な動作デモボットです。すべてのメッセージに応答し、各チャットから受信したメッセージの数を記憶します。
```javascript
schema.js
import { table, integer } from 'sdk/db';
export const counters = table('counters', {
chatId: integer('chat_id').primaryKey(),
seen: integer('seen').notNull().default(0),
});
handlers/message.js
import { api, db } from 'sdk';
import { counters } from 'schema';
import { sql } from 'sdk/db';
export default async function (message) {
const chatId = message.chat.id;
// カウンターを挿入するか、このチャットが既に持っている場合はインクリメントし、
// 同じステートメントで .returning() を介して結果の行を取得します。
const [row] = await db.insert(counters)
.values({ chatId, seen: 1 })
.onConflictDoUpdate({
target: counters.chatId,
set: { seen: sql`${counters.seen} + 1` },
})
.returning()
.run();
await api.sendMessage({
chat_id: chatId,
text: `Hello! I've seen ${row.seen} message(s) from you.`,
});
}
```
デプロイ:
npx tgcloud push # モジュールをアップロード
npx tgcloud migrate # `counters` テーブルを作成
これで、永続的な状態を持つサーバーレスのライブボットが完成しました。これに含まれるすべて(api、db、table() DSL)は、以下のセクションで説明されています。
Serverlessは、Telegramボットおよびミニアプリ向けの汎用バックエンドであり、特定の種類のアプリのテンプレートではありません。以下のような用途に最適です:
会話型AIボット。データベースにユーザーごとの状態を保存する必要があるボット。
ミニアプリのバックエンド。ユーザーデータを保存し、動的なコンテンツを提供するもの。
ゲームとツール — リーダーボード、クイズなど。
サードパーティのHTTP APIを呼び出し、結果をチャットにプッシュする自動化と統合。
はじめに
このチュートリアルでは、空のフォルダからメッセージに応答し、データを保存するライブボットを作成するまでの手順を説明します。Node.js 18以降がインストールされており、@BotFatherでボットが登録されていることを前提としています。最後までには、毎日使用するすべてのコマンド(push, migrate, run, status)を使用することになります。
まず、Serverlessをオンにします。@BotFatherで、ボットを開き → Serverless を選択してオンにします。これにより、このボットの機能がオンになり、CLIアクセスキー、ハンドラー、ライブラリ、データベースへのアクセスが有効になります。
1. プロジェクトを作成する
最も簡単な開始方法は、プロジェクト作成ツールを使用することです。これにより、プロジェクトの雛形が作成され、CLIがインストールされます。
npm create @tgcloud/bot example_bot
cd example_bot
引数はターゲットフォルダです。現在のフォルダに雛形を作成するには `.` を渡すか、任意のパスを指定します。既存のフォルダでも機能し、既に存在するファイルは上書きしません。
これにより、すぐに編集できるプロジェクトが作成されます。
example_bot/
├─ docs/
│ └─ tgcloud-sdk.md # SDKリファレンス(あなたとあなたのAIコーディングアシスタント用)
├─ handlers/
│ └─ message.js # スターターメッセージハンドラー(テキストをエコーバックします)
├─ lib/ # 共有モジュールはここに置きます(最初は空)
├─ AGENTS.md # AIコーディングアシスタント向けのガイダンス
├─ package.json
└─ schema.js # データベーステーブル
雛形化されたファイルは自己文書化されており、各ファイルには次に何ができるかのコメント付き例が含まれています。CLIはプロジェクトのローカル開発依存関係としてインストールされるため、npx tgcloud <command>(npx はプロジェクトの node_modules 内のコピーを見つけます)または、雛形がpackage.jsonに追加するnpm runショートカット(npm run deploy, npm run status)を通じて実行します。デフォルトでは、PATHにグローバルなtgcloudはありません。代わりに、どこからでもプレーンなtgcloudを入力できるように、グローバルにインストールすることもできます(npm install -g @tgcloud/cli)。これは、任意の空のフォルダでtgcloud init を実行するのに便利で、シェルタブ補完に必要なものです。どちらの方法でも同じプロジェクトが得られます。
2. ボットをリンクする
各プロジェクトは1つのボットに紐付けられます。ログインを使用して接続します。これにより、CLIアクセスキー(@BotFather → あなたのボット → Serverless → CLI Access → Access token — ボットのAPIトークンとは別のトークン)が求められ、ローカルに保存されます。
npx tgcloud login
トークンは app<id>:<secret> の形式です。CLIはそれを .tgcloud/ に保存し、gitから除外され、シークレット部分は決して表示しません。ログインは、トークンが要求される唯一の機会です。CIでのトークンの解決方法については、認証を参照してください。
3. 状況を確認する
2つのコマンドで、いつでも状況を確認できます。どちらも完全にオフラインで実行できます。
npx tgcloud status # ローカルとデプロイされたコピーとの差分
npx tgcloud diff # 行ごとの変更点
初期化直後はすべてが新しく、何もデプロイされていません。status はアップロード待ちのスターターファイルを表示します。
4. デプロイする
モジュールをクラウドに送信します。
npx tgcloud push
push は、変更されたすべてのモジュールを1つのアトミックなバッチでアップロードし、クラウドが現在保持しているもののローカルレコードを更新します。ボットはライブです。ボットをTelegramで開き、メッセージを送信すると、スターターハンドラーがそれをエコーバックします。デプロイはデータベースに一切触れません。コードのプッシュとデータベーススキーマの変更は意図的に別々のステップになっているため、コードのデプロイがデータマイグレーションであなたを驚かせることは決してありません。それが次のステップの目的です。
5. データベーステーブルを追加する
ボットに何かを記憶させましょう。schema.js を開き、テーブルを宣言します。
```javascript
import { table, integer, text, sql } from 'sdk/db';
export const messages = table('messages', {
id: integer('id').primaryKey({ autoIncrement: true }),
chatId: integer('chat_id').notNull(),
text: text('text'),
created: integer('created_at', { mode: 'timestamp' }).default(sql`(unixepoch())`),
});
```
デプロイする