刪除一個 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 標題則不然。我測試了四個 使用者名稱 — 兩個活躍的機器人,兩個不存在的:
| URL | og:title |
|---|---|
t.me/BookClassBot (活躍) |
BookClass |
t.me/instanavy_bot (活躍) |
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 中的破折號。它是 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 App 目錄時遇到了這個問題。每個項目都通過了 傳統的連結檢查。只有在加入標題檢查後,我才能說這些機器人確實存在。它現在每週在 CI 中執行,並標記任何已悄然 消失的項目。
值得一提的注意事項
- 這取決於 Telegram 的標記,而這不是 API 合約。如果他們更改預留位置 字串,檢查就會過時。將這些字串明顯地固定在某處,並偶爾針對已知失效的使用者名稱進行測試。
- 存在但已損壞、被封鎖或無回應的機器人仍然會通過檢查。這只告訴您 使用者名稱可以解析 — 僅此而已。
- 請有禮貌地抓取。這是每個項目一次請求,依排程進行,而不是爬取。
通用原則
可重複使用的教訓與 Telegram 無關。重點在於 HTTP 200 意味著伺服器 有回應,而不是該項目存在。許多平台會提供裝飾過的 「這裡沒有東西」頁面,而不是 404 — 這對人類來說更好,但對所有指向它們的 自動化檢查來說更糟。
每當您在別人的平台上檢查資源時,要問的問題是:這個主機對於 確定不存在的項目會回傳什麼?先找出答案,然後再撰寫檢查。假設您從未驗證過的 404 是監控器連續數月回報綠色的原因。
這個案例出處的目錄位於
這裡 — 檢查程式位於
scripts/check.py,屬於公共領域,請自行取用。我也建立了
StoriesFly,這就是上面 Instagram 風格測試
使用者名稱的來源。
0 Comments
Log in to join the conversation.No comments yet. Be the first to share your thoughts.