У меня есть проект, в котором мне нужно будет добавить листы Google, а затем мне придется обновить.
Я могу добавить электронную таблицу, и вот код, который я использую
public string[] Scopes = { SheetsService.Scope.Spreadsheets };
static string ApplicationName = "SheetUpdate";
public SheetsService AuthorizeGoogleApp()
{
string fileName = "./credentials.json";
UserCredential credential;
using (var stream =
new FileStream(fileName, FileMode.Open, FileAccess.Read))
{
string credPath = "token.json";
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
Scopes,
"user",
CancellationToken.None,
new FileDataStore(credPath, true)).Result;
}
var service = new SheetsService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName,
});
return service;
}
public string CreateNewSheet(string sheetTitle)
{
var newSheet = new Spreadsheet();
newSheet.Properties = new SpreadsheetProperties();
newSheet.Properties.Title = sheetTitle;
var nsheet = AuthorizeGoogleApp().Spreadsheets.Create(newSheet).Execute();
return nsheet.SpreadsheetId.ToString();
}
Однако мне нужно получить лист позже, и для этого мне придется сравнить его по имени, чтобы добавить соответствующие данные.
Но я не нашел никакого решения, чтобы получить заголовок листа, используя SheetsService API
.
Я могу получить это, используя Google Drive API
как
public SpreadsheetsService AuthorizeGoogleDrive()
{
string keyFilePath = @"C:\Users\abc\429e5c50bdab.p12";
string serviceAccountEmail = "xyz@xyz-1546703100663.iam.gserviceaccount.com";
var certificate = new X509Certificate2(keyFilePath, "notasecret", X509KeyStorageFlags.Exportable);
var serviceAccountCredentialInitializer = new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
Scopes = new[] { "https://spreadsheets.google.com/feeds" }
}.FromCertificate(certificate);
var credential = new ServiceAccountCredential(serviceAccountCredentialInitializer);
if (!credential.RequestAccessTokenAsync(System.Threading.CancellationToken.None).Result)
throw new InvalidOperationException("Access token request failed.");
var requestFactory = new GDataRequestFactory(null);
requestFactory.CustomHeaders.Add("Authorization: Bearer " + credential.Token.AccessToken);
var service = new SpreadsheetsService(null) { RequestFactory = requestFactory };
return service;
}
public void GetSheetByTitle(string title)
{
var service = AuthorizeGoogleDrive();
SpreadsheetQuery query = new SpreadsheetQuery();
SpreadsheetFeed feed = service.Query(query);
if (feed.Entries.Count == 0)
{
MessageBox.Show("There are no sheets");
}
// Iterate through all of the spreadsheets returned and get id by title
foreach (SpreadsheetEntry sheet in feed.Entries)
{
MessageBox.Show(sheet.Title.Text);
}
}
}
Проблема в том, что SheetsService
использует credentials.json
, который содержит учетные данные для учетной записи Gmail и лист добавляется туда, и SpreadSheetService
не может быть подключен (или я не смог) с использованием учетных данных и может только быть подключенным через служебную учетную запись, которая использует другую электронную почту, и лист не будет доступен для служебной электронной почты до тех пор, пока я не предоставлю доступ к учетной записи службы вручную.
Я ищу 1 из этих 2 решений:
1 - чтобы получить заголовок листа с SheetsService API
2 - Соединить оба API с одной и той же учетной записью (учетная запись службы или учетные данные Gmail)
Обновление
Когда я пытаюсь использовать учетные данные для подключения SpreadSheetService
как
public SpreadsheetsService AuthorizeGoogleDrive2()
{
var service = new SpreadsheetsService(null);
service.setUserCredentials("xyz@gmail.com", "***");
return service;
}
Я получаю error execution of authentication request returned unexpected result 404