Sly Bye

Telegramボットを削除しても https://t.me/your_deleted_bot は引き続き HTTP 200 を返し、
見た目が完全に普通のページを表示します。CIアクション、
ディレクトリスクリプト、監視cronジョブなど、知っているすべてのリンクチェッカーはそれを永遠に健全と報告します。

Telegramボットを一覧表示するものを管理している場合、リストの一部は
すでに死んでいてもチェックでは問題ないと判断されます。

再現方法

存在したことのないユーザー名を選んでください:

curl -s -o /dev/null -w "%{http_code}\n" https://t.me/nonexistent_test_bot_77712
# 200

Enter fullscreen mode Exit fullscreen mode

200番。リダイレクトも404もなく、本文にステータスチェックが検出できるソフト404マーカーもありません。

真実はここにある

ステータスコードはここでは役に立ちませんが、Open Graphのタイトルは役立ちます。4つの
ユーザー名(生きているボット2つ、存在しないもの2つ)を測定しました:

URL og:title
t.me/BookClassBot (live) BookClass
t.me/instanavy_bot (live) StoryViewer - anonymous instagram story viewer tool
t.me/nonexistent_test_bot_77712 Telegram: Contact @nonexistent_test_bot_77712
t.me/zzz_definitely_not_a_real_bot_9182 Telegram – a new era of messaging

生きているボットは og:title に自分の表示名を入れます。死んでいるものはTelegramのプレースホルダーのいずれかになります:Telegram: Contact @<username>、またはユーザー名が文法的に有効でない場合は一般的な Telegram – a new era of messaging です。

それが全体のシグナルです。

curl -s https://t.me/some_bot | grep -o '<meta property="og:title" content="[^"]*"'

Enter fullscreen mode Exit fullscreen mode

チェック方法

標準ライブラリのみ、依存関係なし:

import re
import urllib.request

UA = "Mozilla/5.0 (compatible; linkcheck/1.0)"

DEAD_EXACT = {"Telegram – a new era of messaging", "Telegram"}
DEAD_PREFIX = "Telegram: Contact @"


def telegram_bot_exists(url: str) -> bool:
    """True if the bot behind a t.me URL still exists.

    HTTP status is not usable here: Telegram serves 200 with a placeholder page
    for usernames that were deleted or never existed. The Open Graph title is
    what actually differs.
    """
    req = urllib.request.Request(url, headers={"User-Agent": UA})
    with urllib.request.urlopen(req, timeout=20) as resp:
        html = resp.read(200_000).decode("utf-8", "replace")

    m = re.search(r'<meta\s+property="og:title"\s+content="([^"]*)"', html)
    title = m.group(1).strip() if m else ""

    if not title:
        return False
    return title not in DEAD_EXACT and not title.startswith(DEAD_PREFIX)

Enter fullscreen mode Exit fullscreen mode

Telegram – a new era of messaging のem dashに注意してください。これはU+2013で、ハイフンではありません。
私はこれに数分かかりました。

URLバリアントでも有効

Mini Appは複数の形式でリンクされ、すべての形式でチェックが有効です — タイトルは依然としてアプリの実際の名前に解決されます:

t.me/DefyTONBot/app                            -> "DefyTON"
t.me/arena_defense_bot/arena_defense           -> "ARENA DEFENSE"
t.me/lexicon_snap_bot?startapp=cat_awesome     -> "LexiCon"
t.me/playful_mind_bot/play?startapp=cat_awesome_tma -> "Playful Mind"

Enter fullscreen mode Exit fullscreen mode

したがって、誰かが送信したURLに対してそのままチェックを適用でき、最初にベアユーザー名に正規化する必要はありません。

なぜ気にする必要があるのか

ディレクトリは静かに劣化し、静かな劣化こそがディレクトリを破壊するからです。

すべてのエントリが200を返すボットリストは、維持されているように見えます。すべてのエントリが
緑色です。一方で、その一部はTelegramの何もないページにつながり、それを発見するのはリストをクリックした読者だけです — 一度クリックした後、二度とそのリストを信用しません。

私はTelegram Mini Appsのカタログを作成しているときにこれに遭遇しました。すべてのエントリが従来のリンクチェックをパスしました。タイトルのチェックを追加した後で初めて、ボットが実際に存在すると言えるようになりました。今ではCIで週1回実行され、静かに消えたものをフラグ付けします。

述べる価値のある注意点

  • これはTelegramのマークアップに依存しており、API契約ではありません。プレースホルダー文字列が変更されるとチェックは古くなります。文字列を明確な場所に固定し、既知の死んだユーザー名に対して定期的にテストしてください。
  • 存在するが壊れている、禁止されている、または応答しないボットは依然としてパスします。これはユーザー名が解決されることを示すだけで、それ以上のものではありません。
  • 礼儀正しくフェッチしてください。これはエントリごとの1リクエストで、スケジュールされたものであり、クロールではありません。

一般的な形

再利用可能な教訓はTelegramに関するものではありません。HTTP 200はサーバーが応答したことを意味し、そのものが存在することを意味しないということです。多くのプラットフォームは404ではなく装飾された「ここには何もない」ページを提供します — それは人間にとっては良いですが、それらを対象としたすべての自動チェックにとっては悪いものです。

他の誰かのプラットフォーム上のリソースをチェックする際、最初に尋ねるべき質問は:このホストは確実に存在しないものに対して何を返すか?です。まずそれを調べ、その後チェックを書いてください。検証していない404を仮定することが、モニターが数ヶ月間緑色を報告する原因になります。


これが生まれたカタログは
こちら — チェックは
scripts/check.py にあり、パブリックドメインなのでご自由にお使いください。私はまた
StoriesFly も作成しており、そこから上記のInstagram風のテスト ユーザー名が生まれました。