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

GCP云函数中Go调用Google Chat API认证失败排查与解决

Go云函数调用Google Chat API认证错误排查与解决

问题背景

在GCP Cloud Function中使用Go语言调用Google Chat API时持续遇到认证错误,但相同配置下的Node.js版本实现可正常运行。

旧版google.golang.org/api/chat/v1实现代码

import (
    "context"
    "fmt"
    "google.golang.org/api/chat/v1"
)

func getMessage() {
    ctx := context.Background()
    c, err := chat.NewService(ctx)

    message, err := c.Spaces.Messages.Get("my id").Do()
    if err != nil {
        fmt.Printf("Error requesting message for %s: %v\n", t.Name, err)
        return
    }
}

触发错误:

Get "https://chat.googleapis.com/v1/spaces/../messages?alt=json&prettyPrint=false": credentials: cannot fetch token: compute: Received 500 `Could not fetch URI /computeMetadata/v1/instance/service-accounts/default/token?scopes=...

新版cloud.google.com/go/chat实现代码

import (
    chat "cloud.google.com/go/chat/apiv1"
    "cloud.google.com/go/chat/apiv1/chatpb"
    "context"
    "fmt"
)

func getMessage() {
    ctx := context.Background()
    c, err := chat.NewClient(ctx)
    request := &chatpb.GetMessageRequest{
        Name: "spaces/123/messages/456",
    }
    message, err := c.GetMessage(ctx, request)
    if err != nil {
        fmt.Printf("Error requesting message for %s: %v\n", t.Name, err)
        return
    }
}

触发错误:

Error requesting message for spaces/..: rpc error: code = Unauthenticated desc = transport: per-RPC creds failed due to error: credentials: cannot fetch token: compute: Received 500 Could not fetch URI /computeMetadata/v1/instance/service-accounts/default/token?scopes=...

差异原因

Node.js的Google Cloud客户端库会自动适配Cloud Function环境,默认补充Chat API所需的权限范围(scopes);而Go语言的客户端库不会自动添加Chat API的权限范围,Cloud Function默认服务账号的scopes不包含Chat API访问权限,导致请求元数据服务获取token时失败,触发500错误。

解决方法

方法1:代码中显式指定Chat API权限范围

在创建Chat服务客户端时,通过option.WithScopes传入所需的权限范围:

旧版库实现修改

import (
    "context"
    "fmt"
    "google.golang.org/api/chat/v1"
    "google.golang.org/api/option"
)

func getMessage() {
    ctx := context.Background()
    // 显式传入Chat API权限范围
    c, err := chat.NewService(ctx, option.WithScopes(chat.ChatScope))
    if err != nil {
        fmt.Printf("Failed to create chat service: %v\n", err)
        return
    }

    message, err := c.Spaces.Messages.Get("spaces/123/messages/456").Do()
    if err != nil {
        fmt.Printf("Error requesting message: %v\n", err)
        return
    }
}

新版库实现修改

import (
    chat "cloud.google.com/go/chat/apiv1"
    "cloud.google.com/go/chat/apiv1/chatpb"
    "context"
    "fmt"
    "google.golang.org/api/option"
)

func getMessage() {
    ctx := context.Background()
    // 按需求指定对应权限范围,示例为只读权限
    c, err := chat.NewClient(ctx, option.WithScopes("https://www.googleapis.com/auth/chat.messages.readonly"))
    if err != nil {
        fmt.Printf("Failed to create chat client: %v\n", err)
        return
    }
    request := &chatpb.GetMessageRequest{
        Name: "spaces/123/messages/456",
    }
    message, err := c.GetMessage(ctx, request)
    if err != nil {
        fmt.Printf("Error requesting message: %v\n", err)
        return
    }
}

提示:可根据业务需求选择合适的scope,比如https://www.googleapis.com/auth/chat.bot或https://www.googleapis.com/auth/chat.messages等。

方法2:部署时指定服务账号权限范围

通过gcloud部署命令,为Cloud Function显式添加Chat API的权限范围:

gcloud functions deploy YOUR_FUNCTION_NAME \
    --runtime go121 \
    --service-account YOUR_SERVICE_ACCOUNT \
    --scopes https://www.googleapis.com/auth/chat.messages.readonly

部署完成后,Go客户端会自动使用包含所需scope的服务账号凭证,无需在代码中额外配置。

额外检查项

  • 确认服务账号已拥有Chat Viewer或对应Chat API的访问权限(比如chat.messages.readonly权限)。
  • 本地测试时需设置GOOGLE_APPLICATION_CREDENTIALS环境变量,指向服务账号密钥文件路径。

内容的提问来源于stack exchange,提问作者Muhammad Dyas Yaskur

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 20:38:24