awacke1 commited on
Commit
7d4aef0
Β·
verified Β·
1 Parent(s): a13b66a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +442 -31
app.py CHANGED
@@ -2,6 +2,7 @@ import os
2
  import streamlit as st
3
  import requests
4
  import msal
 
5
  import base64
6
  import hashlib
7
  import secrets
@@ -10,9 +11,12 @@ import secrets
10
  APPLICATION_ID_KEY = os.getenv('APPLICATION_ID_KEY')
11
  CLIENT_SECRET_KEY = os.getenv('CLIENT_SECRET_KEY')
12
  AUTHORITY_URL = 'https://login.microsoftonline.com/common' # Use 'common' for multi-tenant apps
13
- REDIRECT_URI = 'https://huggingface.co/spaces/awacke1/MSGraphAPI' # Update this to match your app's redirect URI
 
 
14
 
15
  # 🎯 Define the scopes your app will need
 
16
  SCOPES = ['User.Read']
17
 
18
  # New function to generate PKCE code verifier and challenge
@@ -21,15 +25,49 @@ def generate_pkce_codes():
21
  code_challenge = base64.urlsafe_b64encode(hashlib.sha256(code_verifier.encode()).digest()).decode().rstrip('=')
22
  return code_verifier, code_challenge
23
 
24
- # πŸ› οΈ Initialize the MSAL client for Public Client App (PKCE support)
25
- def get_msal_app():
26
  return msal.PublicClientApplication(
27
  client_id=APPLICATION_ID_KEY,
28
  authority=AUTHORITY_URL
29
  )
 
 
 
 
 
 
 
 
30
 
31
  # πŸ” Acquire access token using authorization code
32
- def get_access_token(code, code_verifier=None):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  client_instance = get_msal_app()
34
 
35
  st.write("Debug: MSAL App Configuration:")
@@ -38,12 +76,11 @@ def get_access_token(code, code_verifier=None):
38
  st.write(f"Redirect URI: {REDIRECT_URI}")
39
 
40
  try:
41
- # Attempt to acquire token, use PKCE code_verifier if provided
42
  result = client_instance.acquire_token_by_authorization_code(
43
  code=code,
44
  scopes=SCOPES,
45
  redirect_uri=REDIRECT_URI,
46
- code_verifier=code_verifier # Include only if PKCE is enabled
47
  )
48
 
49
  if 'access_token' in result:
@@ -54,62 +91,87 @@ def get_access_token(code, code_verifier=None):
54
  except Exception as e:
55
  st.error(f"Exception in get_access_token: {str(e)}")
56
  raise
57
-
58
- # πŸƒβ€β™‚οΈ Main function to process the query parameters and handle the token exchange
59
  def process_query_params():
 
60
  try:
61
- query_params = st.experimental_get_query_params()
62
  st.write("Debug: All query parameters:", query_params)
63
 
64
  if 'error' in query_params:
65
  error = query_params.get('error')
66
  error_description = query_params.get('error_description', 'No description provided')
67
  st.error(f"Authentication Error: {error}")
68
- st.error(f"Error Description: {error_description}")
69
  st.stop()
70
 
71
  if 'code' in query_params:
72
- code = query_params.get('code')[0] # MS Graph returns the code as a list
73
  st.write('πŸ”‘ Authorization Code Obtained:', code[:10] + '...')
74
 
75
  try:
76
- # Retrieve code_verifier from session state
77
  code_verifier = st.session_state.get('code_verifier')
78
  if not code_verifier:
79
  st.error("Code verifier not found in session state.")
80
  st.stop()
81
 
82
- # Acquire the access token
83
  access_token = get_access_token(code, code_verifier)
84
  st.session_state['access_token'] = access_token
85
  st.success("Access token acquired successfully!")
86
-
87
- # Clear the query parameters from the URL
88
  st.experimental_set_query_params()
89
- st.experimental_rerun()
90
  except Exception as e:
91
  st.error(f"Error acquiring access token: {str(e)}")
92
  st.stop()
93
  else:
94
  st.warning("No authorization code found in the query parameters.")
95
- except Exception as e:
96
- st.error(f"Error processing query parameters: {str(e)}")
97
- st.stop()
98
 
99
- # Main application function
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100
  def main():
101
  st.title("πŸ¦„ MS Graph API with AI & Cloud Integration with M365")
102
 
 
 
 
 
103
  if 'access_token' not in st.session_state:
104
  if 'code_verifier' not in st.session_state:
105
- # Generate PKCE codes and store code_verifier in session
106
  code_verifier, code_challenge = generate_pkce_codes()
107
  st.session_state['code_verifier'] = code_verifier
108
  else:
109
  code_verifier = st.session_state['code_verifier']
110
  code_challenge = base64.urlsafe_b64encode(hashlib.sha256(code_verifier.encode()).digest()).decode().rstrip('=')
111
-
112
- # Get MSAL app and construct the authorization URL
113
  client_instance = get_msal_app()
114
  auth_url = client_instance.get_authorization_request_url(
115
  scopes=SCOPES,
@@ -118,23 +180,372 @@ def main():
118
  code_challenge_method="S256"
119
  )
120
  st.write('πŸ‘‹ Please [click here]({}) to log in and authorize the app.'.format(auth_url))
121
- st.stop()
122
 
123
- # Process query parameters to acquire token
124
- process_query_params()
125
 
126
- # If access token is present, greet the user
127
- if 'access_token' in st.session_state:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
128
  access_token = st.session_state['access_token']
129
  headers = {'Authorization': 'Bearer ' + access_token}
130
-
 
131
  response = requests.get('https://graph.microsoft.com/v1.0/me', headers=headers)
132
  if response.status_code == 200:
133
  user_info = response.json()
134
- st.write(f"πŸ‘‹ Hello, {user_info['displayName']}!")
135
  else:
136
- st.error("Failed to fetch user info.")
137
  st.write(response.text)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
138
 
139
  # πŸš€ Run the main function
140
  if __name__ == "__main__":
 
2
  import streamlit as st
3
  import requests
4
  import msal
5
+ import urllib.parse
6
  import base64
7
  import hashlib
8
  import secrets
 
11
  APPLICATION_ID_KEY = os.getenv('APPLICATION_ID_KEY')
12
  CLIENT_SECRET_KEY = os.getenv('CLIENT_SECRET_KEY')
13
  AUTHORITY_URL = 'https://login.microsoftonline.com/common' # Use 'common' for multi-tenant apps
14
+ #REDIRECT_URI = 'http://localhost:8501' # πŸ‘ˆ Make sure this matches your app's redirect URI
15
+ REDIRECT_URI = 'https://huggingface.co/spaces/awacke1/MSGraphAPI' # πŸ‘ˆ Make sure this matches your app's redirect URI
16
+
17
 
18
  # 🎯 Define the scopes your app will need
19
+ #SCOPES = ['User.Read', 'Calendars.ReadWrite', 'Mail.ReadWrite', 'Notes.ReadWrite.All', 'Files.ReadWrite.All']
20
  SCOPES = ['User.Read']
21
 
22
  # New function to generate PKCE code verifier and challenge
 
25
  code_challenge = base64.urlsafe_b64encode(hashlib.sha256(code_verifier.encode()).digest()).decode().rstrip('=')
26
  return code_verifier, code_challenge
27
 
28
+ def get_msal_app(code_challenge=None):
 
29
  return msal.PublicClientApplication(
30
  client_id=APPLICATION_ID_KEY,
31
  authority=AUTHORITY_URL
32
  )
33
+
34
+ # πŸ› οΈ Initialize the MSAL client
35
+ def get_msal_app_old():
36
+ return msal.ConfidentialClientApplication(
37
+ client_id=APPLICATION_ID_KEY,
38
+ client_credential=CLIENT_SECRET_KEY,
39
+ authority=AUTHORITY_URL
40
+ )
41
 
42
  # πŸ” Acquire access token using authorization code
43
+ def get_access_token(code):
44
+ client_instance = get_msal_app()
45
+
46
+ # Debug: Print MSAL app configuration (be careful not to expose secrets)
47
+ st.write("Debug: MSAL App Configuration:")
48
+ st.write(f"Client ID: {APPLICATION_ID_KEY[:5]}...") # Show first 5 chars
49
+ st.write(f"Authority: {AUTHORITY_URL}")
50
+ st.write(f"Redirect URI: {REDIRECT_URI}")
51
+
52
+ try:
53
+ result = client_instance.acquire_token_by_authorization_code(
54
+ code=code,
55
+ scopes=SCOPES,
56
+ redirect_uri=REDIRECT_URI
57
+ )
58
+
59
+ if 'access_token' in result:
60
+ return result['access_token']
61
+ else:
62
+ error_description = result.get('error_description', 'No error description provided')
63
+ raise Exception(f"Error acquiring token: {error_description}")
64
+ except Exception as e:
65
+ st.error(f"Exception in get_access_token: {str(e)}")
66
+ raise
67
+ #st.stop()
68
+
69
+
70
+ def get_access_token(code, code_verifier):
71
  client_instance = get_msal_app()
72
 
73
  st.write("Debug: MSAL App Configuration:")
 
76
  st.write(f"Redirect URI: {REDIRECT_URI}")
77
 
78
  try:
 
79
  result = client_instance.acquire_token_by_authorization_code(
80
  code=code,
81
  scopes=SCOPES,
82
  redirect_uri=REDIRECT_URI,
83
+ code_verifier=code_verifier # Include the code verifier here
84
  )
85
 
86
  if 'access_token' in result:
 
91
  except Exception as e:
92
  st.error(f"Exception in get_access_token: {str(e)}")
93
  raise
94
+
 
95
  def process_query_params():
96
+ # βš™οΈq= Run ArXiv search from query parameters
97
  try:
98
+ query_params = st.query_params
99
  st.write("Debug: All query parameters:", query_params)
100
 
101
  if 'error' in query_params:
102
  error = query_params.get('error')
103
  error_description = query_params.get('error_description', 'No description provided')
104
  st.error(f"Authentication Error: {error}")
105
+ st.error(f"Error Description: {urllib.parse.unquote(error_description)}")
106
  st.stop()
107
 
108
  if 'code' in query_params:
109
+ code = query_params.get('code')
110
  st.write('πŸ”‘ Authorization Code Obtained:', code[:10] + '...')
111
 
112
  try:
 
113
  code_verifier = st.session_state.get('code_verifier')
114
  if not code_verifier:
115
  st.error("Code verifier not found in session state.")
116
  st.stop()
117
 
 
118
  access_token = get_access_token(code, code_verifier)
119
  st.session_state['access_token'] = access_token
120
  st.success("Access token acquired successfully!")
121
+ # Clear the code from the URL
 
122
  st.experimental_set_query_params()
123
+ st.rerun()
124
  except Exception as e:
125
  st.error(f"Error acquiring access token: {str(e)}")
126
  st.stop()
127
  else:
128
  st.warning("No authorization code found in the query parameters.")
 
 
 
129
 
130
+
131
+ query = (query_params.get('q') or query_params.get('query') or [''])
132
+ if len(query) > 1:
133
+ #result = search_arxiv(query)
134
+ #result2 = search_glossary(result)
135
+
136
+ filesearch = PromptPrefix + query
137
+ st.markdown(filesearch)
138
+ process_text(filesearch)
139
+ except:
140
+ st.markdown(' ')
141
+
142
+ if 'action' in st.query_params:
143
+ action = st.query_params()['action'][0] # Get the first (or only) 'action' parameter
144
+ if action == 'show_message':
145
+ st.success("Showing a message because 'action=show_message' was found in the URL.")
146
+ elif action == 'clear':
147
+ clear_query_params()
148
+ #st.rerun()
149
+
150
+ if 'query' in st.query_params:
151
+ query = st.query_params['query'][0] # Get the query parameter
152
+ # Display content or image based on the query
153
+ display_content_or_image(query)
154
+
155
+
156
+
157
+
158
+ # πŸƒβ€β™‚οΈ Main application function
159
  def main():
160
  st.title("πŸ¦„ MS Graph API with AI & Cloud Integration with M365")
161
 
162
+
163
+
164
+ process_query_params()
165
+
166
  if 'access_token' not in st.session_state:
167
  if 'code_verifier' not in st.session_state:
168
+ # Generate PKCE codes
169
  code_verifier, code_challenge = generate_pkce_codes()
170
  st.session_state['code_verifier'] = code_verifier
171
  else:
172
  code_verifier = st.session_state['code_verifier']
173
  code_challenge = base64.urlsafe_b64encode(hashlib.sha256(code_verifier.encode()).digest()).decode().rstrip('=')
174
+
 
175
  client_instance = get_msal_app()
176
  auth_url = client_instance.get_authorization_request_url(
177
  scopes=SCOPES,
 
180
  code_challenge_method="S256"
181
  )
182
  st.write('πŸ‘‹ Please [click here]({}) to log in and authorize the app.'.format(auth_url))
183
+ #st.stop()
184
 
 
 
185
 
186
+ # πŸš€ Sidebar navigation
187
+ st.sidebar.title("Navigation")
188
+ menu = st.sidebar.radio("Go to", [
189
+ "1️⃣ Dashboard",
190
+ "🏠 Landing Page",
191
+ "πŸ“… Upcoming Events",
192
+ "πŸ“† Schedule",
193
+ "πŸ“ Agenda",
194
+ "πŸ” Event Details",
195
+ "βž• Add Event",
196
+ "πŸ”Ž Filter By"
197
+ ])
198
+
199
+ # πŸ“ M365 Products with MS Graph Integration & AI Features
200
+ st.sidebar.title("πŸ“ M365 Products")
201
+ st.sidebar.write("Toggle integration for each product:")
202
+
203
+ # πŸŽ›οΈ Product Integration Toggles
204
+ products = {
205
+ "πŸ“§ Outlook": {
206
+ "ai_capabilities": "Copilot for enhanced email writing, calendar management, and scheduling.",
207
+ "graph_api": "Access to mail, calendar, contacts, and events."
208
+ },
209
+ "πŸ“’ OneNote": {
210
+ "ai_capabilities": "Content suggestion, note organization, and OCR for extracting text from images.",
211
+ "graph_api": "Manage notebooks, sections, and pages."
212
+ },
213
+ "πŸ“Š Excel": {
214
+ "ai_capabilities": "Copilot for advanced data analysis, data insights, and formula generation.",
215
+ "graph_api": "Create and manage worksheets, tables, charts, and workbooks."
216
+ },
217
+ "πŸ“„ Word": {
218
+ "ai_capabilities": "Copilot for document drafting, summarization, and grammar improvements.",
219
+ "graph_api": "Document content access, templates, and file management."
220
+ },
221
+ "πŸ—ƒοΈ SharePoint": {
222
+ "ai_capabilities": "Intelligent search, document tagging, and metadata extraction.",
223
+ "graph_api": "Access to sites, lists, files, and document libraries."
224
+ },
225
+ "πŸ“… Teams": {
226
+ "ai_capabilities": "Copilot for meeting summaries, transcription, and chat suggestions.",
227
+ "graph_api": "Manage chats, teams, channels, and meetings."
228
+ },
229
+ "πŸ’¬ Viva": {
230
+ "ai_capabilities": "Personalized learning insights, well-being insights, and productivity suggestions.",
231
+ "graph_api": "Access to user analytics and learning modules."
232
+ },
233
+ "πŸš€ Power Platform": {
234
+ "ai_capabilities": "Automation with AI Builder, data insights, and custom AI models.",
235
+ "graph_api": "Automation workflows, app creation, and data visualization."
236
+ },
237
+ "🧠 Copilot": {
238
+ "ai_capabilities": "Embedded across Word, Excel, Outlook, Teams, and more for AI-driven productivity.",
239
+ "graph_api": "Underpins Copilot's access to data and integrations."
240
+ },
241
+ "πŸ—‚οΈ OneDrive": {
242
+ "ai_capabilities": "Intelligent file organization and search.",
243
+ "graph_api": "File and folder access, sharing, and metadata."
244
+ },
245
+ "πŸ’‘ PowerPoint": {
246
+ "ai_capabilities": "Design suggestions, presentation summarization, and speaker coaching.",
247
+ "graph_api": "Presentation creation, slide management, and templates."
248
+ },
249
+ "πŸ“š Microsoft Bookings": {
250
+ "ai_capabilities": "Automated scheduling and reminders.",
251
+ "graph_api": "Booking calendars, services, and appointment details."
252
+ },
253
+ "πŸ““ Loop": {
254
+ "ai_capabilities": "Real-time collaboration and content suggestions.",
255
+ "graph_api": "Access to shared workspaces and collaborative pages."
256
+ },
257
+ "πŸ—£οΈ Translator": {
258
+ "ai_capabilities": "Real-time language translation and text-to-speech.",
259
+ "graph_api": "Integrated into communication and translation services."
260
+ },
261
+ "πŸ“‹ To Do & Planner": {
262
+ "ai_capabilities": "Task prioritization and smart reminders.",
263
+ "graph_api": "Task creation, management, and synchronization."
264
+ },
265
+ "πŸ”— Azure OpenAI Service": {
266
+ "ai_capabilities": "Access to GPT models for custom AI implementations.",
267
+ "graph_api": "Used indirectly for building custom AI models into workflows."
268
+ }
269
+ }
270
+
271
+ # πŸ—³οΈ Create toggles for each product
272
+ selected_products = {}
273
+ for product, info in products.items():
274
+ selected = st.sidebar.checkbox(product)
275
+ if selected:
276
+ st.sidebar.write(f"**AI Capabilities:** {info['ai_capabilities']}")
277
+ st.sidebar.write(f"**Graph API:** {info['graph_api']}")
278
+ selected_products[product] = True
279
+
280
+ # πŸ”‘ Authentication
281
+ if 'access_token' not in st.session_state:
282
+ # πŸ•΅οΈβ€β™‚οΈ Check for authorization code in query parameters
283
+ query_params = st.query_params
284
+ query = (query_params.get('code'))
285
+ #if len(query) > 1:
286
+
287
+ #st.write('Parsing query ' + query_params )
288
+ if 'code' in query_params:
289
+ #code = query_params['code'][0]
290
+ code = query_params.get('code')
291
+
292
+ st.write('πŸ”‘Access Code Obtained from MS Graph RedirectπŸ”‘!:' + code)
293
+
294
+ st.write('πŸ”‘ Acquiring access token from redirect URL for code parameter.')
295
+ access_token = get_access_token(code)
296
+
297
+ st.session_state['access_token'] = access_token # πŸ”‘ Save it for later
298
+
299
+ st.rerun() # Reload the app to clear the code from URL
300
+ else:
301
+ # πŸ“’ Prompt user to log in
302
+ client_instance = get_msal_app()
303
+ authorization_url = client_instance.get_authorization_request_url(
304
+ scopes=SCOPES,
305
+ redirect_uri=REDIRECT_URI
306
+ )
307
+ st.write('πŸ‘‹ Please [click here]({}) to log in and authorize the app.'.format(authorization_url))
308
+ st.stop()
309
+
310
+
311
+ else:
312
+ # πŸ₯³ User is authenticated, proceed with the app
313
  access_token = st.session_state['access_token']
314
  headers = {'Authorization': 'Bearer ' + access_token}
315
+
316
+ # πŸ€— Greet the user
317
  response = requests.get('https://graph.microsoft.com/v1.0/me', headers=headers)
318
  if response.status_code == 200:
319
  user_info = response.json()
320
+ st.sidebar.write(f"πŸ‘‹ Hello, {user_info['displayName']}!")
321
  else:
322
+ st.error('Failed to fetch user info.')
323
  st.write(response.text)
324
+
325
+ # πŸŽ›οΈ Handle menu options
326
+ if menu == "1️⃣ Dashboard with Widgets":
327
+ st.header("1️⃣ Dashboard with Widgets")
328
+ st.write("Widgets will be displayed here. πŸŽ›οΈ")
329
+ # Add your widgets here
330
+
331
+ elif menu == "🏠 Landing Page":
332
+ st.header("🏠 Landing Page")
333
+ st.write("Welcome to the app! πŸ₯³")
334
+ # Add landing page content here
335
+
336
+ elif menu == "πŸ“… Upcoming Events":
337
+ st.header("πŸ“… Upcoming Events")
338
+ events = get_upcoming_events(access_token)
339
+ for event in events:
340
+ st.write(f"πŸ“† {event['subject']} on {event['start']['dateTime']}")
341
+ # Display upcoming events
342
+
343
+ elif menu == "πŸ“† Schedule":
344
+ st.header("πŸ“† Schedule")
345
+ schedule = get_schedule(access_token)
346
+ st.write(schedule)
347
+ # Display schedule
348
+
349
+ elif menu == "πŸ“ Agenda":
350
+ st.header("πŸ“ Agenda")
351
+ st.write("Your agenda for today. πŸ“‹")
352
+ # Display agenda
353
+
354
+ elif menu == "πŸ” Event Details":
355
+ st.header("πŸ” Event Details")
356
+ event_id = st.text_input("Enter Event ID")
357
+ if event_id:
358
+ event_details = get_event_details(access_token, event_id)
359
+ st.write(event_details)
360
+ # Display event details based on ID
361
+
362
+ elif menu == "βž• Add Event":
363
+ st.header("βž• Add Event")
364
+ event_subject = st.text_input("Event Subject")
365
+ event_start = st.date_input("Event Start Date")
366
+ event_start_time = st.time_input("Event Start Time")
367
+ event_end = st.date_input("Event End Date")
368
+ event_end_time = st.time_input("Event End Time")
369
+ if st.button("Add Event"):
370
+ event_details = {
371
+ "subject": event_subject,
372
+ "start": {
373
+ "dateTime": f"{event_start}T{event_start_time}",
374
+ "timeZone": "UTC"
375
+ },
376
+ "end": {
377
+ "dateTime": f"{event_end}T{event_end_time}",
378
+ "timeZone": "UTC"
379
+ }
380
+ }
381
+ add_event(access_token, event_details)
382
+ st.success("Event added successfully! πŸŽ‰")
383
+ # Form to add new event
384
+
385
+ elif menu == "πŸ”Ž Filter By":
386
+ st.header("πŸ”Ž Filter Events")
387
+ filter_criteria = st.text_input("Enter filter criteria")
388
+ if filter_criteria:
389
+ filtered_events = filter_events(access_token, filter_criteria)
390
+ for event in filtered_events:
391
+ st.write(f"πŸ“… {event['subject']} on {event['start']['dateTime']}")
392
+ # Filter events based on criteria
393
+
394
+ # 🧩 Handle selected products
395
+ if selected_products:
396
+ st.header("🧩 M365 Product Integrations")
397
+ for product in selected_products:
398
+ st.subheader(f"{product}")
399
+ # Call the function corresponding to the product
400
+ handle_product_integration(access_token, product)
401
+ else:
402
+ st.write("No products selected.")
403
+ pass
404
+
405
+ # 🧩 Function to handle product integration
406
+ def handle_product_integration(access_token, product):
407
+ if product == "πŸ“§ Outlook":
408
+ st.write("Accessing Outlook data...")
409
+ # Implement Outlook integration
410
+ inbox_messages = get_outlook_messages(access_token)
411
+ st.write("Inbox Messages:")
412
+ for msg in inbox_messages:
413
+ st.write(f"βœ‰οΈ {msg['subject']}")
414
+ elif product == "πŸ“’ OneNote":
415
+ st.write("Accessing OneNote data...")
416
+ # Implement OneNote integration
417
+ notebooks = get_onenote_notebooks(access_token)
418
+ st.write("Notebooks:")
419
+ for notebook in notebooks:
420
+ st.write(f"πŸ“” {notebook['displayName']}")
421
+ elif product == "πŸ“Š Excel":
422
+ st.write("Accessing Excel data...")
423
+ # Implement Excel integration
424
+ st.write("Excel integration is a placeholder.")
425
+ elif product == "πŸ“„ Word":
426
+ st.write("Accessing Word documents...")
427
+ # Implement Word integration
428
+ st.write("Word integration is a placeholder.")
429
+ elif product == "πŸ—ƒοΈ SharePoint":
430
+ st.write("Accessing SharePoint sites...")
431
+ # Implement SharePoint integration
432
+ sites = get_sharepoint_sites(access_token)
433
+ st.write("Sites:")
434
+ for site in sites:
435
+ st.write(f"🌐 {site['displayName']}")
436
+ elif product == "πŸ“… Teams":
437
+ st.write("Accessing Teams data...")
438
+ # Implement Teams integration
439
+ teams = get_user_teams(access_token)
440
+ st.write("Teams:")
441
+ for team in teams:
442
+ st.write(f"πŸ‘₯ {team['displayName']}")
443
+ # Add additional product integrations as needed
444
+ else:
445
+ st.write(f"No integration implemented for {product}.")
446
+
447
+ # πŸ“¨ Function to get Outlook messages
448
+ def get_outlook_messages(access_token):
449
+ headers = {'Authorization': 'Bearer ' + access_token}
450
+ response = requests.get('https://graph.microsoft.com/v1.0/me/messages?$top=5', headers=headers)
451
+ if response.status_code == 200:
452
+ messages = response.json().get('value', [])
453
+ return messages
454
+ else:
455
+ st.error('Failed to fetch messages.')
456
+ st.write(response.text)
457
+ return []
458
+
459
+ # πŸ“” Function to get OneNote notebooks
460
+ def get_onenote_notebooks(access_token):
461
+ headers = {'Authorization': 'Bearer ' + access_token}
462
+ response = requests.get('https://graph.microsoft.com/v1.0/me/onenote/notebooks', headers=headers)
463
+ if response.status_code == 200:
464
+ notebooks = response.json().get('value', [])
465
+ return notebooks
466
+ else:
467
+ st.error('Failed to fetch notebooks.')
468
+ st.write(response.text)
469
+ return []
470
+
471
+ # 🌐 Function to get SharePoint sites
472
+ def get_sharepoint_sites(access_token):
473
+ headers = {'Authorization': 'Bearer ' + access_token}
474
+ response = requests.get('https://graph.microsoft.com/v1.0/sites?search=*', headers=headers)
475
+ if response.status_code == 200:
476
+ sites = response.json().get('value', [])
477
+ return sites
478
+ else:
479
+ st.error('Failed to fetch sites.')
480
+ st.write(response.text)
481
+ return []
482
+
483
+ # πŸ‘₯ Function to get user's Teams
484
+ def get_user_teams(access_token):
485
+ headers = {'Authorization': 'Bearer ' + access_token}
486
+ response = requests.get('https://graph.microsoft.com/v1.0/me/joinedTeams', headers=headers)
487
+ if response.status_code == 200:
488
+ teams = response.json().get('value', [])
489
+ return teams
490
+ else:
491
+ st.error('Failed to fetch teams.')
492
+ st.write(response.text)
493
+ return []
494
+
495
+ # πŸ“… Function to get upcoming events
496
+ def get_upcoming_events(access_token):
497
+ headers = {'Authorization': 'Bearer ' + access_token}
498
+ response = requests.get('https://graph.microsoft.com/v1.0/me/events?$orderby=start/dateTime&$top=10', headers=headers)
499
+ if response.status_code == 200:
500
+ events = response.json().get('value', [])
501
+ return events
502
+ else:
503
+ st.error('Failed to fetch upcoming events.')
504
+ st.write(response.text)
505
+ return []
506
+
507
+ # πŸ“† Function to get schedule (Placeholder)
508
+ def get_schedule(access_token):
509
+ # Implement API call to get schedule
510
+ return "πŸ“† Your schedule goes here."
511
+
512
+ # βž• Function to add a new event
513
+ def add_event(access_token, event_details):
514
+ headers = {
515
+ 'Authorization': 'Bearer ' + access_token,
516
+ 'Content-Type': 'application/json'
517
+ }
518
+ response = requests.post('https://graph.microsoft.com/v1.0/me/events', headers=headers, json=event_details)
519
+ if response.status_code == 201:
520
+ st.success('Event created successfully! πŸŽ‰')
521
+ else:
522
+ st.error('Failed to create event.')
523
+ st.write(response.text)
524
+
525
+ # πŸ” Function to get event details
526
+ def get_event_details(access_token, event_id):
527
+ headers = {'Authorization': 'Bearer ' + access_token}
528
+ response = requests.get(f'https://graph.microsoft.com/v1.0/me/events/{event_id}', headers=headers)
529
+ if response.status_code == 200:
530
+ event = response.json()
531
+ return event
532
+ else:
533
+ st.error('Failed to fetch event details.')
534
+ st.write(response.text)
535
+ return {}
536
+
537
+ # πŸ”Ž Function to filter events
538
+ def filter_events(access_token, filter_criteria):
539
+ headers = {'Authorization': 'Bearer ' + access_token}
540
+ # Implement filtering logic based on criteria
541
+ response = requests.get(f"https://graph.microsoft.com/v1.0/me/events?$filter=startswith(subject,'{filter_criteria}')", headers=headers)
542
+ if response.status_code == 200:
543
+ events = response.json().get('value', [])
544
+ return events
545
+ else:
546
+ st.error('Failed to filter events.')
547
+ st.write(response.text)
548
+ return []
549
 
550
  # πŸš€ Run the main function
551
  if __name__ == "__main__":