Electron and Microsoft Graph
Electron is a framework for creating native desktop applications with web technologies like JavaScript, HTML, and CSS. It has become a popular development platform for native applications and is seeing increasing adoption on Windows. Some of the popular applications on Windows, such as Microsoft Teams, VS Code and Slack are in fact Electron Applications!
Microsoft Graph enables developers to tap into the tremendous amount of data in Microsoft 365 to create rich, user-centric and intelligent app experiences. It provides an API endpoint to all kinds of data related to the user, such as the people they work with, files they recently opened, their agenda, and more that can easily boost user productivity in your application. For example, you can use the Microsoft Graph API to access your calendar, and find the best time for your next meeting, and schedule it too. Neat, right?
To learn more about how you can use Microsoft Graph in your application, visit their documentation or play around with the Graph APIs in the Graph Explorer.
Today, we will be bringing these two amazing technologies together and build a Microsoft Graph powered Electron application. For authentication, we will be using the Electron provider, an auth provider part of the Microsoft Graph toolkit built specifically for Electron. This blog post will cover the following sections:
- Authenticating users in a new Electron app by using the Electron Provider
- Adding content to the app and calling Microsoft Graph API’s using the Graph toolkit.
Getting Started
The Microsoft Graph Toolkit (MGT) is a collection of reusable, framework-agnostic components, and authentication providers for accessing and working with Microsoft Graph. If you want to learn more about the Microsoft Graph Toolkit, I suggest visiting a blog series called A Lap around Microsoft Graph Toolkit and then checking out our documentation.
The Electron Provider can be used to authenticate with Microsoft Identity and access Microsoft Graph in an Electron application with just a few lines of code. In this blogpost, we will build a To-Do application that allows you to view and edit your to-do’s. You will also use the Electron provider for authentication and add some other MGT (Microsoft Graph Toolkit) components to make your application look better.
And…..there’s more! This app will also have a fun feature that changes your desktop wallpaper based on your presence status fetched from the Graph, just to give you that extra push of motivation to focus when you really need to!
Let’s get started…
Create an Electron app and add the Electron provider
The following section will walk through the steps to create a simple Electron Application. If you are new to electron or want to learn more about the provider’s capabilities such as caching tokens, I recommend that you follow the Getting Started guide in our documentation. You can then come back here for the later sections.
First, let’s clone the electron-quickstart-typescript repository on GitHub. We will be building on top of this boilerplate code.
git clone https://github.com/electron/electron-quick-start-typescript.git
Navigate to the project folder.
cd electron-quick-start-typescript
Install all the necessary packages for this project.
npm install
Next, install the @microsoft/mgt-electron-provider
and @microsoft/mgt-element
npm packages as well. These will allow you to provide authentication for your app using MSAL and use the Microsoft Graph Toolkit components.
npm i @microsoft/mgt-element @microsoft/mgt-electron-provider
Next, install the @microsoft/mgt-components
package that contains all the Microsoft Graph-connected web components.
npm i @microsoft/mgt-components
Finally, confirm that you can run the app:
npm start
Initializing the provider
To enable authentication on your app, you will need to initialize two classes: ElectronAuthenticator and ElectronProvider, in the main and renderer processes respectively.
What do ElectronAuthenticator and ElectronProvider do?
- ElectronAuthenticator is responsible for setting up the configuration variables for MSAL authentication and acquiring access tokens.
- Since these tokens are needed by the components in the UI to call Microsoft Graph, we have an ElectronProvider (in the renderer process) that communicates with ElectronAuthenticator (in the main process) to request access tokens and receive information regarding signed in state.
Let’s go ahead and initialize the ElectronAuthenticator in the main process and set up the configuration variables such as client ID and required scopes.
First, open src/main.ts and import ElectronAuthenticator and MsalElectronConfig as follows:
import {
ElectronAuthenticator,
MsalElectronConfig,
} from '@microsoft/mgt-electron-provider/dist/Authenticator';
Next, add these lines of code in the createWindow() function to initialize the ElectronAuthenticator, right after where mainWindow is declared.
- Replace with the client ID from your app registration.
- mainWindow is the BrowserWindow instance that requires authentication
- scopes is a list of all the scopes that are needed to render our MGT components as well as call the presence API.
const config: MsalElectronConfig = {
clientId: '<your_client_id>',
mainWindow: mainWindow, //BrowserWindow instance that requires auth
scopes: [
'user.read',
'people.read',
'user.readbasic.all',
'contacts.read',
'presence.read.all',
'presence.read',
'user.read.all',
'calendars.read',
'Sites.Read.All',
'Sites.ReadWrite.All',
],
};
ElectronAuthenticator.initialize(config);
To initialize the ElectronProvider, add the following code to the src/renderer.ts file. In this code snippet, we are also importing all the mgt components so we can use them in our html code.
import { Providers, ProviderState } from '@microsoft/mgt-element';
import { ElectronProvider } from '@microsoft/mgt-electron-provider/dist/Provider';
import '@microsoft/mgt-components';
// initialize the auth provider globally
Providers.globalProvider = new ElectronProvider();
And that’s it! Authentication, check!
Adding content and Graph Integrations
You can now use the Microsoft Graph Toolkit components in your index.html page and show the user’s To Do tasks. For this, we are going to be using 3 MGT components:
- mgt-login (Facilitates authentication with a button to log in),
- mgt-person (Shows details about the logged in user) and
- mgt-todo (Enables the user to add, remove or edit tasks from Microsoft To Do)
Replace the content of the index.html page with the following.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>My To-Do App</title>
<script type="module" src="./dist/renderer.js"></script>
</head>
<body>
<mgt-login></mgt-login>
<mgt-person person-query="me" show-presence view="twoLines" ></mgt-person>
<mgt-todo group-by-day></mgt-todo>
</body>
</html>
We are now done with the basic version of this app!
You can now run the app with this command:
npm start
Your app should now look like this (play the GIF if it does not autoplay):
That’s how simple it is to get started with the Microsoft Graph Toolkit on Electron 😊
Change your wallpaper based on Presence data
Now for the fun part! Let’s enable this app to change the desktop wallpaper based on the user’s presence.
First, let’s install an npm package that makes it easy to change the desktop wallpaper:
npm install wallpaper
Now, our aim is to detect the state of the logged in user, and change the wallpaper based on their presence. This means we need to:
- Check if there is a logged in user, and
- Call a function to get presence data and change the user’s wallpaper.
To check if a user is logged in, in the renderer process, simply subscribe to the “onStateChanged” event that is fired by the globalProvider whenever there is a change in the logged in or logged out state.
Providers.globalProvider.onStateChanged(async (e) => {
if (Providers.globalProvider.state === ProviderState.SignedIn) {
checkPresence();
}
});
Now, we have our presence object. I’d recommend that you run console.log(presence) before the next step, just to know what the object looks like.
Let’s change the wallpaper in three situations. One, when the user’s presence is Do Not Disturb the other when it is Offline, and the last one for all others. We will need to use three different wallpapers.
You may now proceed to spend an embarrassing amount of time looking up stuff like “funny giraffe motivational wallpapers” ….No I didn’t do that :P.
Finally, let’s complete our checkPresence() function.
async function checkPresence() {
setInterval(async function () {
//Calling presence API to fetch presence data
const presence = await Providers.globalProvider.graph
.api('/me/presence')
.get();
if (presence.availability === 'DoNotDisturb') {
await wallpaper.set(‘path-to-wallpaper1’);
} else {
if (presence.availability === 'Offline') {
await wallpaper.set(‘path-to-wallpaper2’);
} else {
await wallpaper.set(path.join(‘path-to-wallpaper3’));
}
}
}, 5000);
}
As you may have noticed, I have set an interval of 5 seconds which is how often the presence API will be queried.
We’re all done! Now you have an Electron application that you can sign in to and authenticate using the Electron provider, display your to-do tasks, and change your wallpaper based on your Teams status.
The working sample is on GitHub if you want to run it locally and check it out.
Here are some links to learn more about Microsoft Graph Toolkit and the Electron Provider:
- Electron provider documentation
- Microsoft Graph Toolkit Overview and Documentation
- Toolkit Playground
- Microsoft Graph Toolkit GitHub repository
That’s all folks! The giraffe is right, I need to get back to work. See you next time!
Fantastic! 👏