Ruby自定义Discord客户端无法获取消息内容及报错求助
问题排查与修复方案
1. 修复JSON解析错误
报错809: unexpected token at ''是因为WebSocket收到空消息,直接调用JSON.parse会失败。需要先过滤空消息,同时添加解析异常捕获:
client.on(:message) do |msg| next if msg.data.strip.empty? # 跳过空消息 begin data = JSON.parse(msg.data) rescue JSON::ParserError => e puts "JSON解析失败: #{e.message}" next end # 后续逻辑 end
2. 解决undefined method [] for nil:NilClass错误
这个错误的核心是未过滤消息事件类型:OP0是Dispatch事件,但包含几十种不同类型(如READY、GUILD_CREATE、MESSAGE_CREATE等),只有MESSAGE_CREATE才是用户发送的消息。其他事件的data['d']结构完全不同,直接访问author、content会触发nil调用。
修复后的消息处理逻辑:
client.on(:message) do |msg| next if msg.data.strip.empty? begin data = JSON.parse(msg.data) rescue JSON::ParserError => e puts "JSON解析失败: #{e.message}" next end # 仅处理用户发送的消息事件 if data['op'] == 0 && data['t'] == 'MESSAGE_CREATE' # 逐层检查字段,避免nil调用 d = data['d'] || {} channel_id = d['channel_id'] || '未知频道' author = d['author'] || {} username = author['username'] || '未知用户' content = d['content'] || '' puts "[#{channel_id}] <#{username}> #{content}" end end
3. 修复消息内容为空的问题
核心修复点:
- 升级Gateway版本:v9已被Discord弃用,改用最新的v10版本:
version = '10' # 替换原有的'9' - 调整身份验证参数:用户账号(非机器人)不需要
intents字段,Discord会忽略该设置,移除后可避免不必要的错误:client.on(:open) do client.send({ op: 2, d: { token: token, properties: { '$os': 'linux', '$browser': 'chrome', '$device': '' }, presence: { status: 'online', afk: false } # 用户账号可设置在线状态 } }.to_json) end - 可选:排除Webhook消息:如果需要过滤机器人Webhook发送的消息,在判断条件中添加:
if data['op'] == 0 && data['t'] == 'MESSAGE_CREATE' && !d['webhook_id']
4. 额外优化建议
- 添加心跳维持连接:Discord Gateway要求定期发送心跳(OP1),否则会被断开连接:
client.on(:open) do # ... 身份验证代码 ... Thread.new do loop do client.send({ op: 1, d: nil }.to_json) sleep 41.5 # Discord建议的心跳间隔,或从READY事件获取准确值 end end end - 添加重连逻辑:WebSocket断开后自动重新连接,避免程序直接退出。
内容的提问来源于stack exchange,提问作者user22128726
相关产品推荐
相关产品推荐

