【问题标题】:Google Contacts API failing to retrieve contact information via a service accountGoogle Contacts API 无法通过服务帐户检索联系信息
【发布时间】:2025-12-21 09:45:11
【问题描述】:

我未能成功使用 Google Contacts API 从服务帐户检索联系信息(未使用实时用户会话)。无论我尝试什么,我要么得到一个异常(例如:Message = "Error:\"invalid_request\",Description:\"Invalid impersonation prn email address.\",Uri:\"\""),要么没有错误,但返回了 0 个联系人。

我已经仔细检查了 Google Apps 管理控制台和管理 API 客户端访问页面中的设置(包括从 Google App 技术支持获取这些设置的验证),但无论如何,我无法加载联系人。我还尝试了所有可以在“堆栈溢出”中找到的示例,但似乎都没有解决问题。

这些尝试已经在 C# / ASP.net 中进行,但我对其他语言足够精通,因此我应该能够改编任何可能有人可以使用的示例。

我希望有人成功地通过服务帐户使用 Google 通讯录 API,并愿意分享他们为实现这一目标所做的代码。

谢谢!!!

这是我尝试的示例,它总是导致异常“invalid_request\”:“Invalid impersonation prn email address.\”

    private void TestLoadContacts()
    {
        try
        {
            string strClientID = "STRINGGENERATEDFROMGOOGLEAPPSINTERFACE.apps.googleusercontent.com";
            var credential = GenerateCred(new[] { "https://www.google.com/m8/feeds" }, strClientID);

            // Get the token for this scope and user
            if (credential.RequestAccessTokenAsync(new CancellationToken()).Result)
            {
                // use the token to initalize the request
                var rs = new RequestSettings("Google Sync")
                {
                    OAuth2Parameters = new OAuth2Parameters()
                    {
                        AccessToken = credential.Token.AccessToken
                    }
                };

                var request = new ContactsRequest(rs);
                Feed<Contact> f = request.GetContacts();
                foreach (var c in f.Entries)
                {
                    //process each contact
                }
            }
        }
        catch (Exception ex)
        {
            string strError = ex.Message;
        }
    }

    private static ServiceAccountCredential GenerateCred(IEnumerable<string> scopes, string delegationUser)
    {
        string strServiceAccountEmail = "account-1@MyGoogleAccount-1139.iam.gserviceaccount.com";
        X509Certificate2 certificate = new X509Certificate2(@"C:\MyP12s\MyGoogleAccount-9da1a08f4eef.p12",
            "notasecret", X509KeyStorageFlags.Exportable);

        var credential = new ServiceAccountCredential(
            new ServiceAccountCredential.Initializer(strServiceAccountEmail)
            {
                Scopes = scopes,
                User = delegationUser
            }.FromCertificate(certificate));
        return credential;
    }

【问题讨论】:

    标签: google-app-engine google-contacts-api google-shared-contacts


    【解决方案1】:

    检索联系人应该很容易完成(在Google Contacts API documentation 中引用)

    使用服务帐户本身的问题更多吗?如果是这样,您需要启用对服务帐户的域范围委派(更多信息可以在here 中找到;这也链接在上面的参考资料中)。基本上,您需要将要使用的特定范围添加到授权服务帐户。

    希望这会有所帮助!

    【讨论】:

    • 感谢您的想法。但是,我认为我可能已经在我的服务帐户中设置了适当的范围 (google.com/m8/feeds)。这是我如何设置它的屏幕截图。这在某种程度上是错误的吗?
    • 嗯——我无法提供屏幕截图,但这是我在“安全”->“管理 API 客户端访问”页面中的值。在授权 API 客户端列中,我有以下内容:“STRINGGENERATEDFROMGOOGLEAPPSINTERFACE.apps.googleusercontent.com”(与我在提供的代码 sn-p 中放入 strClientID 的值相同);在一个或多个 API 范围中,我有:“google.com/m8/feeds。”这在某种程度上是错误的吗?