Releases: nylas/nylas-java
v1.11.0
This release of the Nylas Java SDK brings forward a handful of new features, including support for our Scheduler API.
New Features
- Added support for Scheduler API
- Added support for calendar availability
- Added support for
Event
to ICS file generation - Added support for modifying
Folder
- Expanded metadata support for
Calendar
,Account
,Message
, andDraft
New Contributors
This is a new section that will be used to highlight all the wonderful people who have provided their first contribution to this project!
- @TDtianzhenjiu made their first contribution with
Add metadata field for message
(#43)
Using New Features
Scheduler API
To create a new Scheduler page:
Scheduler scheduler = new Scheduler();
scheduler.addAccessTokens("access.token");
scheduler.setName("Java SDK Example");
scheduler.setSlug("java_example");
nylas.schedulers().save(scheduler);
To return all Scheduler pages:
List<Scheduler> schedulerList = nylas.schedulers().list();
To return a single Scheduler page:
Scheduler scheduler = nylas.schedulers().get("SCHEDULER_ID");
To update a Scheduler page:
Scheduler scheduler = nylas.schedulers().get("SCHEDULER_ID");
scheduler.name = "Updated page name"
nylas.schedulers().save(scheduler);
To delete a Scheduler page:
nylas.schedulers().delete("SCHEDULER_ID");
To get available calendars for a Scheduler page:
Scheduler scheduler = nylas.schedulers().get("SCHEDULER_ID");
List<AvailableCalendars> availableCalendars = nylas.schedulers().getAvailableCalendars(scheduler.getId());
To upload an image:
Scheduler scheduler = nylas.schedulers().get("SCHEDULER_ID");
UploadImageResponse uploadImageResponse = nylas.schedulers().uploadImage(scheduler.getId(), "image/png", "test.png");
Checking Provider Availability
// Google Availability
List<ProviderAvailability> googleAvailability = nylas.schedulers().getGoogleAvailability();
// Office 365 Availability
List<ProviderAvailability> office365Availability = nylas.schedulers().getOffice365Availability();
Get page information/configuration
Scheduler page = nylas.schedulers().getPageBySlug(scheduler.getSlug());
Retrieve available time slots
List<TimeSlot> timeSlots = nylas.schedulers().getAvailableTimeSlots(scheduler.getSlug());
Book a time slot
TimeSlot slot = new TimeSlot();
slot.setAccountId("test-account-id");
slot.setCalendarId("test-calendar-id");
slot.setEmails(Collections.singletonList("[email protected]"));
slot.setHostName("Host");
slot.setStart(1636728347L);
slot.setEnd(1636728347L);
BookingRequest bookingRequest = new BookingRequest();
Map<String, Object> additionalValues = new HashMap<>();
additionalValues.put("important", true);
bookingRequest.setAdditionalValues(additionalValues);
bookingRequest.setEmail("[email protected]");
bookingRequest.setLocale("en_US");
bookingRequest.setName("John Doe");
bookingRequest.setTimezone("America/New_York");
bookingRequest.setSlot(slot);
BookingConfirmation bookingConfirmation = nylas.schedulers().bookTimeSlot("slug", bookingRequest);
Confirm a booking
BookingConfirmation bookingConfirmation = nylas.schedulers().confirmBooking("slug", "edit-hash");
Cancel a booking
nylas.schedulers().cancelBooking("slug", "edit-hash", "reason");
Checking Calendar Availability
To check availability for a single meeting
NylasClient nylas = new NylasClient();
NylasAccount account = nylas.account("{ACCESS_TOKEN}");
Calendars calendars = account.calendars();
// Prepare OpenHours for availability request
OpenHours openHours = new OpenHours();
openHours.setEmails(Collections.singletonList("[email protected]"));
openHours.setDays(Collections.singletonList(0));
openHours.setTimezone("America/Chicago");
openHours.setStart("10:00");
openHours.setEnd("14:00");
// Build availability request
SingleAvailabilityQuery query = new SingleAvailabilityQuery()
.durationMinutes(30)
.buffer(30)
.startTime(Instant.now())
.endTime(Instant.now().plus(1, ChronoUnit.HOURS))
.emails(Collections.singletonList("[email protected]"));
.intervalMinutes(5);
// Get availability
Availability availability = calendars.availability(query);
To check availability for a multiple meetings
NylasClient nylas = new NylasClient();
NylasAccount account = nylas.account("{ACCESS_TOKEN}");
Calendars calendars = account.calendars();
// Prepare emails for availability request
List<List<String>> emails = new ArrayList<>();
emails.add(Collections.singletonList("[email protected]"));
emails.add(Collections.singletonList("[email protected]"));
// Prepare OpenHours for availability request
OpenHours openHours = new OpenHours();
List<String> openHoursEmails = new ArrayList<>();
openHoursEmails.add("[email protected]");
openHoursEmails.add("[email protected]");
openHours.setEmails(openHoursEmails);
openHours.setDays(Collections.singletonList(0));
openHours.setTimezone("America/Chicago");
openHours.setStart("10:00");
openHours.setEnd("14:00");
// Build availability request
MultipleAvailabilityQuery consecutiveQuery = new MultipleAvailabilityQuery()
.durationMinutes(30)
.buffer(30)
.startTime(Instant.now())
.endTime(Instant.now().plus(1, ChronoUnit.HOURS))
.emails(emails)
.openHours(Collections.singletonList(openHours))
.intervalMinutes(5);
// Get consecutive availability
List<List<ConsecutiveAvailability>> consecutiveAvailability = calendars.consecutiveAvailability(consecutiveQuery);
Generating an ICS from an Event
NylasClient nylas = new NylasClient();
NylasAccount account = nylas.account("{ACCESS_TOKEN}");
Events events = account.events();
Event event = events.get("{eventId}");
// You can make an ICS file from an event ID
String icsFromEventID = events.generateICS(event.getId());
// You can make an ICS file from an Event object
String icsFromEvent = events.generateICS(event);
// You can also pass ICS Options for more configuration
ICSOptions icsOptions = new ICSOptions();
icsOptions.setIcal_uid("test_uuid");
icsOptions.setMethod(ICSMethod.ADD);
icsOptions.setProdid("test_prodid");
String icsFromEventWithOptions = events.generateICS(event, icsOptions);
Modifying a Folder
NylasClient nylas = new NylasClient();
NylasAccount account = nylas.account("{ACCESS_TOKEN}");
Folders folders = account.folders();
Folder folder = folders.get("{folderId}");
folder.setDisplayName("Updated name");
folder.setName("sent");
Folder updated = folders.update(folder);
Expanded Metadata
Adding Metadata to Calendar
Calendar newCal = new Calendar();
newCal.setName("New Test Calendar");
newCal.setDescription("Testing calendar creation");
newCal.setLocation("far, far away");
newCal.setTimezone("America/Los_Angeles");
Map<String, String> metadata = new HashMap<>();
metadata.put("calendar_type", "test");
newCal.setMetadata(metadata);
Calendar created = calendars.create(newCal);
// Or you can update a calendar with metadata
Map<String, String> metadata = new HashMap<>();
metadata.put("calendar_type", "test");
calendar.setMetadata(metadata);
Calendar updatedCalendar = account.calendars().update(calendar);
Query Calendars by Metadata
CalendarQuery metadataQuery = new CalendarQuery().metadataKey("calendar_type");
List<Calendar> calendarsWithMetadata = account.calendars().list(metadataQuery).fetchAll();
Calendar calendar = calendarsWithMetadata.get(0);
Adding Metadata to Draft
Draft draft = new Draft();
Map<String, String> metadata = new HashMap<>();
metadata.put("message_type", "test");
draft.setMetadata(metadata);
Adding Metadata to Message
Map<String, String> metadata = new HashMap<>();
metadata.put("message_type", "test");
Message message = account.messages().setMetadata("{EXISTING_MESSAGE_ID}", metadata);
Adding Metadata to Account
Map<String, String> metadata = new HashMap<>();
metadata.put("account_type", "test");
Account account = account.accounts().setMetadata("{EXISTING_ACCOUNT_ID}", metadata);
Query Account by Metadata
AccountQuery metadataQuery = new AccountQuery().metadataKey("account_type");
List<Account> accountsWithMetadata = account.accounts().list(metadataQuery).fetchAll();
Account account = accountsWithMetadata.get(0);
v1.10.3
Enhancements
- Added support for the
forced_password
Hosted Auth setting - Added missing
EMAIL
scope - Fixed bug where saving an event without participants threw a
NullPointerException
v1.10.2
Changed
- Added
false
parameter whennotifyParticipants
is false
Security
- Address major
log4j
vulnerability, updatedlog4j
to v2.17.0
v1.10.1
This patch addresses the log4j
vulnerability.
Security
- Address major
log4j
vulnerability, updatedlog4j
to v2.15.0
v1.10.0
This release of the Nylas Java SDK introduces 2 new features and fixes a critical bug where updating an event with participants can result in an error.
New Features
- Add support for automatic meeting details
- Add support for Event notifications
Enhancements
- Fix bug where updating an event resulted in an API error
Using New Features
Automatic Meeting Details
To have Nylas autocreate the conference field for you, pass the autocreate
object to the new event:
public class NylasExamples {
public static void postEventExample() throws IOException, RequestFailedException {
NylasClient nylas = new NylasClient();
NylasAccount account = nylas.account("{ACCESS_TOKEN}");
// Create a new event object
Event event = new Event("{CALENDAR_ID}", when);
// Add conferencing details
Event.Conferencing conferencing = new Event.Conferencing();
conferencing.setProvider("Zoom Meeting");
Event.Conferencing.Autocreate autocreate = new Event.Conferencing.Autocreate();
conferencing.setAutocreate(autocreate)
event.setConferencing(conferencing);
}
}
A few notes and things to keep in mind:
- Only one of
details
orautocreate
can be present, and we have implemented client-side checking to enforce this rule - Autocreating conferencing data is an asynchronous operation on the server-side. The Event object returned will not have a conferencing field, but it should be available in a future get call once the conference is created on the backend. The initial Event object returned will have a
jobStatusId
value which can be used to check on the status of conference creation. - The
settings
object within theautocreate
object maps to the settings the Nylas API will send to the conference provider for the conference creation. For example with Zoom the settings object maps to Zoom's Create a Meeting object.
Event Notifications
To add notifications to an event:
NylasClient nylas = new NylasClient();
NylasAccount account = nylas.account("{ACCESS_TOKEN}");
Events events = account.events();
Event event = new Event("{CALENDAR_ID}", new Timespan(startTime, endTime));
Event.Notification emailNotification = new Event.Notification();
emailNotification.setType(Event.Notification.NotificationType.EMAIL);
emailNotification.setMinutesBeforeEvent(600);
emailNotification.setSubject("Test Event Notification");
emailNotification.setBody("Reminding you about our meeting.");
Event.Notification webhookNotification = new Event.Notification();
webhookNotification.setType(Event.Notification.NotificationType.WEBHOOK);
webhookNotification.setMinutesBeforeEvent(600);
webhookNotification.setUrl("https://hooks.service.com/services/T01A03EEXDE/B01TBNH532R/HubIZu1zog4oYdFqQ8VUcuiW");
Map<String, Object> payload = new HashMap<>();
payload.put("text", "Your reminder goes here!");
webhookNotification.setPayload(JsonHelper.mapToJson(payload));
Event.Notification smsNotification = new Event.Notification();
smsNotification.setType(Event.Notification.NotificationType.SMS);
smsNotification.setMinutesBeforeEvent(60);
smsNotification.setSubject("Test Event Notification");
event.setNotifications(Arrays.asList(emailNotification, webhookNotification, smsNotification));
events.create(event, true);
To retrieve event notification details of an event:
NylasClient nylas = new NylasClient();
NylasAccount account = nylas.account("{ACCESS_TOKEN}");
Events events = account.events();
Event event = events.get("{eventId}");
int minutesBeforeEvent = event.getNotifications().getMinutesBeforeEvent();
String type = event.getNotifications().getType();
String body = event.getNotifications().getBody();
String url = event.getNotifications().getUrl();
String subject = event.getNotifications().getSubject();
String payload = event.getNotifications().getPayload();
String message = event.getNotifications().getMessage();
To update an event with a notification:
NylasClient nylas = new NylasClient();
NylasAccount account = nylas.account("{ACCESS_TOKEN}");
Events events = account.events();
Event event = events.get("{eventId}");
Event.Notification notification = new Event.Notification();
notification.setType(Event.Notification.NotificationType.EMAIL);
notification.setMinutesBeforeEvent(60);
notification.setSubject("Test Event Notification");
notification.setBody("Reminding you about our meeting.");
event.setNotifications(Collections.singletonList(notification));
events.update(event, true);
To delete a notification from an event:
NylasClient nylas = new NylasClient();
NylasAccount account = nylas.account("{ACCESS_TOKEN}");
Events events = account.events();
Event event = events.get("{eventId}");
event.setNotifications(Collections.emptyList());
events.update(event, true);
v1.9.0
New Features
- Add support for Event conferencing
- Add support for Account deletion
Deprecated
- MicrosoftExchangeProviderSettings easServerHost in favor of exchangeServerHost
Using New Features
Event Conferencing
Event.conference
is now a field that will contain conference details for Events that contain them, and it can be populated when new events through the SDK.
You can read the values like so:
public class NylasExamples {
public static void getEventExample() throws IOException, RequestFailedException {
NylasClient nylas = new NylasClient();
NylasAccount account = nylas.account("{ACCESS_TOKEN}");
// Get an event object with conferencing details
Event event = account.events().get("{EVENT_ID}");
// Parse the conferencing data
Event.Conferencing conferencing = event.getConferencing();
String conferencingProvider = conferencing.getProvider();
Event.Conferencing.Details details = conferencing.details();
String meetingCode = details.getMeetingCode();
String password = details.getPassword();
String pin = details.getPin();
String url = details.getUrl();
List<String> phone = details.getPhone();
}
}
You can also build a new event that includes conferencing details with the SDK:
public class NylasExamples {
public static void postEventExample() throws IOException, RequestFailedException {
NylasClient nylas = new NylasClient();
NylasAccount account = nylas.account("{ACCESS_TOKEN}");
// Create a new event object
Event event = new Event("{CALENDAR_ID}", when);
// Add conferencing details
Event.Conferencing conferencing = new Event.Conferencing();
conferencing.setProvider("Zoom Meeting");
Event.Conferencing.Details details = new Event.Conferencing.Details();
details.setMeetingCode("213");
details.setPassword("xyz");
details.setPin("555");
details.setUrl("https://us02web.zoom.us/j/****************");
details.setPhone(Collections.singletonList("+11234567890"));
conferencing.setDetails(details);
event.setConferencing(conferencing);
}
}
v1.8.0
This new release of the Nylas Java SDK brings a few new features, most notably support for the Nylas Neural API! More information below on how to use each part of the Neural API through our Node SDK.
New Features
- Enabled support for Nylas API v2.2
- Add Event Metadata support (#8)
- Add support for new
RoomResource
fields (#13) - Add missing getters for Event.Recurrence fields (#14)
- Add support for Neural API Sentiment Analysis, OCR, Signature Extraction, and Clean Conversations (#15)
- Add getters for Time.timezone, Timespan.start_timezone, Timespan.end_timezone (#16)
Using New Features
Neural API
To use Sentiment Analysis:
// To perform sentiment analysis on a message, pass in the list of message ID:
List<String> messageIds = new ArrayList<>(Collections.singletonList(MESSAGE_ID));
List<NeuralSentimentAnalysis> messageAnalysis = neural.sentimentAnalysisMessage(messageIds);
// To perform sentiment analysis on just text, pass in a string:
NeuralSentimentAnalysis textAnalysis = neural.sentimentAnalysisText("Hi, thank you so much for reaching out! We can catch up tomorrow.");
To use Signature Extraction:
List<String> messageIds = new ArrayList<>(Collections.singletonList(MESSAGE_ID));
List<NeuralSignatureExtraction> signature = neural.extractSignature(messageIds);
// The method also accepts two optional parameters
// parseContact, a boolean for whether Nylas should parse the contact from the signature (API defaults to true)
// options, an object of options that can be enabled for the Neural endpoint, of type NeuralMessageOptions:
NeuralMessageOptions options = NeuralMessageOptions options = new NeuralMessageOptions()
.ignoreImages(true)
.ignoreTables(false)
.ignoreLinks(true)
.removeConclusionPhrases(false)
.imagesAsMarkdown(true)
.parseContacts(false);
signature = neural.extractSignature(messageIds, true, options);
and to parse the contact and convert it to the standard Nylas contact object:
NeuralSignatureExtraction extractedSignature = extractSignature.get(0);
Contact contact = extractedSignature.getContacts().toContactObject();
To use Clean Conversations:
List<String> messageIds = new ArrayList<>(Collections.singletonList(MESSAGE_ID));
List<NeuralCleanConversation> cleanConversations = neural.cleanConversation(messageIds);
// You can also pass in an object of options that can be enabled for the Neural endpoint, of type NeuralMessageOptions
cleanConversations = neural.cleanConversation(messageIds, options);
and to extract images from the result:
NeuralCleanConversation cleanConvo = cleanConversations.get(0);
neural.extractImages(cleanConvo);
To use Optical Character Recognition:
NeuralOcr ocr = neural.ocrRequest( FILE_ID );
// This endpoint also supports a second, optional parameter for an array specifying the pages that the user wants analyzed:
ocr = neural.ocrRequest( FILE_ID, 2, 3 );
Event Metadata
To create a new event with event metadata, you can create a Map<String, String>
with a mapping of key-value pairs for the metadata:
Event event = new Event(calendarId, new Timespan(startTime, endTime));
....
Map<String, String> metadata = new HashMap<>();
metadata.put("event_category", "gathering");
event.setMetadata(metadata);
To query events based on metadata, you can filter on three different parameters:
metadata_key
(string or array) to filter based on the keys within the metadata objectmetadata_value
(string or array) to filter based on the value within the metadata objectmetadata_pair
(pair of strings; a key and a value) to filter based on the key-value pairs within the metadata object
You can invoke them as such and even chain them:
EventQuery query = new EventQuery()
.calendarId(calendarId)
.metadataKey("visitors", "parking")
.metadataValue("garden")
.metadataPair("event_category", "gathering");
Room Resources
Currently, the /resource
endpoint only supports the GET
operation without any extra functionality like filtering. To get a list of all room resource objects attached to your account, you can do the following:
// Initialize and connect to the Nylas client
NylasClient nylas = new NylasClient();
NylasAccount account = nylas.account("ACCESS_TOKEN");
RoomResources roomResource = account.roomResources();
List<RoomResource> roomResourceList = roomResource.list();