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

如何使用Roblox私信Web API的Send接口?luasocket请求报错咨询

问题描述

使用luasocket调用Roblox私信发送接口时触发两类报错:

  • 403: Token Validation Failed
  • 401: Authorization has been denied for this request.

原始请求代码:

local socket = require'socket.http'
local json = require'json'

print(os.date('at %c'..', the program starts.'))
-- 底部实现参考公开的Lua HTTP请求示例(非安全实现)

local result,code,headers,stats = socket.request(
    {
        method = 'POST',
        url = 'https://privatemessages.roblox.com/v1/messages/send',
        headers = ({
            ["Cookie"] =".ROBLOSECURITY=not-showing-to-you",
            ["content-length"]= 10 -- I have no idea how this thing works
        })
    }
)
print(json.encode(result))
print(code)
print(stats)
print(json.encode(headers))

补充说明

尝试多日调试后,因不借助封装类库实现该功能逻辑过于复杂,已放弃调试。


问题原因与修复方案

代码存在4个核心问题,按优先级排序:

  1. 依赖模块错误:socket.http仅支持HTTP协议请求,目标接口是HTTPS协议,必须替换为LuaSec库提供的ssl.https模块发起请求,否则连接本身就不符合接口要求。
  2. 缺少必填校验头:Roblox所有非GET接口都要求携带X-CSRF-TOKEN请求头,没有这个头会直接返回403 Token校验失败。这个token不需要提前获取,第一次发POST请求时故意不带该头,接口会在响应头的x-csrf-token字段返回有效值,后续请求带上这个值即可。
  3. 请求参数与Content-Length设置错误:
    • 私信发送接口要求POST请求体必须携带JSON格式的三个必填字段:收件人IDrecipientId、私信标题subject、私信内容body,当前代码完全没有传请求体。
    • content-length是请求体的实际字节长度,不能随便填固定值10,计算实际请求体的字节长度填入即可,部分场景下也可以直接省略该头让HTTP库自动计算。
  4. 请求头缺失触发反爬拦截:仅携带Cookie会被Roblox反爬策略识别为异常请求返回401,需要补充Content-Type: application/json、Origin: https://www.roblox.com、Referer: https://www.roblox.com/几个基础头模拟正常浏览器请求。

修复后的最小可用代码参考:

-- 注意需要先通过LuaRocks安装luasec依赖
local https = require("ssl.https")
local json = require("json")
local ltn12 = require("ltn12")

-- 配置项
local ROBLOX_SECURITY = "替换为你自己的.ROBLOSECURITY值"
local RECIPIENT_ID = 替换为收信人的用户ID
local MESSAGE_SUBJECT = "测试私信标题"
local MESSAGE_BODY = "测试私信内容"

-- 第一步:获取CSRF Token
local csrf_token = nil
local _, code, resp_headers = https.request({
    method = "POST",
    url = "https://privatemessages.roblox.com/v1/messages/send",
    headers = {
        ["Cookie"] = ".ROBLOSECURITY=" .. ROBLOX_SECURITY,
        ["Content-Type"] = "application/json",
        ["Origin"] = "https://www.roblox.com",
        ["Referer"] = "https://www.roblox.com/"
    }
})
-- 第一次请求会返回403,同时在响应头带CSRF Token
if code == 403 and resp_headers["x-csrf-token"] then
    csrf_token = resp_headers["x-csrf-token"]
else
    print("获取CSRF Token失败,返回码:" .. tostring(code))
    os.exit(1)
end

-- 第二步:构造合法请求发送私信
local request_body = json.encode({
    recipientId = RECIPIENT_ID,
    subject = MESSAGE_SUBJECT,
    body = MESSAGE_BODY
})
local response_body = {}
local result_code, result_status
_, result_code, resp_headers, result_status = https.request({
    method = "POST",
    url = "https://privatemessages.roblox.com/v1/messages/send",
    headers = {
        ["Cookie"] = ".ROBLOSECURITY=" .. ROBLOX_SECURITY,
        ["Content-Type"] = "application/json",
        ["Origin"] = "https://www.roblox.com",
        ["Referer"] = "https://www.roblox.com/",
        ["X-CSRF-TOKEN"] = csrf_token,
        ["Content-Length"] = #request_body
    },
    source = ltn12.source.string(request_body),
    sink = ltn12.sink.table(response_body)
})

print("请求返回码:" .. tostring(result_code))
print("返回内容:" .. table.concat(response_body))

注意:如果账号开启了两步验证,或者Roblox升级了反爬策略,可能还需要补充更多浏览器特征头,或者处理验证码校验逻辑。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 20:27:26