Because why pay money for something you can do yourself?
MeetEasier is a web application that visualizes meeting room availability. It works using Microsoft Graph API in Microsoft 365.
Note: The Exchange Web Services (EWS) is deprecated and will be removed in the future.
MeetEasier is licensed under the open source GNU General Public License (GPL 3.0).
In the event of wanting to commercially distribute a closed source modification of this code, please contact me.
- v0.3.4
- #34 - bug fix for 'Next up:' displaying incorrectly
- v0.3.3
- #18 - use localized sort for rooms
- v0.3.2
- Added additional error handling for incorrect credentials. The error will now be shown on the front end.
- Updated the socket component to stop most ERR_CONNECTION_REFSUED errors from happening.
- v0.3.1
- Removed skipped rooms/room blacklist filtering from front end and added to back end.
- v0.3
- Cleaned up unnecessarily nested component folder structure
- #8 - add script-shortcuts to
package.json
in root - #9 - support environment-variables for authentication and port configuration
- #10 - create shrinkwraps for npm-dependencies
- #11 - add
.editorconfig
- #12 - pass error (while fetching appointments), to frontend
- #13 - set engine-requirements
- #14 - add heartbeat-endpoint, to check if server is alive (for monitoring)
- #15 - add '.nvmrc'
- v0.2
- Changed domain to accept more than just ".com" extension
- Changed
ui-react/config/flightboard.config.js
to handle all text so that the application can be multilingual - Added
ui-react/config/singleRoom.config.js
to do the same for thesingle-room
component - Added
console.log
toserver.js
to know when the server is running correctly - Updated styles slightly
- v0.1
- Initial release
This application assumes you have:
- Microsoft Graph API (Microsoft 365)
- Conference room mailboxes organized in room lists
- A registered application in Azure AD (see here for more information)
- A web server with Node.js installed to run the application
Please Note: This application uses Basic Authentication which, by its very nature, is insecure. I would strongly suggest using SSL where ever you decide to run this.
- Optional: Install IISNode
- I've also included a
web.config
file for an IIS install
- I've also included a
- In root directory, open a terminal or cmd:
$ npm install
- In the root directory, open a terminal or cmd:
$ npm run build
- In the root directory, open a terminal or cmd:
$ npm start
- If you want to start the react development server, in the root directory run:
$ npm start-ui-dev
app/
: Routes for MSGRAPH and EWS APIsapp/ews/
: All EWS functionalityapp/msgraph/
: All Microsoft Graph functionalityconfig/
: All server side configuration settingsscss/
: All stylesstatic/
: All global static filesui-react/
: Front end React routes and components
There are three main directories in the ui-react/src/
folder:
components/
: Components separated in folders by functionconfig/
: Customizable config file (see defails below in Customization section)layouts/
: Layout components for the two different layouts used.
flightboard/
: All components related to the flightboard or "all meeting" layoutglobal
: Components that will be used by both layoutssingle-room
: All components related to the Single Room layout
Board
: Actual flightboard component itselfClock
: Clock component for the upper right hand of the displayNavbar
: Top navigation/title bar pieceRoomFilter
: Room list filter in the navbar
NotFound
: A "not found" page if an error or "404" occursSocket
: A service component to run the web socket connection for updating the flightboard and single room display
Clock
: Clock component for the upper right hand of the displayDisplay
: All other features of the single room display
flightboard.config.js
: Simple customization config explained in the Customization section
flightboard/
: Layout for flightboard displaysingle-room/
: Layout for single room display
- Login to the Microsoft 365 admin center
- Go to the "Azure Active Directory" admin center
- Go to "App Registrations"
- Click "New Registration"
- Enter a name for the application, e.g. "MeetEasier"
- Select "Accounts in this organizational directory only", and leave everything else default
- Click "Register"
- Copy the "Application (client) ID" and save it for later
- Copy the "Directory (tenant) ID" and save it for later
- Click "Certificates & secrets"
- Click "New client secret"
- Enter a description, e.g. "MeetEasier secret"
- Set the expiration to "Custom" and set to however long you want the secret to last
- Click "Add"
- Copy the secret and save it for later
- Click "API permissions"
- Click "Add a permission"
- Select "Microsoft Graph"
- Select "Application permissions"
- Select "Calendars.Read, Place.Read.All, User.Read.All"
- Click "Add permissions"
- Click "Grant admin consent for your tenant"
- Click "Yes"
And you're done!
Set enviroment variables, or use a .env file (prefered method). See .env.template for details on what variables are needed. You may skip the EWS_ and DOMAIN variables as this is now deprecated.
- Using a .env file, rename or copy the .env.template file to .env and fill in the values. Run the following comand in the top-level directory of this project:
cp .env.template .env
- Using enviroment variables, run the following in the shell:
export OAUTH_CLIENT_ID=0c9c8ca8-5a1a-11ed-9b6a-0242ac120002 (from step 8 above)
export OAUTH_AUTHORITY=https://login.microsoftonline.com/00afbbe0-5a1a-11ed-9b6a-0242ac120002 (from step 9 above)
export OAUTH_CLIENT_SECRET=XuR8Q~OotnWOrUholnAZWu4p~5VplaCBGUZA1a9S (from step 15 above)
export SEARCH_USE_GRAPHAPI=true
export SEARCH_MAXROOMLISTS=10
export SEARCH_MAXDAYS=10
export SEARCH_MAXITEMS=6
-
In
/config/room-blacklist.js
, add any room by email to exclude it from the list of rooms:module.exports = { roomEmails: ["[email protected]"], };
-
In
/ui-react/src/config/flightboard.config.js
, manage your customizations:module.exports = { board: { nextUp: "Next Up", statusAvailable: "Open", statusBusy: "Busy", statusError: "Error", }, navbar: { title: "Conference Room Availability", }, roomFilter: { filterTitle: "Locations", filterAllTitle: "All Conference Rooms", }, };
-
Upload your logo to
/static/img/logo.png
- All EWS functionality is located in
app/ews
. - To change the interval in which the web socket emits, edit the interval time in
app/socket-controller.js
. By default, it is set to 1 minute. - To update styles, make sure you install grunt first with
npm install -g grunt-cli
. Then rungrunt
in the root directory to watch for SCSS changes. Use the.scss
files located in the/scss
folder.- All React components can be locally styled by adding a new
.css
file and importing it into the component itself if you'd prefer to do it that way.
- All React components can be locally styled by adding a new
- In
app/ews/rooms.js
, there is a block of code that may not be necessary but were added as a convenience. Feel free to use it, comment it out, or remove it completely. It was designed for a use case where the email addresses (ex: [email protected]) do not match the corporate domain (ex: jsmith-enterprise).// if the email domain != your corporate domain, // replace email domain with domain from auth config var email = roomItem.Address; email = email.substring(0, email.indexOf("@")); email = email + "@" + auth.domain + ".com";