当你在Telegram聊天框中输入 @你的机器人 关键词 时,机器人可以立即返回一组精心设计的结果供你选择,这就是内联模式(Inline Mode)。对于开发者而言,掌握如何发送内联查询结果是构建高效、用户友好机器人的核心技能。本文将以官方API为基准,通过实例详解Telegram机器人发送内联查询结果的完整流程,帮助你快速上手。
一、内联模式与内联查询结果基础
内联模式允许用户在任何聊天对话中直接调用你的机器人,而无需先进入与机器人的私聊界面。当用户输入 @机器人 查询内容 后,Telegram客户端会向你的服务器发送一个 inline_query 更新,包含 query(用户输入的查询字符串)和 inline_query_id(用于响应的唯一标识)。
机器人需要回复这个更新,通过调用 answerInlineQuery 方法返回一个或多个“内联查询结果”(InlineQueryResult)。这些结果会以列表形式展示给用户,用户点击任意结果后,该结果对应的内容(如文本、图片链接、视频等)就会被发送到当前聊天中。
二、answerInlineQuery方法详解
下面是 answerInlineQuery 方法的核心参数:
- inline_query_id(必需):来自
inline_query更新的唯一ID,用于关联响应。 - results(必需):一个JSON数组,包含最多50个内联查询结果对象,类型必须为
InlineQueryResult子类。 - cache_time(可选):结果缓存的秒数,默认300秒。设置为0可禁用缓存,确保每次都是新结果。
- is_personal(可选):布尔值,设为
true可让结果仅对当前用户可见,适合个性化内容。 - next_offset(可选):分页游标,用于返回下一组结果。配合
inline_query.offset实现“加载更多”。 - button(可选):在结果列表底部显示一个按钮,通常用于打开机器人或网页。
最重要的就是 results 参数,它是由具体的内联查询结果类型组成的数组。
三、常见的内联查询结果类型及适用场景
Telegram Bot API 定义了多种内联查询结果类型,每种都有不同的字段和适用场景。以下是最常用的几种:
1. InlineQueryResultArticle
用于发送纯文本、链接或HTML内容。当你希望用户点击后直接发送一条消息时,这是最基础的类型。
{
"type": "article",
"id": "1",
"title": "今日天气",
"input_message_content": {
"message_text": "北京:晴,25℃"
},
"description": "点击查看北京天气",
"url": "https://example.com/weather"
}
2. InlineQueryResultPhoto
用于发送图片。需要提供图片URL或Telegram文件ID。
{
"type": "photo",
"id": "2",
"photo_url": "https://example.com/cat.jpg",
"thumb_url": "https://example.com/thumb.jpg",
"caption": "一只可爱的猫咪"
}
3. InlineQueryResultVideo
用于发送视频。需要视频URL和缩略图URL。
{
"type": "video",
"id": "3",
"video_url": "https://example.com/video.mp4",
"mime_type": "video/mp4",
"thumb_url": "https://example.com/video_thumb.jpg",
"title": "我的旅行vlog"
}
4. InlineQueryResultGif
用于发送GIF动图。
{
"type": "gif",
"id": "4",
"gif_url": "https://example.com/animation.gif",
"thumb_url": "https://example.com/gif_thumb.jpg"
}
5. 缓存类型(Cached)
如果机器人已经通过其他方式上传了文件(如发送过照片、视频等),可以获取对应的file_id,并使用 InlineQueryResultCachedPhoto 等类型直接引用,避免重复上传,响应更快。
选择正确的结果类型能让用户体验更加直观。例如,搜索机器人返回文章卡片,图片机器人返回缩略图,电商机器人返回商品卡片。
四、实战:Python实现发送内联查询结果
我们使用 python-telegram-bot 库(或纯 requests)来实现一个简单的内联机器人。这里以官方推荐的 python-telegram-bot v20+ 为例。
步骤1:安装库与创建机器人
pip install python-telegram-bot
在BotFather中创建机器人,并开启内联模式:
- 发送
/newbot创建机器人并获得token。 - 发送
/setinline选择机器人,输入占位符如搜索...。
步骤2:编写处理inline_query的代码
from telegram import InlineQueryResultArticle, InputTextMessageContent, Update
from telegram.ext import Application, InlineQueryHandler, ContextTypes
async def inline_query(update: Update, context: ContextTypes.DEFAULT_TYPE):
query = update.inline_query.query
# 构造结果:返回查询内容的反转字符串
reversed_text = query[::-1] if query else "请输入内容"
results = [
InlineQueryResultArticle(
id="1",
title="反转文本",
description=f"点击发送:",
input_message_content=InputTextMessageContent(reversed_text)
)
]
await update.inline_query.answer(results=results, cache_time=0)
def main():
app = Application.builder().token("YOUR_TOKEN").build()
app.add_handler(InlineQueryHandler(inline_query))
app.run_polling()
if __name__ == "__main__":
main()
步骤3:测试
在任意聊天框输入 @你的机器人 你好,机器人会返回“反转文本”结果,点击后发送“好你”。
五、实战:Node.js实现发送内联查询结果
使用 node-telegram-bot-api 库实现相同功能。
步骤1:安装库
npm install node-telegram-bot-api
步骤2:编写代码
const TelegramBot = require('node-telegram-bot-api');
const token = 'YOUR_TOKEN';
const bot = new TelegramBot(token, { polling: true });
bot.on('inline_query', async (msg) => {
const query = msg.query || '';
const reversedText = query.split('').reverse().join('') || '请输入内容';
const results = [{
id: '1',
type: 'article',
title: '反转文本',
description: `点击发送:$`,
input_message_content: {
message_text: reversedText
}
}];
await bot.answerInlineQuery(msg.id, results, { cache_time: 0 });
});
步骤3:运行与测试
保存文件后运行 node bot.js,在Telegram中测试即可。
六、缓存与分页:优化内联查询体验
实际生产环境中,我们往往需要处理大量内容。两项关键设置能显著提升性能:
1. 合理利用cache_time
对于不经常变化的数据(如词典、百科词条),可以设置较长的 cache_time(如3600秒),减少服务器压力。对于实时数据(如股票价格),设置 cache_time=0 禁用缓存。
2. 实现分页加载
当结果超过50条时,必须使用 next_offset 实现分页。客户端在滚动到底部时会自动发送带有 offset 字段的新 inline_query,机器人处理该字段并返回相应的 next_offset。
# Python 示例:简单分页
async def inline_query(update: Update, context: ContextTypes.DEFAULT_TYPE):
query = update.inline_query.query
offset = int(update.inline_query.offset) if update.inline_query.offset else 0
page_size = 10
# 假设从数据库获取数据
data = fetch_items(query, offset, page_size)
results = [
InlineQueryResultArticle(
id=str(i),
title=item.title,
input_message_content=InputTextMessageContent(item.url)
) for i, item in enumerate(data)
]
next_offset = str(offset + page_size) if len(data) == page_size else ''
await update.inline_query.answer(results, next_offset=next_offset, cache_time=0)
七、常见问题与调试技巧
- 问题:机器人没有响应内联查询? 检查是否通过BotFather开启了内联模式(
/setinline),并确保回调函数没有报错。 - 问题:返回的结果不显示? 确认
results数组中的每个对象都包含必填字段(如id必须唯一,type必须正确)。 - 问题:点击结果后无法发送消息? 检查
input_message_content是否正确,对于URL类型需要设置为disable_web_page_preview或处理链接预览。 - 调试技巧: 在开发者环境中打印
inline_query的完整更新对象,使用print(update.inline_query)或console.log(msg)检查数据。
总结
通过本文的实例,我们学习了Telegram机器人发送内联查询结果的完整流程,从理解内联模式到使用 answerInlineQuery 方法,再到Python和Node.js的实战实现。掌握内联查询结果的类型选择和缓存分页优化,能让你的机器人更加专业和高效。现在,你不妨动手试一下,为用户创造更便捷的交互体验吧!