I'm inserting a new event on Google Calendar using a service account service#entreprise.tn.
I can't specify the organizer or the creator of an event.
My code is:
Organizer organizer = new Organizer().setEmail("user1#entreprise.tn").setSelf(true);
Creator creator = new Creator().setEmail("user1#entreprise.tn").setSelf(true);
Calendar service = Calendar_Utils.getCalendarService();
Event event = new Event()
.setSummary("Google Calendar API")
.setOrganizer(organizer)
.setCreator(creator);
DateTime startDateTime = new DateTime("2020-04-24T09:00:00.000Z");
EventDateTime start = new EventDateTime()
.setDateTime(startDateTime)
.setTimeZone("Africa/Tunis");
event.setStart(start);
DateTime endDateTime = new DateTime("2020-04-24T10:30:00.000Z");
EventDateTime end = new EventDateTime()
.setDateTime(endDateTime)
.setTimeZone("Africa/Tunis");
event.setEnd(end);
String calendarId = "primary";
event = service.events().insert(calendarId, event).execute();
System.out.printf("Event created: %s\n", event.getHtmlLink() + " - " + event.getOrganizer() + " - " + event.getCreator());
As result, the new event is inserted, but with organizer and creator service#entreprise.tn and not user1#entreprise.tn.
Could you please tell me how can I change my code to set the organizer to user1#entreprise.tn.
Thanks a lot.
When you create an event with the service account, you need to impersonate the user on whose behalf the event shall be created
In Java you would do it as following:
GoogleCredential getCredentials = new GoogleCredential.Builder()
.setTransport(HTTP_TRANSPORT)
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId(serviceAccount)
.setServiceAccountPrivateKeyFromP12File(pk12)
.setServiceAccountScopes(SCOPES)
.setServiceAccountUser("user1#entreprise.tn")
.build();
Do an events.patch and update the organizer fields on the Event by default the organizer property is set to the person or service account which created the event.
Impersonation
If the service account has been set up with domain wide delegation to a gsuie domain you can impersonate one of the users on the domain and the organizer will be the user who was impersonated.
Related
I am working on a spring boot api which schedules events for me but and its working fine but along with events I want to add a meet link too and I am not able to do that.I am using a service account from cloud console and shared my personal account with this service account.How can I implement google meet?
Here's my code:
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.");
ConferenceSolutionKey conferenceSKey = new ConferenceSolutionKey();
conferenceSKey.setType("hangoutsMeet");
CreateConferenceRequest createConferenceReq = new CreateConferenceRequest();
createConferenceReq.setRequestId("adojajaod"); // ID generated by you
createConferenceReq.setConferenceSolutionKey(conferenceSKey);
ConferenceData conferenceData = new ConferenceData();
conferenceData.setCreateRequest(createConferenceReq);
System.out.println(conferenceData);
event.setConferenceData(conferenceData);
DateTime startDateTime = new DateTime("2021-08-14T09:00:00-07:00");
EventDateTime start = new EventDateTime()
.setDateTime(startDateTime)
.setTimeZone("America/Los_Angeles");
event.setStart(start);
DateTime endDateTime = new DateTime("2021-08-15T17: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));
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);
event = client.events().insert("himanshuranjan30#gmail.com", event).setConferenceDataVersion(1).execute();
System.out.printf("Event created: %s\n", event.getHtmlLink());
Here I am trying to setup a meet link using conference but its not working and giving a error like:
{
"code" : 400,
"errors" : [ {
"domain" : "global",
"message" : "Invalid conference type value.",
"reason" : "invalid"
} ],
"message" : "Invalid conference type value."
}
Any help will be appreciated.
conferenceSKey.setType("hangoutsMeet");
Looks like the calendar where you try to insert the event does not accept the "hangoutsMeet" conference call type.
To verify use get of Calendar API to view your target Calendar metadata.
https://developers.google.com/calendar/api/v3/reference/calendars
You can see the allowed types under,
"conferenceProperties": {
"allowedConferenceSolutionTypes": [
string
]
}
I have a requirement of creating a google calendar event on a calendar and add other users as attendees to that event. The objective is to send calendar events to the application users without taking their consent ( O-Auth ).
After reading Google's documentation, I found out that I need a service account. So I created a project and a service account from one of the email addresses of our G-Suite, noreply#xxxxx.com and enabled calendar API for the same.
I created and downloaded a key pair ( JSON ) whose content is,
{
"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"
}
And as per the documentation, I proceded to write authentication flow code,
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;
}
The credential object has most of the details from the key file. But, the fields, serviceAccountUser, accessToken, refreshToken, clientAuthentication and requestInitializer have null value. ( I am guessing something wrong here )
Now, using the credentialObject, I continued to write the code as per the documentation to create the event.
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());
But, this resulted in the error,
{
"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."
}
After spending time on Domain-Wide Delegation, I understood that this is needed if we have to send the event as other user from our g-suite, which is not needed for my problem. But, to debug, I went ahead and provided Domain-Wide Delegation and re ran the program. The same error came again.
So, I removed the invitees/attendees from the event object and re ran the application. This time the program ran without any error, but the event link generated, on click says, Could not find the requested event.
I do not see any examples of using the service account via java client libraries on the google developer link.
Can you please let me know what is going wrong here and the official/working documentation on how exactly to create a google calendar event from my project add other ( non g suite as well ) users to add as attendees, so that I do not have to get consent from other users to add events to their own calendar?
Thank You.
Fist off I want to say that this is something new, if you are seeing a lot of questions, and tutorials that did not state you needed to do this its because service accounts used to be able to send invites, this is something google locked down about a year ago.
This should work but i have not tested it as i no longer have access to a Gsuite account. You need to have the gsuite admin set up domain wide delegation to anther user. Then the service account needs to impersonate that user so it will appear as that user is the one sending the invites.
The only example I have for how that is added is in .net
.net example
var gsuiteUser = "se#clawskeyboard.com";
var serviceAccountCredentialInitializer = new ServiceAccountCredential.Initializer(serviceAccount)
{
User = gsuiteUser,
Scopes = new[] { GmailService.Scope.GmailSend, GmailService.Scope.GmailLabels }
}.FromCertificate(certificate);
Java example guess
I am not a java dev but the .net client library and the Java client library are very close in how they were developed. I would guess that you are looking for a method called setServiceAccountUser
GoogleCredential credential = new GoogleCredential.Builder().setTransport(HTTP_TRANSPORT)
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
.setServiceAccountScopes(CalendarScopes.CALENDAR)
.setServiceAccountPrivateKeyFromP12File(credsPath))
.setServiceAccountUser(gsuiteUser)
.build();
OAuth2 for Service Accounts
You should be able to impersonate the account user by setting the delegated variable to the user's email in the GoogleCredential object.
GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream("credentials.json"))
.createScoped(<SCOPES>)
.createDelegated("user#example.com");
I'm trying to create the Google Calendar event with the conference(Google Meet) using Java SDK V3. The event is getting created but the conference details are not being set. Not sure what's missing
Create request:
Calendar service = new Calendar
.Builder(GoogleNetHttpTransport.newTrustedTransport(),
getDefaultInstance(),
new HttpCredentialsAdapter(googleCalendarCredentials()))
.setApplicationName(APPLICATION_NAME)
.build();
Event event = new Event();
event.setStart(new EventDateTime().setDateTime(new DateTime(currentTimeMillis())));
event.setEnd(new EventDateTime().setDateTime(new DateTime(currentTimeMillis() + 10000000)));
ConferenceData conferenceData = new ConferenceData();
conferenceData.setCreateRequest(
new CreateConferenceRequest()
.setConferenceSolutionKey(
new ConferenceSolutionKey()
.setType("hangoutsMeet")));
event.setConferenceData(conferenceData);
service.events().insert("primary", event).execute();
Get Request:
Events events = service.events()
.list("primary")
.execute();
List<Event> items = events.getItems();
if (items.isEmpty()) {
System.out.println("No upcoming events found.");
} else {
System.out.println("Upcoming events");
for (Event eventRs : items) {
System.out.printf("%s\n", eventRs.getConferenceData().getConferenceId());
}
}
Getting eventRs.getConferenceData() as null.
If you check the documentaiton on Event.insert you will see that you need to set the option parameter conferenceDataVersion inorder to enable it to set the conference data.
Version 0 assumes no conference data support and ignores conference data in the event's body. Version 1 enables support for copying of ConferenceData
I need to obtain all public events from my fb page.
It's not possible using an App access token anymore: "Requires a valid Page or User access token with basic permissions." - https://developers.facebook.com/docs/graph-api/reference/page/events/
I don't want to put my User credentials into my Application.
Current code:
FacebookClient.AccessToken accessToken = new DefaultFacebookClient(Version.LATEST).obtainAppAccessToken(facebookProperties.getAppId(), facebookProperties.getAppSecret());
FacebookClient facebookClient = new DefaultFacebookClient(accessToken.getAccessToken(), Version.LATEST);
Date now = new Date();
Connection<com.restfb.types.Event> eventConnection = facebookClient.fetchConnection(facebookProperties.getPageId() + "/events", com.restfb.types.Event.class, Parameter.with("fields", "name,start_time"));
List<Event> events = eventConnection.getData().stream().filter(facebookEvent -> now.compareTo(Optional.ofNullable(facebookEvent.getEndTime()).orElse(facebookEvent.getStartTime())) <= 0).map(facebookEvent -> Event.fromFacebookEvent(facebookEvent)).collect(Collectors.toCollection(LinkedList::new));
A dirty Workaround would be creating a new fb account, adding it as a Page admin and provide its Credentials. Is there a better way to simply obtain the public Events?
Today I created code:
// Create a CalenderService and authenticate
CalendarService myService = new CalendarService("exampleCo-exampleApp-1");
myService.setUserCredentials("j...#gmail.com", "mypassword");
// Send the request and print the response
URL feedUrl = new URL("https://www.google.com/calendar/feeds/default/allcalendars/full");
CalendarFeed resultFeed = myService.getFeed(feedUrl, CalendarFeed.class);
System.out.println("Your calendars:");
System.out.println();
for (int i = 0; i < resultFeed.getEntries().size(); i++) {
CalendarEntry entry = resultFeed.getEntries().get(i);
System.out.println("\t" + entry.getTitle().getPlainText());
}
This code gives out the list of all calendars. At me - a box calendar, a calendar of birthdays of friends and a calendar of holidays. I need to receive all events occurring today - i.e. both my notes, and birthdays of friends, and holidays. How I am able to do it?
This code returns event for specified data range, but it is work for private calendar only; i tried to replace "private" for "allcalendars", but it doesn't work:
URL feedUrl = new URL("https://www.google.com/calendar/feeds/default/private/full");
CalendarQuery myQuery = new CalendarQuery(feedUrl);
myQuery.setMinimumStartTime(DateTime.parseDateTime("2006-03-16T00:00:00"));
myQuery.setMaximumStartTime(DateTime.parseDateTime("2006-03-24T23:59:59"));
CalendarService myService = new CalendarService("exampleCo-exampleApp-1");
myService.setUserCredentials("jo#gmail.com", "mypassword");
// Send the request and receive the response:
CalendarEventFeed resultFeed = myService.query(myQuery, Feed.class);
Your problem is in the your feed url. The one you are using is getting the events on the default calendar.
To get the other calendars you should replace default in the url by the calendar's id, for example:
feedUrl = new URL("https://www.google.com/calendar/feeds/xxxxxxxxxxxxxxxxx#group.calendar.google.com/private/full");