Search code examples
c#.netgmailgoogle-api-dotnet-clientgoogle-people-api

Accessing Gmail contacts via the Google People API using service account credentials always returning null


I cannot access Gmail contacts with the following code. It always returns null, and all API permissions are granted with contacts inside the account.

string jsonText = @"{""type"": ""service_account"",
    ""project_id"": """",
    ""private_key_id"": """",
    ""private_key"": """",
    ""client_email"": """",
    ""client_id"": """",
    ""auth_uri"": """",
    ""token_uri"": """",
    ""auth_provider_x509_cert_url"": """",
    ""client_x509_cert_url"": """"
}";

var credentialParameters = NewtonsoftJsonSerializer.Instance.Deserialize<JsonCredentialParameters>(jsonText);

// Credentials
var credential = new ServiceAccountCredential(new ServiceAccountCredential.Initializer(credentialParameters.ClientEmail)
{
    User = credentialParameters.ClientEmail,
    Scopes = new[] { "https://www.googleapis.com/auth/contacts.readonly",
                     "https://www.googleapis.com/auth/contacts",
                     "https://www.googleapis.com/auth/contacts.other.readonly " }
                   }.FromPrivateKey(credentialParameters.PrivateKey));

// accessToken
var accessToken = await credential.GetAccessTokenForRequestAsync();

// Create the service.
var service = new PeopleServiceService(new BaseClientService.Initializer()
{
    HttpClientInitializer = credential,
});

GoogleCredential googleCredentials = GoogleCredential.FromJson(jsonText);

var ser = new PeopleServiceService(new BaseClientService.Initializer()
{
    HttpClientInitializer = googleCredentials,
});

// Get list of contacts
ConnectionsResource.ListRequest peopleRequest = ser.People.Connections.List("people/me");

peopleRequest.PersonFields = "names,emailAddresses";
ListConnectionsResponse response = peopleRequest.Execute();
IList<Person> people = response.Connections;

Solution

  • Side note:

    Cannot access Gmail contacts

    It is unclear if you are using a standard Gmail account or working with Google Workspace. You should be aware that Service accounts are not going to work with a standard Gmail user's contacts. There is no way to delegate the permission without workspace.


    Remember a service account is not you. A service account is a dummy user. Its returning null or empty because your service account does not currently have any contacts. You would need to add some.

    However if you are trying to access contacts for a user then.

    In order for a service account to access a users data you need to have delegated to that user. Trying to access Google contacts you will need to go though your workspace account. The workspace admin can set up domain wide delegation to the user on your domain whose contacts you would like to access.

    Make sure that you have included the Domain scope as shown in the documentation.

    Then remember to add the user when you initialize the service account this must be a user on your domain for which you have set up delegation for.

    var serviceAccountCredentialInitializer = new  ServiceAccountCredential.Initializer(serviceAccount)
    {
        User = gsuiteUser,
        Scopes = new[] { GmailService.Scope.GmailSend, GmailService.Scope.GmailLabels }
    
    }.FromCertificate(certificate);