Bir hizmet hesabıyla Google takvim etkinliği oluşturulurken hata meydana geldi

Dec 19 2020

Bir takvimde bir Google takvim etkinliği oluşturma ve diğer kullanıcıları bu etkinliğe katılımcı olarak ekleme zorunluluğum var. Amaç, uygulama kullanıcılarına izinlerini almadan takvim olayları göndermektir (O-Auth).

Google'ın belgelerini okuduktan sonra, bir hizmet hesabına ihtiyacım olduğunu öğrendim. Bu nedenle, G Suite e-posta adreslerimizden biri olan [email protected]'dan bir proje ve hizmet hesabı oluşturdum ve bunun için takvim API'sini etkinleştirdim.

İçeriği şu olan bir anahtar çifti (JSON) oluşturdum ve indirdim:

{
  "type": "service_account",
  "project_id": "*****",
  "private_key_id": "bdbbcd**************49f77d599f2",
  "private_key": "**"
  "client_email": "******@*****.iam.gserviceaccount.com",
  "client_id": "11083******576856",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://oauth2.googleapis.com/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/****dev%40*****kdev.iam.gserviceaccount.com"
}

Ve belgelere göre, kimlik doğrulama akış kodunu yazma prosedürünü uyguladım,

public static GoogleCredential doOauth( String credsPath ) throws IOException
    {
        GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream(credsPath))
                .createScoped(Collections.singleton(CalendarScopes.CALENDAR));
        System.out.println(credential);
        return credential;
    }

credentialNesne anahtar dosyadan detayların en vardır. Ama, alanlar, serviceAccountUser, accessToken, refreshToken, clientAuthenticationve requestInitializersahip nulldeğerini. (Burada yanlış bir şey tahmin ediyorum)

Şimdi, kullanarak credentialObject, etkinliği oluşturmak için belgelere göre kodu yazmaya devam ettim.

GoogleCredential credential = doOauth(CREDENTIALS_FILE_PATH);
        Event event = new Event().setSummary("Google I/O 2015").setLocation("800 Howard St., San Francisco, CA 94103")
                .setDescription("A chance to hear more about Google's developer products.");
        final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();

        DateTime startDateTime = new DateTime("2020-12-28T09:00:00-07:00");
        EventDateTime start = new EventDateTime().setDateTime(startDateTime).setTimeZone("America/Los_Angeles");
        event.setStart(start);

        DateTime endDateTime = new DateTime("2020-12-28T17:00:00-07:00");
        EventDateTime end = new EventDateTime().setDateTime(endDateTime).setTimeZone("America/Los_Angeles");
        event.setEnd(end);

        String[] recurrence = new String[] { "RRULE:FREQ=DAILY;COUNT=2" };
        event.setRecurrence(Arrays.asList(recurrence));

        EventAttendee[] attendees = new EventAttendee[] { new EventAttendee().setEmail("[email protected]") };
        event.setAttendees(Arrays.asList(attendees));

        EventReminder[] reminderOverrides = new EventReminder[] {
                new EventReminder().setMethod("email").setMinutes(24 * 60),
                new EventReminder().setMethod("popup").setMinutes(10), };
        Event.Reminders reminders = new Event.Reminders().setUseDefault(false)
                .setOverrides(Arrays.asList(reminderOverrides));
        event.setReminders(reminders);
        String calendarId = "primary";
        Calendar service = new Calendar.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential)
                .setApplicationName("testapp").build();
        event = service.events().insert(calendarId, event).execute();
        System.out.printf("Event created: %s\n", event.getHtmlLink());

Ancak bu hata ile sonuçlandı,

{
  "code" : 403,
  "errors" : [ {
    "domain" : "calendar",
    "message" : "Service accounts cannot invite attendees without Domain-Wide Delegation of Authority.",
    "reason" : "forbiddenForServiceAccounts"
  } ],
  "message" : "Service accounts cannot invite attendees without Domain-Wide Delegation of Authority."
}

Üzerinde zaman geçirdikten sonra Domain-Wide Delegation, olayı g-suite'imizden başka bir kullanıcı olarak göndermemiz gerektiğinde bunun gerekli olduğunu anladım, ki bu benim sorunum için gerekli değil. Ancak, hata ayıklamak için devam ettim Domain-Wide Delegationve programı sağladım ve yeniden çalıştırdım. Aynı hata yine geldi.

Bu yüzden davetlileri / katılımcıları eventnesneden kaldırdım ve uygulamayı yeniden çalıştırdım. Bu sefer program herhangi bir hatasız çalıştı, ancak oluşturulan olay bağlantısı tıklandığında diyor Could not find the requested event.

Google geliştirici bağlantısında java istemci kitaplıkları aracılığıyla hizmet hesabını kullanmanın herhangi bir örneğini görmüyorum.

Lütfen bana burada neyin yanlış gittiğini ve projemden tam olarak nasıl bir Google takvim etkinliği oluşturacağıma ilişkin resmi / çalışma belgelerini, katılımcı olarak eklemek için diğer (g Suite olmayan) kullanıcıları ekleyebilir misiniz? diğer kullanıcılardan kendi takvimlerine etkinlik eklemek için izin almak için?

Teşekkür ederim.

Yanıtlar

DaImTo Dec 21 2020 at 15:06

Öncelikle bunun yeni bir şey olduğunu söylemek istiyorum, çok fazla soru görüyorsanız ve bunu yapmanız gerektiğini belirtmeyen öğreticiler, çünkü hizmet hesapları eskiden davet gönderebiliyordu, bu google'ın kilitlediği bir şey yaklaşık bir yıl önce.

Bu işe yarayacak, ancak artık bir Gsuite hesabına erişimim olmadığı için test etmedim. Gsuite yöneticisinin başka bir kullanıcıya etki alanı çapında yetkilendirme ayarlamasını sağlamanız gerekir . Daha sonra, hizmet hesabının o kullanıcının kimliğine bürünmesi gerekir, böylece o kullanıcı davetleri gönderen kişi olarak görünecektir.

Bunun nasıl eklendiğine dair sahip olduğum tek örnek .net.

.net örneği

var gsuiteUser = "[email protected]";
var serviceAccountCredentialInitializer = new ServiceAccountCredential.Initializer(serviceAccount)
            {
                User = gsuiteUser,
                Scopes = new[] { GmailService.Scope.GmailSend, GmailService.Scope.GmailLabels }

            }.FromCertificate(certificate);

Java örneği tahmin

Ben bir java geliştiricisi değilim ama .net istemci kitaplığı ve Java istemci kitaplığı geliştirilme biçimlerine çok yakındır. SetServiceAccountUser adlı bir yöntem aradığınızı tahmin ediyorum

GoogleCredential credential = new  GoogleCredential.Builder().setTransport(HTTP_TRANSPORT)
                .setJsonFactory(JSON_FACTORY)
                .setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
                .setServiceAccountScopes(CalendarScopes.CALENDAR)
                .setServiceAccountPrivateKeyFromP12File(credsPath))
                .setServiceAccountUser(gsuiteUser)
                .build();
  • Hizmet Hesapları için OAuth2