C # - Невозможно получить электронную таблицу в Google Drive API, которая добавлена ​​с помощью Spreadsheet API - PullRequest
0 голосов
/ 06 января 2019

У меня есть проект, в котором мне нужно будет добавить листы 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

1 Ответ

0 голосов
/ 29 января 2019

Почему бы не создать лист с заголовком, который вы хотите заблаговременно? Код ниже также возвращает spreadsheetId для последующего использования. Я записываю заголовок и идентификатор в файл, который могу прочитать позже.

try {
    Spreadsheet oBody = new Spreadsheet {
        Properties = new SpreadsheetProperties() {
            Title = sheetTitle,
        },
    };
    SpreadsheetsResource.CreateRequest oRequest = sheetsService.Spreadsheets.Create(oBody);
    Spreadsheet oResponse = oRequest.Execute();
    result = oResponse.SpreadsheetId;
} catch (Exception e) {
    result = "Google API: " + e.Message;
}

СПРАВКА: https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/create

...