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

Discord无法验证Golang AWS Lambda交互端点问题排查

问题描述

我想要搭建一个通过HTTP端点交互的Discord机器人,采用Golang编写的AWS Lambda并通过AWS API Gateway暴露,但在设置“INTERACTIONS ENDPOINT URL”时,Discord提示端点无法验证。日志显示第一个请求成功通过头部验证并响应了PING,但第二个请求出现授权错误。相同代码在另一个项目中可正常运行。

核心处理函数

func handler(request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {

    rawBody := request.Body
    fmt.Println("start")

    // validate nacl header
    err := validator.verifyRequest(
        request.Headers["x-signature-ed25519"],
        request.Headers["x-signature-timestamp"],
        request.Body,
    )
    if err != nil {
        fmt.Println("StatusUnauthorized")
        return formatUnauthorizedResponse()
    }

    discordRequest := DiscordRequestDto{}
    err = json.Unmarshal([]byte(rawBody), &discordRequest)

    // validate ping
    fmt.Println("test ping")
    if validator.IsPing(discordRequest.Type) {
        fmt.Println("is ping !")
        return formatPingResponse()
    }

    return formatResponse("ok")
}

日志详情

START RequestId: 590104c1-4353-4153-8708-614c6afcdbbc Version: $LATEST
start
test ping
is ping !
ping
END RequestId: 590104c1-4353-4153-8708-614c6afcdbbc
REPORT RequestId: 590104c1-4353-4153-8708-614c6afcdbbc  Duration: 36.13 ms  Billed Duration: 37 ms  Memory Size: 128 MB Max Memory Used: 29 MB  Init Duration: 97.97 ms 
START RequestId: b9e94769-0b0d-421b-91c3-72748f333567 Version: $LATEST
start
StatusUnauthorized
END RequestId: b9e94769-0b0d-421b-91c3-72748f333567
REPORT RequestId: b9e94769-0b0d-421b-91c3-72748f333567  Duration: 18.34 ms  Billed Duration: 19 ms  Memory Size: 128 MB Max Memory Used: 30 MB  

完整代码

代码位于GitHub仓库DavidVergison/discord-bot-error中


解决方案

问题出在未处理AWS Lambda请求中的IsBase64Encoded标志。AWS API Gateway会根据请求体类型,将部分请求的body以base64编码形式传递给Lambda:

  • 第一个PING请求的body内容简单,未被base64编码,直接使用request.Body验证通过;
  • 第二个请求的body被API Gateway编码为base64,你直接用编码后的字符串参与签名验证,导致和Discord生成签名时的原始body不匹配,验证失败。

修改handler函数,先判断IsBase64Encoded并解码body:

func handler(request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
    fmt.Println("start")

    // 处理base64编码的body
    var rawBody string
    if request.IsBase64Encoded {
        decodedBytes, err := base64.StdEncoding.DecodeString(request.Body)
        if err != nil {
            fmt.Println("Failed to decode base64 body")
            return formatUnauthorizedResponse()
        }
        rawBody = string(decodedBytes)
    } else {
        rawBody = request.Body
    }

    // validate nacl header
    err := validator.verifyRequest(
        request.Headers["x-signature-ed25519"],
        request.Headers["x-signature-timestamp"],
        rawBody, // 使用解码后的原始body
    )
    if err != nil {
        fmt.Println("StatusUnauthorized")
        return formatUnauthorizedResponse()
    }

    discordRequest := DiscordRequestDto{}
    err = json.Unmarshal([]byte(rawBody), &discordRequest)
    if err != nil {
        fmt.Println("Failed to unmarshal request")
        return formatUnauthorizedResponse()
    }

    // validate ping
    fmt.Println("test ping")
    if validator.IsPing(discordRequest.Type) {
        fmt.Println("is ping !")
        return formatPingResponse()
    }

    return formatResponse("ok")
}

同时需确保API Gateway的集成设置中,Content Handling配置为Passthrough,避免API Gateway修改原始请求体内容。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 15:53:11