Tuesday, March 31, 2020

Using microsoft graph API to book things in outlook

Quick notice

I hate microsoft. Soooo much. And its API even more. I hated everything about using it, and having to read its very hard to understand documentation.
But it's the lesser evil to actually having to use ms outlook to book meeting rooms in an environment non ms free. The real solution is to get rid of microsoft and everything microsoft in your office.

Purpose

My office has these meeting rooms, which are always occupied. And it's very hard to make a reservation. I hate ms outlook too much to have to do this every day manually, so I checked out the ms "graph API" (in case you wonder, it's not to make "graphs", it's just the stupid name they use for their office API).
Now I can get all the meeting rooms I need daily for all my team without having to move a finger.

Code

The actual script I use is here: https://gitlab.com/rikijpn/ugly_ms_outlook_appointment_taker
I'm obviously removing all the tokens though.
It's in python, running daily. So you can just put this in cron, so as soon as they let you book meeting rooms (like 30, 60 days after the current day's specific time) you'be able to send the appointment request.

Preparation (create an "app")


1. create app (in your azure portal)
In the left-hand navigation pane, select the Azure Active Directory service, and then select App registrations → New registration.
https://portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/RegisteredApps
2. in azure, select Manage → API Permissions → app (Microsoft APIs → Microsoft Graph → Delegated permissions)
Make sure you have the following permissions:
Calendars.ReadWrite
User.Read
offline_access

3. in azure, select Manage → Authentication → "Default client type" → "Treat application as public client"
4. in azure, select Manage → Authentication → "Supported account types" → "Accounts in this organizational directory only (this will probably have your company/school name here)"
5. get consent
https://login.microsoftonline.com/${tenant_id}/oauth2/v2.0/authorize?client_id=${client_id}&response_type=code&response_mode=query&state=12345&scope=offline_access%20user.read%20Calendars.ReadWrite
The "tenant_id" here is just  whatever you already have in your url when looking azure, a long senseless string, that is common through all the pages for your organization.
"client_id" will be shown in your "app"'s top/info page.
You can just ignore the rest and use it as it is.

Put this in your browser, and you'll be sent to a blank page by default. Check the URL in your browser, and you'll see there will be an "access" and "refresh" token.

Usage

And that's pretty much it. Now you are ready to do some tests.
I'm posting the test code (emacs's restclient-mode stuff) in the same gitlab repo: https://gitlab.com/rikijpn/ugly_ms_outlook_appointment_taker/-/blob/master/sample_requests.txt
In short, every time you want to use it, you'll have to use your "refresh_token" to create a new "access_token", which lasts very shortly (a couple of mins? one hour? don't remember).


One thing though, is that every time you change your password, you'll have to do get consent again:
https://login.microsoftonline.com/${tenant_id}/oauth2/v2.0/authorize?client_id=${client_id}&response_type=code&response_mode=query&state=12345&scope=offline_access%20user.read%20Calendars.ReadWrite

And update your tokens.

When you make a meeting room reservation (appointment, using the meeting room as a "resource"), you'll get a 200 status code if your auth has no issues. But that DOES NOT mean your meeting room was acknowledged, and that you got the meeting room. It just means the damn ms outlook server got  your request. The pain.
You'll get an e-mail with the approval/denial response a bit after your request is processed. I think you can also check with the API somehow.

Final thoughts

Really ugly documentation. That's how I've described pretty much all ms documentation in the past, and how I still do for everything about this "graph API" thing.
It's like, they don't really want you to be able to use it.
The token usage is frankly not bad, seems like a good (secure and clear) authorization and all, most likely thanks to its usage of OAuth2.0 and JWT.

No comments:

Post a Comment