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

同步命令执行异常:Discord-VK转发Bot无法兼顾命令与转发

让VK-Discord转发Bot同时支持命令与消息转发

你的代码核心问题在于longpoll.listen()是同步阻塞的循环——在异步函数disbot()里直接运行这个同步循环会独占整个事件循环,导致Discord的命令处理逻辑完全无法执行。下面是修复方案:

修改思路

  1. 将VK长轮询的监听逻辑放到独立线程中运行,避免阻塞Discord的异步事件循环
  2. 跨线程调用Discord的异步发送消息方法时,使用asyncio.run_coroutine_threadsafe()来安全调度异步任务

修复后的完整代码

import vk_api
from vk_api.longpoll import VkEventType, VkLongPoll
import discord
from discord.ext import commands
import asyncio
import threading

client = commands.Bot(command_prefix='!', intents=discord.Intents.all())

@client.event
async def on_ready():
    print('The bot is connected to Discord!')

@client.event
async def on_message(message):
    if message.author == client.user:  
        return
    await client.process_commands(message)

@client.command(pass_context=True)
async def hi(ctx: commands.Context):
    await ctx.send('Hi!')

# VK相关配置(替换为你的实际信息)
login = '你的VK登录账号'
password = '你的VK密码'
api_version = '5.131'  # 替换为正确的VK API版本
chat_id = 1  # 要监听的VK聊天ID
discord_channel_id = 1234567890  # 替换为目标Discord频道ID
discord_token = '你的Discord Bot Token'

vk_session = vk_api.VkApi(login, password, api_version=api_version)
vk_session.auth()
vk = vk_session.get_api()

def vk_listener():
    longpoll = VkLongPoll(vk_session)
    for event in longpoll.listen():
        if event.type == VkEventType.MESSAGE_NEW and event.from_chat and event.chat_id == chat_id:
            user_id = event.user_id
            message_text = event.text
            attachments = event.attachments
            user_info = vk.users.get(user_ids=user_id)
            user_name = f"{user_info[0]['first_name']} {user_info[0]['last_name']}"
            
            # 构建要发送的消息内容
            if '@all' in message_text:
                msg_content = f"{user_name} » {message_text} @everyone"
            else:
                msg_content = f"{user_name} » {message_text}"
            
            if 'attach1_type' in attachments:
                msg_content += " [Attachment]"
            
            # 跨线程调度Discord发送消息的异步任务
            async def send_to_discord():
                await client.wait_until_ready()
                channel = client.get_channel(discord_channel_id)
                if channel:
                    await channel.send(msg_content)
            
            asyncio.run_coroutine_threadsafe(send_to_discord(), client.loop)

async def main():
    # 启动VK监听线程
    threading.Thread(target=vk_listener, daemon=True).start()
    await client.start(discord_token)

asyncio.run(main())

关键修改说明

  • 新增vk_listener()同步函数,将VK的长轮询逻辑移到这里,然后用线程启动这个函数,彻底避免阻塞Discord的事件循环
  • 使用asyncio.run_coroutine_threadsafe()将发送Discord消息的异步任务提交到Discord的事件循环中执行,保证跨线程调用的安全性
  • 修正了原代码中的占位符提示,明确标注需要替换的配置项

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 23:10:12