Telegram通过Bot API实现文件预览功能:从缩略图到内容抽取的完整攻略

深入探索Telegram Bot API的文件发送机制,手把手教你为文档、图片添加自定义缩略图,并实现文件内容文本预览,打造高效的文件分享机器人。

阅读提示建议先浏览小标题,再根据需要深入阅读具体段落。

Telegram Bot API为开发者提供了强大的文件传输能力,但许多人在实际使用中发现,机器人发送的文件在聊天窗口中往往只有一个默认图标,用户无法快速了解文件内容,用户体验大打折扣。你是否希望机器人发送的PDF、Word或图片能直接生成预览,甚至附带文本摘要?本文将深入剖析Telegram Bot API的文件预处理机制,带你一步步实现从自定义缩略图到内容抽取的完整文件预览方案,让你的机器人在群组和频道中脱颖而出。

理解Bot API的文件发送与预览机制

Telegram客户端本身支持对图片、视频、GIF等媒体文件自动生成预览,但像PDF、Office文档、文本文件等,客户端通常只显示一个文件卡片,不会自动渲染内容。不过,Bot API提供了多种参数和扩展方式,让我们能够主动填补这一空白。

核心思路有两种:一是为文件指定自定义缩略图(thumb),让聊天界面显示一张有信息量的图片;二是提前提取文件内容,作为caption(说明文字)附加在文件之后。两种方式可以组合使用,达到“视觉+文字”双重预览效果。

为文档添加自定义缩略图:使用sendDocument中的thumb参数

Telegram Bot API的sendDocument方法支持一个参数thumb,允许我们传入一张JPEG格式的图片作为文档的缩略图。该图片必须满足:JPEG格式、大小不超过200KB、宽高均不超过320像素。注意,缩略图只能使用JPEG,PNG会被自动转换或拒绝。

下面是一个使用Python请求库的完整示例,发送一个PDF文件并附带自定义缩略图:

import requests

bot_token = "YOUR_BOT_TOKEN"
chat_id = "YOUR_CHAT_ID"

url = f"https://api.telegram.org/bot/sendDocument"
files = {
    "document": ("report.pdf", open("report.pdf", "rb"), "application/pdf"),
    "thumb": ("thumb.jpg", open("thumb.jpg", "rb"), "image/jpeg")
}
data = {
    "chat_id": chat_id,
    "caption": "我是reports的摘要信息,供快速了解。"
}
response = requests.post(url, files=files, data=data)
print(response.json())

保存运行后,你在Telegram中就能看到这个文档附带了一张缩略图,用户无需下载即可通过缩略图了解大致内容。注意,thumb参数在发送视频时同样适用。

图片与视频的预览优化:生成压缩版本再发送

对于图片,Telegram客户端本身就会生成预览,但原图过大时上传速度慢,且可能消耗群组空间。我们可以使用Pillow库在本地生成一张缩小尺寸的预览图,然后通过sendPhoto发送预览图,原图作为sendDocument发送。这样既保留了原图,又能在聊天窗口快速显示小图预览。

以下代码演示使用Pillow制作宽度为320像素的JPEG缩略图:

from PIL import Image

img = Image.open("photo.png")
img.thumbnail((320, 320))
img.save("preview.jpg", "JPEG")
# 然后使用上面的files上传方式发送"preview.jpg"作为photo

视频也可以用类似方式抽取第一帧作为缩略图,配合sendVideothumb参数。

实现文件内容的文本提取预览:PDF与Word实例

如果文件是PDF、Word等文本型文档,我们可以通过脚本提取其中的文字片段,作为文件说明文本发送给用户。这样用户先看到缩略图,再读到核心内容摘要,就能准确判断是否需要下载。

以PDF为例,使用pdfplumber库提取前几页文字:

import pdfplumber

def extract_pdf_preview(path, chars=500):
    with pdfplumber.open(path) as pdf:
        text = ""
        for page in pdf.pages[:3]:  # 提取前3页
            text += page.extract_text() or ""
            if len(text) > chars:
                break
        return text[:chars] or "(无法提取文本)"

对于Word文档,可以使用python-docx读取段落:

from docx import Document

def extract_docx_preview(path, chars=500):
    doc = Document(path)
    text = "\n".join([p.text for p in doc.paragraphs if p.text.strip()])
    return text[:chars] or "(无内容)"

然后提取的文本拼接在caption中,与文件一同发送。

综合实战:构建一个自动文件预览机器人

现在让我们将以上技巧整合到一个真实的Bot中。这个Bot在接收到用户发送的文件后,自动判断类型,生成预览并回复。我们可以使用python-telegram-bot库来简化开发,但为了展示核心原理,这里使用Flask和Webhook的方式。

完整代码结构如下:

import os, tempfile
from flask import Flask, request, jsonify
import requests
from PIL import Image
import pdfplumber
from docx import Document

app = Flask(__name__)
BOT_TOKEN = "YOUR_TOKEN"
API_URL = f"https://api.telegram.org/bot"

def download_file(file_id):
    # 通过getFile获取文件路径并下载
    resp = requests.get(f"/getFile", params={"file_id": file_id})
    path = resp.json()["result"]["file_path"]
    url = f"https://api.telegram.org/file/bot/"
    data = requests.get(url).content
    return data

def make_thumb(data, width=320):
    # 保存临时图片并生成缩略图
    with tempfile.NamedTemporaryFile(suffix=".img") as f:
        f.write(data)
        f.seek(0)
        img = Image.open(f.name)
        img.thumbnail((width, width))
        thumb_path = f.name + ".jpg"
        img.convert("RGB").save(thumb_path, "JPEG")
        return open(thumb_path, "rb")

def extract_text(filename, data):
    # 根据扩展名提取文本
    ext = filename.rsplit(".", 1)[-1].lower()
    if ext == "pdf":
        with tempfile.NamedTemporaryFile(suffix=".pdf") as f:
            f.write(data); f.seek(0)
            return extract_pdf_preview(f.name)
    elif ext in ("docx", "doc"):
        with tempfile.NamedTemporaryFile(suffix=".docx") as f:
            f.write(data); f.seek(0)
            return extract_docx_preview(f.name)
    return ""

@app.route(f"/webhook/", methods=["POST"])
def webhook():
    update = request.get_json()
    if "message" in update:
        msg = update["message"]
        chat_id = msg["chat"]["id"]
        if "document" in msg:
            doc = msg["document"]
            file_id = doc["file_id"]
            filename = doc["file_name"]
            data = download_file(file_id)
            caption = extract_text(filename, data) or "(无可用摘要)"
            thumb = make_thumb(data) if filename.lower().endswith((".png",".jpg",".jpeg")) else None
            # 发送文档
            requests.post(f"/sendDocument",
                data={"chat_id": chat_id, "caption": caption},
                files={"document": (filename, data), "thumb": thumb} if thumb else {"document": (filename, data)})
    return jsonify(ok=True)

if __name__ == "__main__":
    app.run(port=5000)

将代码中的Token替换为你的Bot Token,并设置Webhook(例如使用ngrok),一个具备文件预览能力的机器人就诞生了。当用户发送文件时,Bot会自动下载、生成缩略图、提取文本并回复,全部过程数秒内完成。

进阶技巧:利用Telegram的链接即时预览

有时候文件存储在外部服务器上,你可以直接发送该文件的分享链接,并设置link_preview_options(Bot API 7.0+)来控制链接预览的显示。如果你拥有Telegram的Instant View功能,还可以让文本类网页自动生成精美的预览卡片,但这需要向Telegram申请白名单,与Bot API本身无直接关系,不过可以作为文件预览的辅助方案。

总结

通过Bot API实现文件预览并非难事,关键在于灵活运用thumb参数、文件内容提取技术以及Telegram客户端自带的媒体渲染能力。从自定义缩略图到文本摘要,再到Webhook机器人集成,本文提供了一套从简到繁的完整路径。建议你从最简单的缩略图入手,逐步尝试提取PDF、Word等常见格式的内容,并集成到自己的机器人中。这不仅能极大提升文件分享的效率,也能让用户在Telegram内获得更接近“即时预览”的体验。

现在,动手改造你的Bot吧!如果你有更多关于文件预览的奇思妙想,欢迎在社区中分享。

FAQ

安装与配置指南

常见问题

Telegram Bot API支持发送哪些文件类型的缩略图?

根据官方文档,缩略图必须为JPEG格式,大小不超过200KB,宽高不超过320像素。任何格式的文件都可以附加这样的JPEG缩略图,包括PDF、Word、ZIP等。

发送文件时,缩略图参数是必须的吗?

不是必须的。如果不指定缩略图,Telegram客户端会为部分媒体类型自动生成,但文档类文件通常只会显示一个默认图标。为了更好的预览效果,建议为重要文件配置缩略图。

如何从PDF中提取文本用于文件预览?

可以使用Python的pdfplumber、PyPDF2等库。首先通过Bot API的getFile方法获取文件路径并下载,然后使用pdfplumber逐页提取文本,截取前几百个字符作为摘要,最后通过sendDocument的caption参数发送给用户。

Bot API支持哪些编程语言的SDK?

Telegram官方没有提供SDK,但有社区开发的各种语言的库,如python-telegram-bot、node-telegram-bot-api、telebot(Go)等。你也可以直接使用HTTP请求调用API,本文的示例就是基于requests库的。

生成的缩略图为什么显示不出来?

常见原因包括:缩略图不是JPEG格式、文件大小超过200KB、尺寸超过320x320像素、或FTP服务配置错误。请检查图片是否符合规范,并确保在请求中正确设置文件名和MIME类型。