I have an issue with the authorization in Google Contacts.
Until June my console C# application worked.
I have made steps to get contacts https://developers.google.com/google-apps/contacts/v3/?hl=en.
I cannot get the contacts; I have only access to serviceAccountEmail (xxxxxxxxxxxxxxxxxxx#developer.gserviceaccount.com).
I have 2 contacts stored there and I have access only to them.
I want to have access to my 7000 Gmail contacts.
Is there any tutorial for this in C#?
I found ones for analytics and for calendar but not for contacts.
Below is my code:
const string serviceAccountEmail = "xxxxxxxxxxxxxxxxxxx#developer.gserviceaccount.com";
var certificate = new X509Certificate2("grdom-all-xxxxxxxxxxxx.p12", "notasecret",
X509KeyStorageFlags.Exportable);
ServiceAccountCredential.Initializer serviceAccountCredentialInitializer =
new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
Scopes = new[] { "https://www.google.com/m8/feeds/" },
}.FromCertificate(certificate);
var credential = new ServiceAccountCredential(serviceAccountCredentialInitializer);
if (!credential.RequestAccessTokenAsync(CancellationToken.None).Result)
throw new InvalidOperationException("Access token request failed.");
var oauthParameters = new OAuth2Parameters()
{
AccessToken = credential.Token.AccessToken,
AccessType = "offline",
ApprovalPrompt = "force",
};
var settings = new RequestSettings("grdom-all", oauthParameters)
{
AutoPaging = true,
UseSSL = true,
};
ContactsRequest cr = new ContactsRequest(settings);
var query = new ContactsQuery(ContactsQuery.CreateContactsUri("default"));
Feed<Contact> f = cr.GetContacts();
foreach (Contact entry in f.Entries)
{
//do something
};
Related
I'm using PeopleService in order to create contacts straight into my G Suit Account. I followed the security steps about getting the key for a type of Service Account. My Application will create contacts so that there's no need to request a specific user permission. It has its own key and credentials.
My code seems to work except because the CreateContactRequest provides me ResourceName with value "people/c171255166120767303". And every time I request I got a different resourceName like this "people/c9013378989213012841".
The problem is, where the hell that goes? At my G Suite account, I can’t see the created contact anywhere.
But the resulting Person object seems to be ok.
How can I check if this works? Where the contact was created?
The code is as bellow:
private static string _clientId = "1........1";
private static string _clienteScret = "i******************_";
private static string _serviceAccountId = "aaaa#bbbb.iam.gserviceaccount.com";
public static void Cadastrar(Models.SignupRequest message)
{
var chave =
#"D:\********.p12";
var certificate = new X509Certificate2(chave, "notasecret", X509KeyStorageFlags.Exportable);
var credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(_serviceAccountId)
{
Scopes = new[] {
PeopleService.Scope.Contacts,
PeopleService.Scope.ContactsReadonly,
"https://www.google.com/m8/feeds"
}
}.FromCertificate(certificate));
var service = new PeopleService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "Client for www",
});
var contactToCreate = new Person();
var names = new List<Name> {new Name() {GivenName = message.name, FamilyName = "Doe"}};
contactToCreate.Names = names;
contactToCreate.EmailAddresses = new List<EmailAddress>
{
new EmailAddress()
{
DisplayName = message.name,
Value = message.email
}
};
contactToCreate.Organizations = new List<Organization>
{
new Organization()
{
Current = true,
Name = message.nome_fantasia,
}
};
contactToCreate.Biographies = new List<Biography>
{
new Biography()
{
Value = message.ToString()
}
};
contactToCreate.PhoneNumbers = new List<PhoneNumber>
{
new PhoneNumber()
{
Type = "mobile",
Value = message.celular
},
new PhoneNumber()
{
Type = "work",
Value = message.telefone
}
};
var request = new Google.Apis.PeopleService.v1.PeopleResource.CreateContactRequest(service, contactToCreate);
var createdContact = request.Execute();
}
If you want to create contact for user with 'email#yourdomain.com' through a service account you need:
Use "setServiceAccountUser(userEmail)" to impersonate the user
Enable impersonation on your G-Suite for People API service. For this point:
See section "Delegating domain wide access" here
Get client-id from your credential account
Use "https://www.googleapis.com/auth/contacts" as scope.
I am trying to update custom dimension fields(https://developers.google.com/analytics/devguides/config/mgmt/v3/mgmtReference/management/customDimensions/update) in google analytics by calling the analytics api from C#.
I created a project in https://console.developers.google.com, added a service account(downloaded the .p12, private key file),enabled the analytics api and linked the service account email in https://analytics.google.com
I am able to read the "analytics data"(like account summaries etc) but not insert or update. When I try to do that, I get the Insufficient permission 403 error. The service account added to google analytics has all the privileges.
class Program
{
static void Main(string[] args)
{
test();
}
public static void test() //takes clientid as input
{
string[] scopes = new string[] { AnalyticsService.Scope.Analytics }; // view and manage your Google Analytics data
var keyFilePath = #"C:\Users\xyz\Desktop\CustomDimUpdate\xxxxxxxx.p12"; // Downloaded from https://console.developers.google.com
var serviceAccountEmail = "xxxx.iam.gserviceaccount.com"; // found https://console.developers.google.com
//loading the Key file
var certificate = new X509Certificate2(keyFilePath, "notasecret", X509KeyStorageFlags.Exportable);
var credential = new ServiceAccountCredential(new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
Scopes = scopes
}.FromCertificate(certificate));
var service = new AnalyticsService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential
//ApplicationName = "Analytics API Sample",
});
CustomDimension body = new CustomDimension();
body.Name = "Configurable"; //Found in https://analytics.google.com
body.Scope = "Product"; //Found in https://analytics.google.com
body.Active = true;
try
{
//analytics.management().customDimensions()
// .update("123456", "UA-123456-1", "ga:dimension2", body).execute();
ManagementResource.CustomDimensionsResource.UpdateRequest update = service.Management.CustomDimensions.Update(body, "123456", "UA-123456-1", "ga:dimension1");
update.Execute(); //Errors out here
ManagementResource.AccountsResource.ListRequest list = service.Management.Accounts.List();
list.MaxResults = 1000; // Maximum number of Accounts to return, per request.
Accounts feed1 = list.Execute(); //Works perfectly fine
foreach (Account account in feed1.Items)
{
// Account
Console.WriteLine(string.Format("Account: {0}({1})", account.Name, account.Id));
}
ManagementResource.ProfilesResource.ListRequest list1 = service.Management.Profiles.List("123456", "UA-123456-1");
Profiles feed = list1.Execute();
foreach (Profile profile in feed.Items)
{
Console.WriteLine(string.Format("\t\tProfile: {0}({1})", profile.Name, profile.Id));
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
I was able to resolve this by changing the below line of code
string[] scopes = new string[] { AnalyticsService.Scope.Analytics }; // view and manage your Google Analytics data
to
string[] scopes = new string[] { AnalyticsService.Scope.AnalyticsEdit }; // view and manage your Google Analytics data
I followed this instruction (Using Azure GraphClient API how can you create a new Native Application?) and I could create a native application by Azure Graph Client. However, I don't know how to grant permissions by Graph API.
This is my code:
var app = new Application()
{
DisplayName = "appNativeName",
Homepage = "https://stackoverflow.com",
RequiredResourceAccess = new List<RequiredResourceAccess>()
{
new RequiredResourceAccess {
ResourceAppId = "00000002-0000-0000-c000-000000000000", //Azure AD
ResourceAccess = new List<ResourceAccess>
{
new ResourceAccess {Id = Guid.Parse("my guid id"), Type = "Scope" }
}
}
},
PublicClient = true //native app
};
await azureADContext.Applications.AddApplicationAsync(app);
var obj = app.ObjectId;
var appId = app.AppId;
I really appreciate your help.
I am creating shared contacts in google, it creates the contact, but I can't see the contacts in the directory in google contacts.
I have looked for answers and found this probably closest.. but I can't seem to get it right...
Here is some code:
string s = "https://www.google.com/m8/feeds";
string targetUri = #"https://www.google.com/m8/feeds/contacts/mycompany.com/full";
string serviceAccountEmail = "123456789012-xxxx1x1xx11x1xxxxxxx11xxxx1xxx11#developer.gserviceaccount.com";
string serviceClientId = "123456789012-xxxx1x1xx11x1xxxxxxx11xxxx1xxx11.apps.googleusercontent.com";
X509Certificate2 certificate = new X509Certificate2(#"C:\All\mygcertificate-1xx1xxx1xx11.p12", "notasecret", X509KeyStorageFlags.Exportable);
ServiceAccountCredential credential = new ServiceAccountCredential(new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
Scopes = new[]
{
"http://www.google.com/m8/feeds/contacts/"
},
User = "my.user#mycompany.com"
}.FromCertificate(certificate));
string AuthenticationToken1 = string.Empty;
if (credential.RequestAccessTokenAsync(CancellationToken.None).Result)
{
AuthenticationToken1 = credential.Token.AccessToken;
}
Service service = new Service(s, serviceClientId);
GAuthSubRequestFactory factory = new GAuthSubRequestFactory(s, serviceClientId);
factory.Token = AuthenticationToken1;
service.RequestFactory = factory;
Contact ct = new Contact();
ct.Name = new Google.GData.Extensions.Name() { GivenName = "Ron", FamilyName = "Swanson", FullName = "Ron Swanson" };
ct.Emails.Add(new Google.GData.Extensions.EMail("Ron.Swanson#someclient.com", #"http://schemas.google.com/g/2005#work") { Primary = true });
ct.Phonenumbers.Add(new Google.GData.Extensions.PhoneNumber("2345555522") { Rel = #"http://schemas.google.com/g/2005#work", Primary = true});
AtomCategory atc = new AtomCategory();
atc.Term = #"http://schemas.google.com/contact/2008#contact";
atc.Scheme = #"http://schemas.google.com/g/2005#kind";
ct.Categories.Add(atc);
var atomentrytoinsert = ct.AtomEntry;
var result = service.Insert(new Uri(targetUri), atomentrytoinsert);
//Stream getresult = service.Query(new Uri(targetUri)); //this read actually gets the records i inserted...
If i run that last commented out line, i can see the entries I created ... but when I go to google contacts and click directory - They are not there. Also not on autocomplete when I compose email... Am I missing a attribute somewhere.
I have left the entries over 24 hours (I created them on Friday).
Would appreciate any input.
I tryed the sharedcontact API yesterday, the new contacts were not visible in directory.
But this morning the autocomplete has suggested the new contacts! To make them visible in the directory I had to open the Admin google Console->google apps-> contacts -> advanced settings and checked the " shows both the profiles of the domain is the Domain Shared Contacts"
It worked immediately for me, I hope help you!
I am using the Google Analytics Api to get web property information from my Analytics account.
When I log into analaytics though, I only have one website, but through the api I get several (old and deleted sites)
My code is like this:
var provider = new WebServerClient(GoogleAuthenticationServer.Description)
{
ClientIdentifier = _appId,
ClientSecret = _appSecret
};
var auth = new OAuth2Authenticator<WebServerClient>(provider, x => new AuthorizationState { AccessToken = token });
var analyticsService = new AnalyticsService(auth);
var accounts = analyticsService.Management.Accounts.List().Fetch();
foreach (var account in accounts.Items)
{
var webProperties = analyticsService.Management.Webproperties.List(account.Id).Fetch();
// todo: determine if web property is still in use?
}
From code how can I tell which ones are still active?
So after a bit more digging.
It seems there is no flag or anything like that indicating it has been removed, but if you keep digging into the result set you will notice that at the profile level, a profile that doesn't have child items seems to be a deleted one.
Which makes sense I guess there wouldn't be a profile associated with those that have been removed.
var provider = new WebServerClient(GoogleAuthenticationServer.Description)
{
ClientIdentifier = _appId,
ClientSecret = _appSecret
};
var auth = new OAuth2Authenticator<WebServerClient>(provider, x => new AuthorizationState { AccessToken = token });
var analyticsService = new AnalyticsService(auth);
var accounts = analyticsService.Management.Accounts.List().Fetch();
var result = new List<Profile>();
foreach (var account in accounts.Items)
{
var webProperties = analyticsService.Management.Webproperties.List(account.Id).Fetch();
foreach (var webProperty in webProperties.Items)
{
var profiles = analyticsService.Management.Profiles.List(account.Id, webProperty.Id).Fetch();
if (profiles.Items != null && profiles.Items.Any())
{
// these are the ones we want
result.AddRange(profiles.Items);
}
}
}
}