I'm using Google Sheet API V4 in C#.
My source will create new Excel file, write data to that file.
When execute, Google API will open a new OAuth tab on the browser, User will choose/login to an email on this tab, and grant Read/Write/All permission for my App.
My question is: How can I get Logged/permitted email address in C# source?
I want to know, what email did the user log in to create myfile.xlsx.
Thanks in advance.
Code snippet:
string[] Scopes = { SheetsService.Scope.DriveFile };
string ApplicationName = "Google Sheets API";
UserCredential credential;
using (var stream =
new FileStream("credentials.json", FileMode.Open, FileAccess.Read))
{
// The file token.json stores the user's access and refresh tokens, and is created
// automatically when the authorization flow completes for the first time.
string credPath = "token.json";
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
Scopes,
"UserName",
CancellationToken.None,
new FileDataStore(credPath, true)).Result;
Console.WriteLine("Credential file saved to: " + credPath);
}
var fileName = "myfile.xlsx";
var myNewSheet = new Spreadsheet();
myNewSheet.Properties = new SpreadsheetProperties();
myNewSheet.Properties.Title = fileName;
var sheet = new Sheet();
sheet.Properties = new SheetProperties();
sheet.Properties.Title = $"data";
myNewSheet.Sheets = new List<Sheet>() { sheet };
var newSheet = service.Spreadsheets.Create(myNewSheet).Execute();
var spreadSheetId = newSheet.SpreadsheetId;
...........
// Write data to file source
Google Indentiy platform describes the procedure of how to authenticate a user to obtain user information and more specifically user profile information
The documentation does not specify how exactly to do it in C#, but basically
Make a GET request to https://www.googleapis.com/oauth2/v3/userinfo
Provide the scopes https://www.googleapis.com/auth/userinfo.profile and https://www.googleapis.com/auth/userinfo.email
There is a good sample on Stackoverflow how to do it in PHP - I hope it helps you with the implementation in C#
There is also a workaround authenticating users with Gmail
Related
I have a question about how correctly add a contact to Google Contacts using Google API.
For authorization I use external Json file Generated.
When I execute it , it doesn't give any mistakes but No Contact is Added to Google Contacts.
What can be wrong with the code?
Please find code below
Thanks
private async Task Run()
{
GoogleCredential credential;
using (Stream stream = new FileStream(#"D:\project1.json", FileMode.Open, FileAccess.Read, FileShare.Read))
{
credential = GoogleCredential.FromStream(stream);
}
string[] scopes = new string[] {
PeopleServiceService.Scope.Contacts,
PeopleServiceService.Scope.ContactsReadonly,
PeopleServiceService.Scope.ContactsOtherReadonly,
};
credential = credential.CreateScoped(scopes);
BaseClientService.Initializer initializer = new BaseClientService.Initializer()
{
HttpClientInitializer = (IConfigurableHttpClientInitializer)credential,
ApplicationName = "Project1",
GZipEnabled = true,
};
PeopleServiceService service = new PeopleServiceService(initializer);
Person contactToCreate = new Person();
List<Name> names = new List<Name>();
names.Add(new Name() { GivenName = "Alex", FamilyName = "Breen", DisplayName = "Alex Breen" });
contactToCreate.Names = names;
List<PhoneNumber> phoneNumbers = new List<PhoneNumber>();
phoneNumbers.Add(new PhoneNumber() { Value = "11-22-33" });
contactToCreate.PhoneNumbers = phoneNumbers;
List<EmailAddress> emailAddresses = new List<EmailAddress>();
emailAddresses.Add(new EmailAddress() { Value = "AlexBreen#mail.com" });
contactToCreate.EmailAddresses = emailAddresses;
PeopleResource.CreateContactRequest request = new PeopleResource.CreateContactRequest(service, contactToCreate);
Person createdContact = request.Execute();
Console.WriteLine(request);
}
Results
Metrics
You need to go though your service object.
var request = service.People.CreateContact(new Person()
{
Names = new List<Name>() { new Name() { DisplayName = "test"}}
// Fill in the rest of the person object here.
});
var response = request.Execute
Make sure you are checking google contacts from the same user you are authenticating your application from.
The response should be returning the new user.
all contacts for a user
You can also test it by doing. This will give you a list of the users inserted for the user you have authorized.
var results = service.People.Connections.List("people/me").Execute();
who is the current user
var results = service.People.Get("people/me").Execute();
var results = service.People.Connections.List("people/me").Execute();
service accounts
A service account is not you. Think of a service account more as a dummy user it has its own Google contacts account. When you insert into it you are inserting into the account owned by the service account.
If you have google workspace you can set up domain wide deligation to the service account and then delegate to users on the domain and add contacts to their google contacts within the domain.
You can not use a service account to write to a standard google gmail user's google contacts. For that you would need to use Oauth2 and authorize the user to access their google contacts.
Based on the comments on the previous answer:
You are inserting contacts to a service account
To use your own account you have to create an OAuth client ID and then use the credentials.json to authorise on the code.
There is no C# sample on the People API samples but you can check on how to use this credentials based on the .NET quickstart for Drive API but without using Drive API scopes and code.
Basically using this part of the code:
UserCredential credential;
using(var stream =
new FileStream("credentials.json", FileMode.Open, FileAccess.Read))
{
// The file token.json stores the user's access and refresh tokens, and is created
// automatically when the authorization flow completes for the first time.
string credPath = "token.json";
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
Scopes,
"user",
CancellationToken.None,
new FileDataStore(credPath, true)).Result;
Console.WriteLine("Credential file saved to: " + credPath);
}
I'm developing an application wich needs to access a "simple database" (google spreadsheet) with users IDs.
I try with Oauth2.0 But that's not what I need.
I'm using this code to get access to the sheet:
private static SheetsService AuthorizeGoogleApp()
{
UserCredential credential;
using (var stream =
new FileStream("client_secret.json", FileMode.Open, FileAccess.Read))
{
string credPath = System.Environment.GetFolderPath(
System.Environment.SpecialFolder.Personal);
credPath = Path.Combine(credPath, ".credentials/sheets.googleapis.com-dotnet-quickstart.json");
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
Scopes,
"user",
CancellationToken.None,
new FileDataStore(credPath, true)).Result;
Console.WriteLine("Credential file saved to: " + credPath);
}
// Create Google Sheets API service.
var service = new SheetsService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName,
});
return service;
}
But with this code the C# application open a browser to ask the user to login in his google account.
I need to have access via API, so it will be transparent to the user.
I already have the api key, but I don't know how to use and I don't find any documentation on Google sites.
Can you help me with some kind of example to read a simple column?
Thanks in advance!
Here is the documentation for the API.
It also covers authorization.
I have created an Alexa skill and enabled account linking. Setup my skills configuration to point to googles authorization and token servers, the skill successfully links. Then alexa sends POST Requests to my service that include the access token and state from Google. I use this to validate the token and what I want to do is use the token to access gmail api and begin calling actions.
However, the only examples online I can find include re-building the gmailservice by using the client secret and client id again. I figure since I have the access token already, why do I need to include the secret and ID again? How can i make gmail api calls with the access token I already have, or is this not possible? Here's the code I'm trying to use:
UserCredential credential;
using (var stream =
new FileStream("client_secret.json", FileMode.Open, FileAccess.Read))
{
string credPath = System.Environment.GetFolderPath(
System.Environment.SpecialFolder.Personal);
credPath = Path.Combine(credPath, ".credentials/gmail-dotnet-quickstart.json");
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
Scopes,
"user",
CancellationToken.None,
new FileDataStore(credPath, true)).Result;
Console.WriteLine("Credential file saved to: " + credPath);
}
// Create Gmail API service.
var service = new GmailService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName,
});
// Define parameters of request.
UsersResource.LabelsResource.ListRequest request = service.Users.Labels.List("me");
// List labels.
IList<Label> labels= request.Execute().Labels;
Console.WriteLine("Labels:");
if (labels != null && labels.Count > 0)
{
foreach (var labelItem in labels)
{
Console.WriteLine("{0}", labelItem.Name);
}
}
else
{
Console.WriteLine("No labels found.");
}
Console.Read();
I don't want to include the client_secret.json file because I already was authorized by google's oauth process in the alexa skill's account linking. Help ?
All code runs without errors, but when I check my Google Drive account I can't find the file I am uploading ("document.txt").
Also it has asked me for Authentication again.
UserCredential credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
new ClientSecrets
{
ClientId = "Here my clientid",
ClientSecret = "client secret",
},
new[] { DriveService.Scope.Drive },
"user",
CancellationToken.None).Result;
// Create the service.
var service = new DriveService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "Drive API Sample",
});
File body = new File();
body.Title = "My document";
body.Description = "A test document";
body.MimeType = "text/plain";
byte[] byteArray = System.IO.File.ReadAllBytes("document.txt");
System.IO.MemoryStream stream = new System.IO.MemoryStream(byteArray);
FilesResource.InsertMediaUpload request = service.Files.Insert(body, stream, "text/plain");
request.Upload();
File file = request.ResponseBody;
Questions:
Why cant I find my uploaded file, and how can I get it to remember my authentication.
I think you are forgetting body.Parent so it doesn't know what directory to place the file into.
parents[] list Collection of parent folders which contain this file.
Setting this field will put the file in all of the provided folders.
On insert, if no folders are provided, the file will be placed in the
default root folder.
example:
body.Parents = new List<ParentReference>() { new ParentReference() { Id = 'root' } };
You are getting asked for authentication again because you aren't saving authentication.
//Scopes for use with the Google Drive API
string[] scopes = new string[] { DriveService.Scope.Drive,
DriveService.Scope.DriveFile};
// here is where we Request the user to give us access, or use the Refresh Token that was previously stored in %AppData%
UserCredential credential =
GoogleWebAuthorizationBroker
.AuthorizeAsync(new ClientSecrets { ClientId = CLIENT_ID
, ClientSecret = CLIENT_SECRET }
,scopes
,Environment.UserName
,CancellationToken.None
,new FileDataStore("Daimto.GoogleDrive.Auth.Store")
).Result;
FileDataStore stores the authentication data in the %appdata% directory.
More detailed information can be found in the tutorial Google Drive API with C# .net – Upload
Update For the following error:
"The API is not enabled for your project, or there is a per-IP or
per-Referer restriction configured on your API key and the request
does not match these restrictions. Please use the Google Developers
Console to update your configuration. [403]"
Go to Developer console for your project here Under APIs & auth -> APIs enable Google drive API and sdk. Also go to credentials and make sure you added a product name and email.
I've seen;
Accessing Google Spreadsheets with C# using Google Data API
and
http://code.google.com/apis/spreadsheets/data/2.0/developers_guide_dotnet.html#CreatingRows
However i'm still having trouble inserting a new row in to an existing google spread sheet. Does anyone have a canned example which inserts a List<string> for example in to new row in a spreadsheet workbook.
Many thanks,
Use GDataDB http://github.com/mausch/GDataDB
GDataDB provides a simple way to insert .net POCO entities in to a google spread sheet.
public void AddToGoogle()
{
var client = new DatabaseClient(Settings.Default.GmailAccount, Settings.Default.GmailPassword);
string dbName = Settings.Default.WorkBook;
var db = client.GetDatabase(dbName) ?? client.CreateDatabase(dbName);
string tableName = Settings.Default.WorkSheet;
var t = db.GetTable<ActivityLog>(tableName) ?? db.CreateTable<ActivityLog>(tableName);
var all = t.FindAll();
t.Add(this);
}
This Services from Google are discontinued and now they came up with another one named Google.Apis.Sheets.v4 services.
so the above code will not work now a days, I have already tried.
And find something that worked out for me.
I have written a blog and shared the whole source code there. Check it out.
private static SheetsService AuthorizeGoogleApp()
{
UserCredential credential;
using (var stream =
new FileStream("client_secret.json", FileMode.Open, FileAccess.Read))
{
string credPath = System.Environment.GetFolderPath(
System.Environment.SpecialFolder.Personal);
credPath = Path.Combine(credPath, ".credentials/sheets.googleapis.com-dotnet-quickstart.json");
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
Scopes,
"user",
CancellationToken.None,
new FileDataStore(credPath, true)).Result;
Console.WriteLine("Credential file saved to: " + credPath);
}
// Create Google Sheets API service.
var service = new SheetsService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName,
});
return service;
}
For the entire source code check it out. Insert new row to Google Sheet using Google.Apis.Sheets.V4 Services