Version:
Only show these results:

Configure authentication for the Scheduler Editor Component

The Scheduler Editor Component uses the Hosted authentication details in nylasSessionsConfig to interact with the Nylas APIs. Instead of using nylasSessionsConfig, you can use nylasApiRequest property in the either of the following situations:

Download Nylas identity package

To use nylasApiRequest, you first need to download the Nylas identity package:

npm i @nylas/identity@latest   

Use existing Nylas Hosted authentication

If you're already using Nylas Hosted auth in your application, you can use nylasApiRequest with NylasIdentityRequestWrapper.

You can also check the complete code in GitHub.

<html class="h-full bg-white" lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Nylas Scheduler Editor with auth using NylasIdentityRequestWrapper</title>

<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap"
rel="stylesheet"
/>


<style type="text/css">
body {
font-family: "Inter", sans-serif;
}
</style>
</head>

<body class="h-full">
<div class="grid h-full place-items-center">
<!-- Add the Nylas Scheduler Editor component -->
<nylas-scheduler-editor />
</div>

<!-- Configure the Nylas Scheduler Editor component -->
<script type="module">

import { defineCustomElement } from "https://cdn.jsdelivr.net/npm/@nylas/web-elements@latest/dist/cdn/nylas-scheduler-editor/nylas-scheduler-editor.es.js";
import { NylasSessions } from 'https://cdn.jsdelivr.net/npm/@nylas/identity@latest/dist/nylas-identity.es.js';
import { NylasIdentityRequestWrapper } from 'https://cdn.jsdelivr.net/npm/@nylas/web-elements@latest/dist/esm/index.js';

defineCustomElement();

// Specify settings for Nylas identity management
const config = {
clientId: '<NYLAS_CLIENT_ID>',
redirectUri: `${window.location.origin}/login`,
domain: 'https://api.us.nylas.com/v3', // or 'https://api.eu.nylas.com/v3' for th E.U. region
hosted: false,
accessType: "offline",
};
const identity = new NylasSessions(config);

async function checkLoggedIn() {
const loggedIn = await identity.isLoggedIn();
return loggedIn;
}

// Create a new nylasApiRequest instance
const nylasApiRequest = new NylasIdentityRequestWrapper(identity);

// Specify Scheduler Editor Component details
const schedulerEditor = document.querySelector("nylas-scheduler-editor");
schedulerEditor.nylasApiRequest = nylasApiRequest;
schedulerEditor.schedulerPreviewLink = `${window.location.origin}/?config_id={config.id}`;
schedulerEditor.eventOverrides = {
// The default behavior of the close button is to log out the user, so redirect to the login page
schedulerConfigCloseClicked: async (e) => {
setTimeout(async () => {
window.location.href = `${window.location.origin}/login`;
}, 3000);
},
}
schedulerEditor.defaultSchedulerConfigState = {
selectedConfiguration: {
requires_session_auth: false, // Create a public configuration which doesn't require a session
},
};

// Redirect to the login page if the user is not logged in
checkLoggedIn().then((loggedIn) => {
if (!loggedIn) {
window.location.href = `${window.location.origin}/login`;
}
});
</script>
</body>
</html>
import { BrowserRouter, Route, Routes } from "react-router-dom";
import { NylasSchedulerEditor, NylasScheduling } from "@nylas/react";
import LoginComp from '@nylas/login-component';
import "./App.css";
import { NylasSessions } from '@nylas/identity';
import { NylasIdentityRequestWrapper } from '@nylas/react';

function App() {
// Get the configuration ID from the URL query string
const urlParams = new URLSearchParams(window.location.search);
const clientId = '<NYLAS_APP_CLIENT_ID>';
const configId = urlParams.get("config_id") || "";
const componentSettings = {
// Adjust the scopes as needed
authSettings: {
scopes: {
google: [
'openid',
'https://www.googleapis.com/auth/userinfo.email',
'https://www.googleapis.com/auth/userinfo.profile',
'https://www.googleapis.com/auth/contacts',
'https://www.googleapis.com/auth/calendar',
'https://www.googleapis.com/auth/directory.readonly',
],
microsoft: ['Calendars.ReadWrite', 'Mail.ReadWrite', 'Contacts.ReadWrite', 'User.Read', 'offline_access'],
},
},
};
const identitySettings = {
clientId: clientId,
redirectUri: `${window.location.origin}/nylas-auth/scheduler-editor`,
domain: 'https://api.us.nylas.com/v3', // or 'https://api.eu.nylas.com/v3' for the E.U. data region
hosted: true,
accessType: 'offline',
};
const identity = new NylasSessions(identitySettings);
const nylasApiRequest = new NylasIdentityRequestWrapper(identity);

return (
<BrowserRouter>
<Routes>
<Route path="/meet" element={
<div>
<a href="/scheduler-editor" className="button">View Scheduler Editor</a>
<NylasScheduling
configurationId={configId}
schedulerApiUrl="https://api.us.nylas.com" // or 'https://api.eu.nylas.com' for the E.U. data region
/>
</div>
}
/>

<Route path="/login" element={
<div>
<LoginComp
clientId={clientId}
redirectUri={`${window.location.origin}/nylas-auth/scheduler-editor`}
config={componentSettings}
identity={identity} popup={false} hosted={false} />
</div>
}
/>

<Route path="/nylas-auth/scheduler-editor" element=
{
<div>
<NylasSchedulerEditor
schedulerPreviewLink={`${window.location.origin}/meet?config_id={config.id}`}
nylasApiRequest={nylasApiRequest}
defaultSchedulerConfigState={{
selectedConfiguration: {
requires_session_auth: false, // Creates a public configuration which doesn't require a session
}
}}

/>
</div>
} />
</Routes>
</BrowserRouter>
);
}
export default App;

Use Custom authentication

If you want to use Custom auth or a different HTTP client library for authentication, you can define a custom wrapper (CustomIdentityRequestWrapper) which implements nylasApiRequest, and set the nylasApiRequest property with CustomIdentityRequestWrapper.

The Scheduler Editor Component and CustomIdentityRequestWrapper require an access token from the same origin. To get the access token:

  1. Add a callback URI.
  2. Make an authorization request to retrieve a code.
  3. Exchange the code for an access token.

Add a callback URI

  1. In your Nylas application, click Hosted Authentication in the left navigation, and click Callback URIs.
  2. Click Add a callback URI.
  3. Select the JavaScript platform.
  4. For URL, enter https://127.0.0.1:3000/scheduler-editor.
    This assumes you host the Scheduler Editor on localhost:3000. The URL will vary based on your hosting choice.
  5. For Origin, enter https://127.0.0.1:3000.
  6. Click Add callback URI.

Make an authorization request

Make a GET /v3/connect/auth request to retrieve an authorization code that you can exchange for an access token.

/v3/connect/auth?
client_id=<NYLAS_CLIENT_ID>
&redirect_uri=https://127.0.0.1:3000/scheduler-editor
&response_type=code
&provider=google
&access_type=offline

Exchange the code for an access token

Using the code from your authorization request, make a POST /v3/connect/token request to get the access token.

curl --request POST \
--url 'https://api.us.nylas.com/v3/connect/token' \
--header 'Content-Type: application/json' \
--header 'Origin: 'https://127.0.0.1:3000' \
--data '
{
"code": "<AUTHORIZATION_CODE>",
"client_id": "<NYLAS_CLIENT_ID>",
"client_secret": "<NYLAS_API_KEY>",
"redirect_uri": "https://127.0.0.1:3000/scheduler-editor",
"grant_type": "authorization_code"
}'

You can then use the access token in CustomIdentityRequestWrapper and the Scheduler Editor Component. Make sure that CustomIdentityRequestWrapper has a currentUser function that returns the same email address that is associated with the access token.

Example: CustomIdentityRequestWrapper and the Scheduler Editor Component

You can also check the complete code in GitHub.

export class CustomIdentityRequestWrapper {
private accessToken: string;

constructor(accessToken: string) {
// Initialize the class
this.accessToken = accessToken;
}
async request<T = any>(args: any): Promise<T> {
try {
const response = await fetch(`https://api.us.nylas.com/v3/grants/me/${args.path}`, {
method: args.method,
body: JSON.stringify(args.body),
headers: {
...args.headers,
'Authorization': `Bearer ${this.accessToken}`,
'Content-Type': 'application/json',
},
});

// Check if the response is not okay (e.g., 404, 500)
if (!response.ok) {
console.error(`Error: ${response.status} ${response.statusText}`);
return { error: `Error: ${response.status} ${response.statusText}` } as any;
}

// Parse the response
const data = await response.json();
return [data, null] as any;
} catch (error) {
console.error('Fetch error:', error);
return { error: "Error" } as any;
}
}

/**
* This method returns the current user's information.
*/


async currentUser() {
// IMPLEMENT: Get the logged in user's ID token and return the user information. For example,
return {
id: 'idToken.sub',
email: 'j.doe@example.com',
name: 'John Doe',
provider: 'google',
};
}

/**
* This method sets the default authentication arguments to use when authenticating the user.
*/

async setDefaultAuthArgs(authArgs: any) {
// Set the default authentication arguments
return authArgs;
};

/**
* This method returns the URL to redirect the user to for authentication.
*/

async authenticationUrl(): Promise<string | undefined> {
// IMPLEMENT: Return the URL to redirect the user to for authentication. For example,
return 'https://example.com/auth';
}
}
<html class="h-full bg-white" lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Nylas Scheduler Editor Component</title>

<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap"
rel="stylesheet"
/>


<script src="https://cdn.tailwindcss.com"></script>

<style type="text/css">
body {
font-family: "Inter", sans-serif;
}
</style>
</head>

<body class="h-full">
<div class="grid h-full place-items-center">
<!-- Add the Nylas Scheduler Editor component -->
<nylas-scheduler-editor />
</div>

<!-- Configure the Nylas Scheduler Editor component -->
<script type="module">

import { defineCustomElement } from "https://cdn.jsdelivr.net/npm/@nylas/web-elements@latest/dist/cdn/nylas-scheduler-editor/nylas-scheduler-editor.es.js";
import { CustomIdentityRequestWrapper } from './custom.js';

defineCustomElement();

const schedulerEditor = document.querySelector("nylas-scheduler-editor");
schedulerEditor.schedulerPreviewLink = `${window.location.origin}/?config_id={config.id}`;

const accessToken = 'NYLAS_ACCESS_TOKEN';
const domain ='https://api.us.nylas.com/v3'; // or 'https://api.eu.nylas.com/v3' for th E.U. region

// Create an instance of the CustomIdentityRequestWrapper class defined above
const nylasApiRequest = new CustomIdentityRequestWrapper(accessToken, domain);
schedulerEditor.nylasApiRequest = nylasApiRequest

schedulerEditor.defaultSchedulerConfigState = {
selectedConfiguration: {
requires_session_auth: false, // Creates a public configuration which doesn't require a session
},
};
</script>
</body>
</html>
import { BrowserRouter, Route, Routes } from "react-router-dom";
import { NylasSchedulerEditor, NylasScheduling } from "@nylas/react";
import { CustomIdentityRequestWrapper } from './custom';
import "./App.css";

function App() {
const accessToken = 'NYLAS_ACCESS_TOKEN';
const domain ='https://api.us.nylas.com/v3'; // or 'https://api.eu.nylas.com/v3' for the E.U. region

// Get the configuration ID from the URL query string
const urlParams = new URLSearchParams(window.location.search);
const configId = urlParams.get("config_id") || "";

const nylasApiRequest = new CustomIdentityRequestWrapper(accessToken, domain);

return (
<BrowserRouter>
<Routes>
<Route path="/meet" element={
<div>
<a href="/scheduler-editor" className="button">View Scheduler Editor</a>
<NylasScheduling
configurationId={configId}
schedulerApiUrl="https://api.us.nylas.com" // or 'https://api.eu.nylas.com' for the E.U. region
/>
</div>
}
/>

<Route path="/custom-auth/scheduler-editor" element=
{
<div>
<NylasSchedulerEditor
schedulerPreviewLink={`${window.location.origin}/meet?config_id={config.id}`}
nylasApiRequest={nylasApiRequest}
defaultSchedulerConfigState={{
selectedConfiguration: {
requires_session_auth: false, // Creates a public configuration which doesn't require a session
}
}}

/>
</div>
} />
</Routes>
</BrowserRouter>
);
}
export default App;