I am using this code and it works and allows my app to get the Calendar List from the used google account.
UserCredential credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
new ClientSecrets
{
ClientId = "xxx",
ClientSecret = "xxxx-xxxx",
},
new[] { CalendarService.Scope.Calendar },
"support#xxx.com",
CancellationToken.None).Result;
// Create the service.
var service = new CalendarService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "xxx",
});
CalendarListResource.ListRequest cal = service.CalendarList.List();
cal.MaxResults = 10;
var calresult = cal.Execute().Items;
My question is when i do this i than import all the Calender's And Events to my local database so after an hour i need to run a script to update the Database with the latest Calendar and Event info as they might have added new Events or deleted some same goes with Calender's.
Not sure where to look for any suggestion?
For others:
The answer is here:
How to access users calendar list and events from google api using access token and refresh token
Basically you save the token and later user it for that Calendar.
Related
I want to access Google Drive to upload files using Google.Apis.Drive.v3.
Here is my code:
protected async void btnConnectGoogleDrive_Click(object sender, EventArgs e)
{
string[] Scopes = { DriveService.Scope.Drive };
UserCredential credential;
credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
new ClientSecrets
{
ClientId = "",
ClientSecret = ""
},
Scopes,
"user",
CancellationToken.None);
InsertGoogleDriveToken(credential.Token.AccessToken, areaID, "accesstoken");
InsertGoogleDriveToken(credential.Token.RefreshToken, areaID, "refreshtoken");
// Create Drive API service.
var service = new DriveService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "SocialLadder",
});
GoogleDriveUpload(service, areaID);
}
Here I am able to get the AccessToken and RefreshToken but user is not redirected to permission page, so when I try to upload images to drive it gives me error that "permission_not_granted". Used same thing in MVC and that works great.
Please help me with this issue.
I suspect that you have changed your scopes. You need to authenticate the user. Do one of the following
Go to %appdata% and delete the creditlas file for this user.
change "user" to something else say "user1"
Your application should then require the user to authenticate again.
My app should create an event in users calendar.
I have refresh token for all user I want to create a new event in their calendar.
I use NuGet package for google calendar client, but when I init google calendar client I can to init only single refresh token.
var token = new TokenResponse { RefreshToken = "single token only" };
var credentials = new UserCredential(new
GoogleAuthorizationCodeFlow(
new GoogleAuthorizationCodeFlow.Initializer {
ClientSecrets = new ClientSecrets() {
ClientId = "id",
ClientSecret = "secret"
}
}
),
"user",
token
);
var calenderClient = new CalendarService(new BaseClientService.Initializer() {
HttpClientInitializer = credential,
ApplicationName = ApplicationName,
});
how can I add another user refresh token?
Thanks
This is how the api works. You get a refresh token for each user you authenticated for that user and then you can add something to their calendar. When you want to do the same for another user you will need to authenticate using the refresh token for that user and then add the event.
Your code looks good just loop it for each refresh token.
I want to fetch the list of people in all the circles of a user's Google plus account.
I am using the Google People API but the list always returns 0.
The code is as below:
string[] scopes = new string[] {PlusService.Scope.PlusLogin,
PlusService.Scope.UserinfoEmail,
PlusService.Scope.UserinfoProfile};
string credPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
credPath = Path.Combine(credPath, ".credentials/", System.Reflection.Assembly.GetExecutingAssembly().GetName().Name);
UserCredential credential =
GoogleWebAuthorizationBroker.AuthorizeAsync(new ClientSecrets
{
ClientId = "someid",
ClientSecret = "somekey"
},
scopes,
Environment.UserName,
CancellationToken.None,
new FileDataStore(credPath,true)
).Result;
PlusService service = new PlusService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "Google Plus Sample",
});
PeopleResource.ListRequest listPeople = service.People.List("me", PeopleResource.ListRequest.CollectionEnum.Visible);
listPeople.MaxResults = 10;
PeopleFeed peopleFeed = listPeople.Execute();
If you check the documentation for people.list you can see that this method doesnt work anymore.
The Google+ People API list endpoint is deprecated. Consider using the Google People API instead.
You can try and switch to the google people api but this is not a list of the users on Google+ IIR its a list of peolpe the user has setup in Google contacts.
I need to be able to use a refresh token to be able to re-authenticate a token after the access token has expired. How can I do this using the C# v3 API? I've looked at the UserCredential class and AuthorizationCodeFlow class and nothing is jumping out at me.
I'm using the following code to authenticate it originally.
var result = await new AuthorizationCodeMvcApp(this, new AppFlowMetadata()).
AuthorizeAsync(CancellationToken.None);
if (result.Credential != null)
{
var service = new YouTubeService(new BaseClientService.Initializer
{
HttpClientInitializer = result.Credential,
ApplicationName = "YouTube Upload Tool"
});
}
And this is my AppFlowMetadata class.
public class AppFlowMetadata : FlowMetadata
{
private static readonly IAuthorizationCodeFlow flow =
new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
{
ClientSecrets = new ClientSecrets
{
ClientId = "ID",
ClientSecret = "SECRET",
},
Scopes = new[] { YouTubeService.Scope.YoutubeUpload },
DataStore = new EFDataStore(-1) // A data store I implemented using Entity Framework 6.
});
public override string GetUserId(Controller controller)
{
return "test";
}
public override IAuthorizationCodeFlow Flow
{
get { return flow; }
}
}
If anyone can suggest anything, I would greatly appreciate it. Thank you.
While this is not an answer, this is how I got around it. I had to create the GET request for authorisation (redirect your user to the url you get back and set your Controller Action to receive the callback specified in your Google Developer Console) and the PUT request for the Token (which I then stored using EF6) manually. I used System.Net.Http.HttpClient to make these requests, which was quite straight forward. See this link for all the details I needed to get this working.
It was the only way I could set the access_type to "offline". If the .NET API does this, I'm still curious to find out how.
With the token data stored, I now use the API to validate and refresh the token when I need to. I actually did this in a server side console application rather than a MVC app (hence the EF token persistence).
UserCredential credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
new ClientSecrets
{
ClientId = "ID",
ClientSecret = "Secret"
},
new[] { YouTubeService.Scope.YoutubeUpload },
"12345",
CancellationToken.None,
new EFDataStore(-1) // My own implementation of IDataStore
);
// This bit checks if the token is out of date,
// and refreshes the access token using the refresh token.
if(credential.Token.IsExpired(SystemClock.Default))
{
if (!await credential.RefreshTokenAsync(CancellationToken.None))
{
Console.WriteLine("No valid refresh token.");
}
}
var service = new YouTubeService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "MY App"
});
I hope this helps others.
I am trying to get google users from my domain using google service account.
But it throws error
Error:"access_denied", Description:"Requested client not authorized.", Uri:""
My code
X509Certificate2 certificate = new X509Certificate2(key_path,
"notasecret", X509KeyStorageFlags.Exportable);
ServiceAccountCredential credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer("publickey.gserviceaccount.com")
{ Scopes = scopes,
User = "admin#domain.com"
}.FromCertificate(certificate));
var service = new DirectoryService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "appname",
});
service.Users.List().Domain = "domain.com";
Users results = service.Users.List().Execute();
Thanks in advance
The service account email address needs to have access the domain. Take the email and add it as a user just enough access that it can read should be good.
Also did you change this for posting?
"publickey.gserviceaccount.com"
A service account email looks more like this:
539621478854-imkdv94bgujcom228h3ea33kmkoefhil#developer.gserviceaccount.com
You need to give your service-account/API project access to your domain first.
Steps detailed in the docs here:
https://developers.google.com/admin-sdk/directory/v1/guides/delegation#delegate_domain-wide_authority_to_your_service_account
You need to specify the correct scopes you need in step 6 of those instructions, which would be https://www.googleapis.com/auth/admin.directory.user.readonly to access the list of users.
In addition for the Directory API to work you need to enable API access in the domain settings: https://developers.google.com/admin-sdk/directory/v1/guides/prerequisites#set_up_api
I was finally able to get this working. Here is the code I have
var grpReq = service.Groups.List();
grpReq.Domain = "mydomain.com";
Groups groups = grpReq.Execute();
IList<Group> gps = groups.GroupsValue;
var memReq=service.Members.List(groups.GroupsValue[0].Id);
Members members = memReq.Execute();
I am still not sure why creating a var object and then Execute() got this to work but the earlier code didn't work.
I still have the problem of the consent screen showing up for all users. I have the following code. I think the way I get the logged in user's email is incorrect. Any ideas?
string mymail = googleauth.GetUsersEmail(ExchangeCodeWithAccessAndRefreshToken().Access_Token);
string path = "d:\\c6b82065f26fbb0-privatekey.p12";
X509Certificate2 certificate = new X509Certificate2(
path,
"notasecret", X509KeyStorageFlags.Exportable);
ServiceAccountCredential credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer("876131792-v824u6drpss#developer.gserviceaccount.com")
{
User = mymail,
Scopes = new[] { PlusService.Scope.UserinfoEmail, PlusService.Scope.UserinfoProfile, PlusService.Scope.PlusMe }
}.FromCertificate(certificate));
PlusService plus = new PlusService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "myapp"
});
Person profile = plus.People.Get("me").Execute();
string email = profile.Emails[0].Value;