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

如何在等待用户输入时让Discord bot正常接收并打印消息

解决方案

核心问题原因

  • 原代码中input()是同步阻塞函数,直接放在异步的on_message回调中会卡死discord.py的异步事件循环,导致新消息接收、后台同步等所有逻辑全部停转
  • on_message是消息触发回调,每收到一条新消息会自动执行一次,不需要额外加无限while循环,多余的死循环会进一步阻塞逻辑
  • 多线程不生效是因为没有把阻塞的输入逻辑和异步事件循环拆开,跨线程调用异步函数需要通过asyncio.run_coroutine_threadsafe提交任务,不能直接调用await

修复后可运行代码

import discord
import asyncio
import threading

# 全局变量存储异步事件循环和当前活跃发送频道
loop = None
current_channel = None

# 需开启消息内容意图才能正常接收消息
intents = discord.Intents.default()
intents.message_content = True
client = discord.Client(intents=intents)

@client.event
async def on_ready():
    global loop
    loop = asyncio.get_running_loop()
    print('Logged in as {0.user}'.format(client))

@client.event
async def on_message(message):
    global current_channel
    # 忽略自身发送的消息
    if message.author == client.user:
        return
    # 更新当前活跃频道为最新收到消息的频道
    current_channel = message.channel
    # 新消息收到直接打印,无需等待输入
    username = str(message.author).split('#')[0]
    print(f'\n{username} : {message.content}')
    # 保留输入提示,优化输入体验
    print('You: ', end='', flush=True)

# 单独线程运行用户输入逻辑,不阻塞主事件循环
def input_handler():
    while True:
        answer = input('You: ')
        if not current_channel or not loop:
            print('暂无可发送的频道,请等待收到消息后重试')
            continue
        # 跨线程提交发送任务到异步事件循环
        asyncio.run_coroutine_threadsafe(current_channel.send(answer), loop)

if __name__ == '__main__':
    # 启动输入守护线程,主程序退出时自动销毁
    threading.Thread(target=input_handler, daemon=True).start()
    # 替换为你自己的Bot Token
    client.run('你的Bot TOKEN')

功能说明

  • 所有新消息收到后会直接打印到控制台,哪怕你正在输入内容也不会漏消息,解决多消息堆叠的问题
  • 输入内容默认发送到最新发来消息的频道,你可以根据需求扩展多频道切换逻辑
  • 使用前需要先在Discord开发者后台的Bot设置页开启Message Content Intent权限,否则无法正常读取消息内容

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 02:15:05