我看过很多关于用户的 Google API 客户端的文档,但关于使用服务帐户的文档很少。这不代表用户,我只是想让一个客户端使用客户端 ID 和客户端密码来使用日历 API,这将通过环境变量为我提供(我不想从一个文件)。
这是我目前所拥有的:
package main
import (
"context"
clientCredentials "golang.org/x/oauth2/clientcredentials"
google "golang.org/x/oauth2/google"
calendar "google.golang.org/api/calendar/v3"
apiOption "google.golang.org/api/option"
)
func main() {
config := &clientCredentials.Config{
ClientID: "<my_id>",
ClientSecret: "-----BEGIN PRIVATE KEY-----\n...",
TokenURL: google.Endpoint.TokenURL,
}
ctx := context.Background()
client := config.Client(ctx)
service, _ := calendar.NewService(ctx, apiOption.WithHTTPClient(client))
calendarList, err := service.CalendarList.List().Do()
}
但是我收到以下错误:
Get "https://www.googleapis.com/calendar/v3/users/me/calendarList?alt=json&prettyPrint=false": oauth2: cannot fetch token: 400 Bad Request
Response: {
"error": "unsupported_grant_type",
"error_description": "Invalid grant_type: client_credentials"
}
非常感谢这里的任何帮助!我是 Golang、Oauth2 和 Google API 的新手:)
我相信你的目标如下。
这样的话,下面的修改怎么样?
package main
import (
"context"
"fmt"
calendar "google.golang.org/api/calendar/v3"
"google.golang.org/api/option"
)
func main() {
ctx := context.Background()
v := `{"type": "service_account", "private_key": "-----BEGIN PRIVATE KEY-----\n###\n-----END PRIVATE KEY-----\n", "client_email": "###"}`
service, _ := calendar.NewService(ctx, option.WithCredentialsJSON([]byte(v)))
calendarList, _ := service.CalendarList.List().Do()
fmt.Println(calendarList)
}
如果要使用包含凭据信息的文件,请修改如下。
service, _ := calendar.NewService(ctx, option.WithCredentialsFile(credentialFile))
如果您想找回您账户的谷歌日历,请将您的谷歌日历分享给服务账户的邮箱。
Linda Lawton - DaImTo 的评论:
Google calendar doesn't support service account for standard google users. You need to configure domain wide delegation and impersonate a user on your google workspace account. and how to add the sub to this code.
@Tanaike 的回答让我走上了正确的轨道。这就是我最终使用的:
package main
import (
"context"
"encoding/json"
"fmt"
googleOauth "golang.org/x/oauth2/google"
calendar "google.golang.org/api/calendar/v3"
apiOption "google.golang.org/api/option"
)
var service *calendar.Service
// Note that some of the fields are optional:
type GoogleAuthConfig struct {
Type string `json:"type"`
ProjectID string `json:"project_id,omitempty"`
ClientEmail string `json:"client_email"`
ClientID string `json:"client_id,omitempty"`
ClientSecret string `json:"private_key"`
ClientSecretID string `json:"private_key_id,omitempty"`
AuthURL string `json:"auth_uri,omitempty"`
TokenURL string `json:"token_uri,omitempty"`
AuthProviderCertURL string `json:"auth_provider_x509_cert_url,omitempty"`
ClientCertURL string `json:"client_x509_cert_url,omitempty"`
}
func main() {
authConfig := GoogleAuthConfig{
Type: "service_account",
ClientEmail: "[email protected]",
ClientID: "1234",
ClientSecret: "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n",
AuthURL: googleOauth.Endpoint.AuthURL,
TokenURL: googleOauth.Endpoint.TokenURL,
}
authConfigJson, err := json.Marshal(authConfig)
ctx := context.Background()
service, err = calendar.NewService(ctx, apiOption.WithCredentialsJSON([]byte(authConfigJson)))
}
请注意,我不必配置域范围的委派或模拟用户;在我将服务帐户添加到日历后,这工作正常。
服务帐号在您将帐号邮箱添加到日历后仍然需要接受日历邀请。这可以通过以下方式完成:
entry := calendar.CalendarListEntry{Id: calendarID}
service.CalendarList.Insert(&entry).Do()