【发布时间】:2021-03-29 19:21:56
【问题描述】:
我需要在日历上创建一个谷歌日历活动,并将其他用户添加为该活动的参与者。目标是在未经应用用户同意的情况下向应用用户发送日历事件 (O-Auth)。
在阅读了 Google 的文档后,我发现我需要一个服务帐户。所以我从我们 G-Suite 的一个电子邮件地址 noreply@xxxxx.com 创建了一个项目和一个服务帐户,并为此启用了日历 API。
我创建并下载了一个密钥对 (JSON),其内容是,
{
"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"
}
根据文档,我开始编写身份验证流程代码,
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;
}
credential 对象包含密钥文件中的大部分详细信息。但是,serviceAccountUser、accessToken、refreshToken、clientAuthentication 和 requestInitializer 字段具有 null 值。 (我猜这里有问题)
现在,使用credentialObject,我继续按照文档编写代码来创建事件。
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("myemailaddress@gmail.com.com") };
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());
但是,这导致了错误,
{
"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."
}
在Domain-Wide Delegation 上花费时间后,我了解到如果我们必须从我们的 g 套件以其他用户的身份发送事件,这是需要的,而我的问题不需要。但是,为了调试,我继续提供Domain-Wide Delegation 并重新运行程序。同样的错误又来了。
所以,我从event 对象中删除了受邀者/与会者并重新运行了应用程序。这次程序运行没有任何错误,但生成的事件链接在点击时显示为Could not find the requested event。
我在 google 开发者链接上没有看到任何通过 java 客户端库使用服务帐户的示例。
您能否让我知道这里出了什么问题,以及有关如何从我的项目中创建谷歌日历事件的官方/工作文档添加其他(非 g 套件)用户添加为与会者,以便我无需征得其他用户的同意即可将活动添加到自己的日历中?
谢谢。
【问题讨论】:
标签: java google-api google-calendar-api google-api-java-client service-accounts