Nylas Node.js SDK Migration (v5.x to v6.x)
The Nylas Node.js SDK v6.0.0 is a major release that brings many breaking changes. The goal of this release was to refactor and improve the SDK to better follow Typescript conventions. We also improved the usability by provider for better and stricter type hinting and expected parameters.
Because of these changes, you'll need to make a few changes to your application before upgrading.
Importing schemas
You need to import schemas for the Nylas Node.js SDK v6.x. You can import schemas by doing one of the following:
-
Use your IDE, such as VS Code, to automatically import schemas from
/nylas/lib/models
. For example, to import the schema for theFile
class, selectnylas/lib/models/file
from the suggestion list. -
Manually add import statements for the objects that you're using from the Node.js SDK. For example,
const Nylas = require('nylas')
const {Days} = require('nylas/lib/models/calendar-availability')
RestfulModelCollection.build() is removed
Before, you would create a new object by invoking build()
and optionally passing in a object of key-value pairs that would instantiate the object with those values.
The issue with this approach is it allowed for any value to be passed in to the object, and it forgoes any type hinting or strictness.
Now, each model class has an accompanying interface type. This interface type represents the expected fields in the properly typed model with the correct strictness. Each models’ constructor takes an optional prop object of that specific interface type. To instantiate a new model object, you can import the model from the Nylas package and use the new keyword.
No prop is passed in
The new Model(); notation with nothing passed in creates a new object with default values already set. These default values are defined at the class-level. Passing in a prop object, such as a new Model(props)
, will set the values of the model to whatever is defined in prop.
Prop is passed in
If prop is passed in, it must match the expected type that accompanies the model class and must include all the required properties at a minimum. Models that are RestfulModel
type, such as Calendar, Event, Draft, a NylasConnection
object must also be passed in as these objects can be directly saved and loaded from the Nylas API.
Create a draft comparison
All classes and properties are exported by the package and can be imported in your application for use.
Nylas.config({clientId: 'clientId', clientSecret: 'clientSecret'});
const nylas = Nylas.with('access_token');
/*
* Create a new draft object by passing in the correct properties
*
* For `Draft`, the accompanying `DraftProperties` type outlines all the fields
* and at the very least you must provide a 'to' field
*/
const draftProperties = {
to: [{ name: 'Nylas Swag', email: '[email protected]' }],
subject: 'With Love, From Nylas',
body: 'This email was sent using the Nylas email API. Visit https://nylas.com for details.',
files: [{ id: '{file_id}' }],
replyToMessageId: '<message_id>'
}
/*
* Note that because `Draft` is a `RestfulModel` type we must pass in
* a `NylasConnection` type at the minimum.
* We will pass in the 'draftProperties' from above to init our `Draft`
* object with the values we want
*/
const draft = new Draft(nylas, draftProperties);
// Save the draft to send it
draft.save()
Nylas.config({clientId: 'clientId', clientSecret: 'clientSecret'});
const nylas = Nylas.with('access_token');
// Create a new draft object
const draft = nylas.drafts.build({
to: [{ name: 'Nylas Swag', email: '[email protected]' }],
subject: 'With Love, From Nylas',
body: 'This email was sent using the Nylas email API. Visit https://nylas.com for details.',
files: [{ id: '{file_id}' }],
replyToMessageId: '<message_id>'
});
// Save the draft to send it
draft.save()
Type changes
The SDK has more typing which covers return types for functions as well as proper typing for attributes.
With this change we identified a few properties that were too abstract or defined well and turned them into classes of Model type.
Event.when changed to When
To specify the when property of an event during initialization it must be set according to WhenProperties
. You can also set the when properties after creating an empty Event
. Helper setter functions Event.start()
and Event.end()
are still available.
Nylas.config({clientId: 'clientId', clientSecret: 'clientSecret'});
const nylas = Nylas.with('access_token');
const eventProperties = {
calendarId: '{CALENDAR_ID}',
when: {
startTime: 1577829600,
endTime: 1577840400,
startDate: '2022-08-29',
endDate: '2022-09-01'
},
title: 'Party!',
location: 'My House!',
description: 'Let\'s celebrate our calendar integration!!',
busy: true
}
const event = new Event(nylas, eventProperties);
Nylas.config({clientId: 'clientId', clientSecret: 'clientSecret'});
const nylas = Nylas.with('access_token');
const event = new Event(nylas);
event.calendarId = '{CALENDAR_ID}';
event.when.startTime = 1577829600;
event.when.endTime = 1577840400;
event.when.startDate = '2022-08-29';
event.when.endDate = '2022-09-01';
event.title = 'Party!';
event.location = 'My House!';
event.description = 'Let\'s celebrate our calendar integration!!';
event.busy = true;
Nylas.config({clientId: 'clientId', clientSecret: 'clientSecret'});
const nylas = Nylas.with('access_token');
const event = new Event(nylas);
event.calendarId = '{CALENDAR_ID}';
event.start = 1577829600;
event.end = 1577840400;
event.title = 'Party!';
event.location = 'My House!';
event.description = 'Let\'s celebrate our calendar integration!!';
event.busy = true;
NeuralMessageOptions changed to a model class
Previously, NeuralMessageOptions
was a interface class, it is now a model class.
When calling Neural.extractSignature()
function, the options parameter is of NeuralMessageOptionsProperties
type instead of NeuralMessageOptions
. This means the key values of options are camelCase instead of snake_case for consistency, in terms of changes to existing applications.
Nylas.config({clientId: 'clientId', clientSecret: 'clientSecret'});
const nylas = Nylas.with('access_token');
const extractedSignature = nylas.neural.extractSignature(['MESSAGE_ID'], {
ignoreImages: true,
ignoreLinks: true,
ignoreTables: true,
imagesAsMarkdown: true,
});
New model classes for CalendarRestfulModelCollection functions
In the CalendarRestfulModelCollection
class, we have the following functions for scheduling-related operations:
freeBusy()
availability()
consecutiveAvailability()
Previously, they provided limited type hinting, limited hinting for request parameters, and no structure for the returned object from the API. We would return JSON. Now, we provide an interface type for the options
parameter of each of these methods as well as a Model representing the expected response from the API.
FreeBusy
The freeBusy()
function now expects options to be an object that matches FreeBusyQuery
, and it returns a FreeBusy
type:
Nylas.config({clientId: 'clientId', clientSecret: 'clientSecret'});
const nylas = Nylas.with('access_token');
const freeBusy: FreeBusy[] = await nylas.calendars.freeBusy({
startTime: 1577829600,
endTime: 1577840400,
emails: ['[email protected]']
})
const email = freeBusy[0].email;
const timeSlot: TimeSlot = freeBusy[0].timeSlots[0];
const timeSlotStatus = timeSlot.status;
const timeSlotStartTime = timeSlot.startTime;
const timeSlotEndTime = timeSlot.status;
Availability
The availability()
function now expects options to be an object that matches SingleAvailabilityQuery
, and it returns a CalendarAvailability
type. In SingleAvailabilityQuery
, freeBusy
is of FreeBusyProperties
type and openHours
are of OpenHoursProperties
type. To make things easier when setting openHours
, the days
property can be set using the Days
enum. This correctly formats the day of the week to its corresponding numerical value instead of referring back to the API reference.
Nylas.config({clientId: 'clientId', clientSecret: 'clientSecret'});
const nylas = Nylas.with('access_token');
const availability: CalendarAvailability = await nylas.calendars.availability({
startTime: 1590454800,
endTime: 1590780800,
interval: 5,
duration: 30,
emails: ['[email protected]'],
openHours: [
{
emails: ['[email protected]'],
days: [Days.Sunday],
timezone: 'America/Chicago',
start: '10:00',
end: '14:00',
},
],
});
const timeSlot = availability.timeSlots[0];
const timeSlotStatus = timeSlot.status;
const timeSlotStartTime = timeSlot.startTime;
const timeSlotEndTime = timeSlot.status;
Consecutive availability
The consecutiveAvailability()
function now expects options to be an object that matches ConsecutiveAvailabilityQuery
, and it returns a CalendarConsecutiveAvailability
type.
Nylas.config({clientId: 'clientId', clientSecret: 'clientSecret'});
const nylas = Nylas.with('access_token');
// Consecutive availability
const consecutiveAvailability: CalendarConsecutiveAvailability = await nylas.calendars.consecutiveAvailability({
startTime: 1590454800,
endTime: 1590780800,
interval: 5,
duration: 30,
emails: [['[email protected]'], ['[email protected]']],
openHours: [
{
emails: ['[email protected]', '[email protected]'],
days: [Days.Sunday],
timezone: 'America/Chicago',
start: '10:00',
end: '14:00',
},
],
});
const emails = consecutiveAvailability.emails;
const startTime = consecutiveAvailability.startTime;
const endTime = consecutiveAvailability.endTime;
Connect functions
Connect.authorize()
takes new parameter types and a new return type.
For sending authorization, the auth
parameter takes in either a VirtualCalendarProperties
or a NativeAuthenticationProperties
type depending on the type of authentication that needs to be performed. In either case, the return type is the same, an AuthorizationCode
type. This is an object that contains one key, a code
(string).
For convenience, we also have provided two useful enum types that can be imported and used in your application. Scope
provides all the possible authorization scopes, and NativeAuthenticationProvider
contains all the providers supported by native authentication.
// For Virtual Calendar authorization
const virtualCalendarAuth = await Nylas.connect.authorize({
name: "Virtual Calendar",
emailAddress: "virtual_account_unique_id",
clientId: "CLIENT_ID", // Note that clientId is optional, defaults to the clientId configured above in Nylas.config()
});
const code = virtualCalendarAuth.code;
// For other authorization
const googleAuth = await Nylas.connect.authorize({
clientId: "CLIENT_ID",
emailAddress: "[email protected]",
scopes: [Scope.EmailReadOnly, Scope.CalendarReadOnly, Scope.ContactsReadOnly],
name: "Google",
provider: NativeAuthenticationProvider.Gmail,
settings: {
google_client_id: "{google_api_client_id}",
google_client_secret: "{geoogle_api_client_secret}",
google_refresh_token: "{google_api_refresh_token}"
}
});
const code = googleAuth.code;
Connect.token() returns an account type
Previously, exchanging the token would result in a JSON returned from the API. However, the object returned from the API is actually an account object. So instead of the SDK returning a JSON of any or unknown type, the SDK now returns an Account
type.
Nylas.application() only takes camelCase parameters
In Nylas.application()
the options
parameter allowed the user to pass in application_name
and redirect_uris
in addition to applicationName
and redirectUris
. To eliminate confusion and improve consistency, we have removed the snake_case parameters and left the camelCase parameters.
Removals
In addition to RestfulModelCollection.build()
, we have made other removals in this new version of the SDK. These removals should have little to no impact. In case you use these functions, the following have been removed:
Connect.newAccount()
- The function body was empty and commented out and has no purposeFile.metadata()
- This is the same as making anylas.files.find(``'``ID``'``);
call and is redundant
What's next?
- Learn about Nylas Node.js SDK releases.