はじめに
Pabal の紹介
Pabal とは何か、どのように構成されているか、今できることとまだできないこと。
Pabal とは
擺撥(パバル、파발)は、朝鮮時代に馬を乗り継ぎながら急ぎの知らせを走り継いだ駅站の制度です。Pabal.me はその名を取ったメッセンジャーで、組織やコミュニティが自前のサーバーで運用する Telegram 互換のメッセンジャーです。
- サーバーを自分で運用します。アカウント・会話・写真はすべて、運営者のサーバーとデータベース(PostgreSQL)に保存されます。サーバープログラムの名前は HunsTelegram(Java 21)です。
- Telegram と同じ言葉を話します。アプリとサーバーの間は Telegram と同じ MTProto 2.0(レイヤー 216)、ボットとサーバーの間は Telegram と同じ HTTP Bot API です。そのため、Telegram 用に作られたアプリ・ライブラリ・ボットが、アドレスを変えるだけで Pabal に接続できます。
- Telegram とはつながっていない、別の世界です。Pabal のアカウントは Pabal サーバーにしか存在せず、Telegram のユーザーとメッセージをやり取りすることはできません。
どのように構成されているか
図の説明
- 3 つの領域:左はサーバーの外で動くもの(アプリ・ボットプログラム・ブラウザー)、中央はサーバーの 2 つの入口、右はサーバーの内部です。ボットプログラムもサーバーの外、運営者や開発者のコンピューターで動きます。
- 入口は 2 つだけです:アプリは MTProto ポート(8443)に直接接続し(MTProto 自体が暗号化するため HTTPS は不要)、Web サイトと Bot API は HTTPS(443)から入ります。
- ボットは 2 つの経路のどちらかで接続します:通常は HTTPS の Bot API(実線)ですが、必要ならアプリと同じ MTProto(青い点線)でも接続できます。どちらでも同じボットアカウント・同じメッセージボックスです。
- 赤い点線は逆向きに進む唯一の矢印です:ボットが Webhook を設定すると、サーバーがボットプログラムの HTTPS アドレスに新着を送ります。それ以外はすべて、外からサーバーに入ってくるリクエストです。
- 記録は 1 か所です:すべての変更はサービスを経て PostgreSQL のイベントストアに残り、写真の原本だけをファイルとして置きます。アプリから送ったメッセージも、ボットが送ったメッセージも同じ経路を通るため、プッシュ・会話一覧・再接続時の復旧がすべてに同じように適用されます。
今できること、まだできないこと
| 機能 | 状態 | メモ |
|---|---|---|
| 登録・ログイン(電話番号 + コード) | 対応 | コードは SMS・メール・管理者による伝達から運営者が選ぶ |
| 1:1 の会話、リアルタイム受信、複数端末 | 対応 | 電源が切れていた端末は、再び起動すると見逃した分に追いつく |
| メッセージの編集・削除 | 対応 | 相手の画面にもすぐ反映 |
| 基本グループ(作成・メンバーの追加・削除・名前) | 対応 | メンバーはグループ情報から直接追加 |
| 写真の送信、プロフィール写真 | 対応 | 原本の 1 サイズのみ保存 |
| ボット — @BotFather、HTTP Bot API、Webhook、MTProto ボット | 対応 | ボタン・コールバック・コマンドメニュー・写真・グループ |
| 管理画面、運用設定 | 対応 | サーバーの 127.0.0.1 でのみ開く |
| Web サイト(10 言語)、ユーザー名・招待リンクのページ | 対応 | 開発者ドキュメントも 10 言語 |
| チャンネル、スーパーグループ | 未対応 | アプリで正しく表示されないことがある |
| 文書・動画・音声ファイル、アルバム | 未対応 | 送ると MEDIA_INVALID で拒否される |
書式付きテキスト(太字・斜体)、ボットの parse_mode | 未対応 | 文字どおりに送られる。コマンド・メンション・リンク・ハッシュタグは自動で表示 |
| 音声・ビデオ通話、シークレットチャット | 未対応 | |
| 2 段階認証(クラウドパスワード) | 未対応 | 設定しようとしても拒否される |
| スマートフォンアプリ、プッシュ通知 | 未対応 | 現在は macOS デスクトップアプリのみ |
| 招待リンクでグループに参加 | 未対応 | リンクは作成できるが、押してもメンバーにならない |
インラインモード(@ボット 検索語)、決済、ゲーム | 未対応 |
Telegram との関係
Pabal は、Telegram の公開されたプロトコルに従う独立したサーバーです。Telegram 社とは関係がなく、Telegram のサーバーに接続することもありません。
- 互換性があるもの:MTProto 2.0(4 種類のトランスポート、ハンドシェイク、一時キーのバインド)、レイヤー 216 のリクエスト・レスポンス形式、HTTP Bot API のアドレス形式・リクエスト・レスポンス・エラー形式。公式の Telegram Desktop 6.2.6 を改変せずに(サーバーアドレスと公開鍵だけを変えて)接続し、確認しました。
- 異なるもの:アカウントとデータはサーバーごとに別々です。ユーザー ID・メッセージ ID・ファイル ID は、このサーバーの中でのみ意味を持ちます。Telegram で使っていたボットトークンは使えず、Pabal の @BotFather から新しく受け取る必要があります。
リンクの形式
アプリとサーバーは https://pabal.me/ でリンクを作ります。ブラウザーで開くと、アプリを開くための小さなページが表示されます。
| リンク | 意味 | アプリで開くアドレス |
|---|---|---|
pabal.me/<ユーザー名> | 人やボットとの会話を開く | tg://resolve?domain=<ユーザー名> |
pabal.me/+<招待コード> | グループの招待リンク(アプリは開くが、リンクからの参加はまだできない) | tg://join?invite=<招待コード> |
pabal.me/joinchat/<招待コード> | 以前の形式の招待リンク(意味は同じ) | tg://join?invite=<招待コード> |
ユーザー名は、英字で始まる英字・数字・アンダースコアの 5〜32 文字です(ボットは bot で終わる)。docs、admin、health のようにサイトが使うパスと同じ名前は、リンクでは開けません。
セキュリティモデル
- アプリ ↔ サーバー:MTProto 2.0 で暗号化されます。アプリはサーバーの RSA 公開鍵を組み込んでビルドされるため、別のサーバーが Pabal サーバーになりすますことはできません。会話は Telegram の「クラウドチャット」と同じで、サーバーは内容を読むことができます(エンドツーエンド暗号化ではありません)。信頼できる人がサーバーを運用しなければならないのはこのためです。
- ボット ↔ サーバー:Bot API は HTTPS でのみ公開します。ボットトークンはボットのパスワードです — 漏れた場合は @BotFather で
/revokeを使って変更してください。以前のトークンと、そのトークンによる接続はただちに切断されます。 - サーバー → Webhook:サーバーは、HTTPS かつグローバルアドレスの Webhook にのみリクエストを送ります。プライベートネットワーク・ループバック・クラウドのメタデータのような内部アドレスは拒否します。ボットは
secret_tokenを使って、リクエストが本物の Pabal サーバーから来たかどうかを確認できます。 - 管理:管理画面はサーバー自身(127.0.0.1)でのみ開き、トークンがなければデータを見られません。運営者は SSH トンネルで入ります。
- 保存:認証キーはサーバーが復号に使う必要があるため、データベースにそのまま入っています。データベースとバックアップは、サーバーの RSA 秘密鍵と同じくらい厳重に守る必要があります。
用語
| 用語 | 意味 |
|---|---|
| MTProto | Telegram が作った、アプリとサーバーの間の暗号化プロトコル。Pabal は 2.0 を使います。 |
| レイヤー(layer) | MTProto の上でやり取りされるリクエスト・レスポンス形式の版。Pabal は 216 です。 |
| 認証キー(auth key) | アプリがはじめて接続するときにサーバーと作る 2048 ビットの秘密。ログインはこのキーに紐づきます。 |
| DC | Telegram のデータセンター番号。Pabal では、1 台のサーバーが DC 1〜5 をすべて担当します。 |
| アップデート、pts | 新しいメッセージ・編集・削除のような変化。pts はユーザーごとの変化の通し番号で、切断されていた端末が何を見逃したかを知るために使います。 |
| ピア(peer) | 会話の相手 — 人、ボット、グループ。 |
| ボットトークン | <ボット ID>:<シークレット> 形式の文字列。Bot API のアドレスに入れて、ボットであることを証明します。 |
| Webhook | ボットが新着を取りに来る代わりに、サーバーがボットの HTTPS アドレスへ送る方式。 |