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

如何实现可同时收发消息的Discord Bot?

Discord Bot 实现控制台收发消息的问题解决

我正在开发一个Discord Bot,希望实现同时在控制台读取他人消息并发送消息的功能。

最初的尝试与问题

最初尝试了以下代码,但存在阻塞问题——必须先输入要发送的内容,才能显示他人发送的消息:

@client.event
async def on_message(message):
  channel = message.channel
  content = message.content
  user = message.author

  talk = input('>')
  await channel.send(talk)
  print(f'{user} - {content}')

多线程尝试的错误

查阅资料后尝试用多线程解决,但方案仍然无法正常运行:

@client.event
async def on_message(message):
  channel = message.channel
  talk = input('>')
  await channel.send(talk)
  def read(message):
      content = message.content
      user = message.author
      print(f'{user} - {content}')

  threadObj = threading.Thread(target=read(message))
  threadObj.start()

问题根源

  • input()是阻塞式函数,放在on_message事件里会卡住Discord的事件循环,导致必须完成输入才会处理消息打印
  • 多线程用法错误:target=read(message)是直接执行了read函数,而非将函数作为线程目标;且逻辑搞反,应该把控制台输入放到线程里,而非消息处理

正确解决方案

将控制台输入逻辑单独放到线程中,避免阻塞事件循环;on_message仅负责处理收到的消息:

完整代码示例

import discord
import threading
import asyncio
from discord.ext import commands

# 初始化Bot,需要开启消息内容权限
intents = discord.Intents.default()
intents.message_content = True
client = commands.Bot(command_prefix="!", intents=intents)

def console_input_loop():
    """控制台输入线程:持续读取输入并发送到指定频道"""
    while True:
        talk = input('>')
        # 替换为你要发送的频道ID
        target_channel = client.get_channel(1234567890)
        if target_channel:
            # 在非异步线程中调用异步发送方法
            asyncio.run_coroutine_threadsafe(target_channel.send(talk), client.loop)

@client.event
async def on_ready():
    print(f'已登录为 {client.user}')
    # 启动控制台输入线程,daemon=True让线程随主程序退出
    threading.Thread(target=console_input_loop, daemon=True).start()

@client.event
async def on_message(message):
    # 忽略Bot自身发送的消息
    if message.author == client.user:
        return
    # 打印收到的消息
    print(f'{message.author} - {message.content}')
    # 若需要处理命令,保留此行
    await client.process_commands(message)

# 替换为你的Bot令牌
client.run('your_bot_token_here')

关键说明

  1. 控制台输入线程:将input()放到单独线程中,避免阻塞Discord的事件循环
  2. 异步调用兼容:用asyncio.run_coroutine_threadsafe在非异步线程中调用Discord的异步方法,确保和事件循环兼容
  3. 消息处理分离:on_message仅负责打印收到的消息,不再处理输入逻辑,不会被阻塞

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 03:18:22