You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

带URL的Inline按钮无法触发CallbackQuery,如何解决?

问题:带URL的InlineKeyboardButton无法触发回调事件

我定义了同时包含url和callback_data的内联键盘按钮,尝试捕获其点击事件,但对应的回调处理函数从未被调用,甚至通用的回调处理器也无法触发。不带URL的其他按钮则能正常工作,问题似乎出在URL参数上。请问有没有其他方法可以捕获带链接按钮的点击事件?

以下是完整代码:

from aiogram import Bot, Dispatcher
from aiogram import types
from aiogram import executor
from aiogram.types import (
    InlineKeyboardMarkup, 
    InlineKeyboardButton
)

bot = Bot(token="BotToken")
dp = Dispatcher(bot)

watch_cb = "watch_cb"
second_cb = "second_cb"

@dp.message_handler(commands=['start'])
async def cmd_start(message: types.Message):
    await message.answer("The bot is started!", reply_markup=get_inline_keyboard())

def get_inline_keyboard():
    return InlineKeyboardMarkup(
                inline_keyboard=[
                    [
                        InlineKeyboardButton(text="Watch", callback_data=watch_cb, url="https://google.com"),
                        InlineKeyboardButton(text="Second Button", callback_data=second_cb)
                    ]
                ]
            )

@dp.callback_query_handler(text=watch_cb)
async def process_watch_btn(call: types.CallbackQuery):
    print("\ncall = process_watch_btn()\n")


@dp.callback_query_handler(text=second_cb)
async def process_second_btn(call: types.CallbackQuery):
    print("\ncall = process_second_btn()\n")


if __name__ == '__main__':
    executor.start_polling(dp, skip_updates=True)

原因与解决方案

核心原因

Telegram官方不支持同时带有url和callback_data的内联按钮。当按钮同时设置这两个参数时,Telegram客户端只会执行URL跳转操作,完全忽略callback_data参数,因此你的回调处理器根本无法收到任何请求。

可行解决方案

方案1:拆分功能为两个独立按钮

将跳转链接和触发回调的逻辑拆分为两个按钮,分别实现各自功能:

def get_inline_keyboard():
    return InlineKeyboardMarkup(
                inline_keyboard=[
                    [
                        InlineKeyboardButton(text="打开链接", url="https://google.com"),
                        InlineKeyboardButton(text="触发操作", callback_data=watch_cb)
                    ],
                    [
                        InlineKeyboardButton(text="Second Button", callback_data=second_cb)
                    ]
                ]
            )

方案2:在回调逻辑中引导用户打开链接

只给按钮设置callback_data,在回调函数内部完成逻辑处理后,再引导用户打开链接:

def get_inline_keyboard():
    return InlineKeyboardMarkup(
                inline_keyboard=[
                    [
                        InlineKeyboardButton(text="Watch", callback_data=watch_cb),
                        InlineKeyboardButton(text="Second Button", callback_data=second_cb)
                    ]
                ]
            )

@dp.callback_query_handler(text=watch_cb)
async def process_watch_btn(call: types.CallbackQuery):
    # 结束回调加载状态,给用户反馈
    await call.answer("正在为你准备链接")
    # 发送链接消息给用户
    await call.message.answer("点击下方链接观看:\nhttps://google.com")
    print("\ncall = process_watch_btn()\n")

方案3:使用Telegram Deep Link(进阶)

通过Deep Link实现“跳转链接+记录操作”的需求:用户点击链接后会先打开目标页面,返回Bot时携带参数,Bot再根据参数处理逻辑。

  1. 构造Deep Link链接(替换为你的Bot用户名):
https://t.me/你的Bot用户名?start=watch_movie
  1. 修改Bot代码处理Deep Link参数:
@dp.message_handler(commands=['start'])
async def cmd_start(message: types.Message):
    args = message.get_args()
    if args == "watch_movie":
        # 处理用户从Deep Link返回后的逻辑
        print("用户触发了观看操作")
        await message.answer("已记录你的操作,你可以前往目标页面观看内容")
    else:
        await message.answer("The bot is started!", reply_markup=get_inline_keyboard())

def get_inline_keyboard():
    return InlineKeyboardMarkup(
                inline_keyboard=[
                    [
                        InlineKeyboardButton(text="Watch", url="https://t.me/你的Bot用户名?start=watch_movie"),
                        InlineKeyboardButton(text="Second Button", callback_data=second_cb)
                    ]
                ]
            )

内容的提问来源于stack exchange,提问作者Daniyar Amirov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 18:43:12