import msal
import requests
import datetime
class OutlookAuth:
def __init__(self, client_id, client_secret, tenant_id, user_id):
"""
:param client_id: Azure app client ID
:param client_secret: Azure app client secret
:param tenant_id: Azure tenant ID
:param user_id: The email or user principal name of the calendar owner
"""
self.client_id = client_id
self.client_secret = client_secret
self.tenant_id = tenant_id
self.user_id = user_id
self.scope = ["https://graph.microsoft.com/.default"]
self.authority = f"https://login.microsoftonline.com/{tenant_id}"
self.app = msal.ConfidentialClientApplication(
client_id=self.client_id,
authority=self.authority,
client_credential=self.client_secret
)
self.access_token = self.get_access_token()
def get_access_token(self):
print("Requesting token with client_id:", self.client_id)
result = self.app.acquire_token_for_client(scopes=self.scope)
if "access_token" in result:
return result["access_token"]
else:
print("Full error result:", result)
raise Exception(f"Auth error: {result.get('error_description', 'Unknown error')}")
def get_calendar_events(self):
url = f"https://graph.microsoft.com/v1.0/users/{self.user_id}/events"
headers = {
"Authorization": f"Bearer {self.access_token}",
"Content-Type": "application/json"
}
response = requests.get(url, headers=headers)
if response.status_code == 200:
return response.json().get('value', [])
else:
print(f"Error fetching events: {response.status_code}")
print("Get_Calendar_Response:", response.text)
return []
def time_conflicts(self, new_start_time, new_end_time):
events = self.get_calendar_events()
if not events:
return False
for event in events:
existing_start = datetime.datetime.fromisoformat(event["start"]["dateTime"])
existing_end = datetime.datetime.fromisoformat(event["end"]["dateTime"])
if (new_start_time < existing_end and new_end_time > existing_start):
return True
return False
def create_event(self, start_time, end_time, subject="Room Booking"):
url = f"https://graph.microsoft.com/v1.0/users/{self.user_id}/events"
headers = {
"Authorization": f"Bearer {self.access_token}",
"Content-Type": "application/json"
}
event_data = {
"subject": subject,
"start": {
"dateTime": start_time,
"timeZone": "Australia/Sydney"
},
"end": {
"dateTime": end_time,
"timeZone": "Australia/Sydney"
}
}
response = requests.post(url, headers=headers, json=event_data)
if response.status_code == 201:
print("Event created successfully")
return response.json().get("id")
else:
print(f"Error creating event: {response.status_code}")
print("Create_Response:", response.text)
return None
def update_event(self, event_id, new_start_time, new_end_time, new_subject=None):
url = f"https://graph.microsoft.com/v1.0/users/{self.user_id}/events/{event_id}"
headers = {
"Authorization": f"Bearer {self.access_token}",
"Content-Type": "application/json"
}
event_data = {
"start": {
"dateTime": new_start_time,
"timeZone": "Australia/Sydney"
},
"end": {
"dateTime": new_end_time,
"timeZone": "Australia/Sydney"
}
}
if new_subject:
event_data["subject"] = new_subject
response = requests.patch(url, headers=headers, json=event_data)
if response.status_code == 200:
print("Event updated successfully")
else:
print(f"Error updating event: {response.status_code}")
print("Response:", response.text)
def delete_event(self, event_id):
url = f"https://graph.microsoft.com/v1.0/users/{self.user_id}/events/{event_id}"
headers = {
"Authorization": f"Bearer {self.access_token}",
}
response = requests.delete(url, headers=headers)
if response.status_code == 204:
print("Event deleted successfully")
else:
print(f"Error deleting event: {response.status_code}")
print("Response:", response.text)
if __name__ == "__main__":
client_id = 'my client-id'
client_secret = 'my client secret-id'
tenant_id = 'my tenant-id'
user_id = "******@bournecloud.com.au"
outlook_auth = OutlookAuth(client_id, client_secret, tenant_id, user_id)
start = "2025-04-25T14:00:00"
end = "2025-04-25T15:00:00"
event_id = outlook_auth.create_event(start, end, subject="Hotel Room Booking")
events = outlook_auth.get_calendar_events()
print(f"Fetched {len(events)} events.")