Spaces:
Sleeping
Success at Last!
I have finally completed a working full Azure and Microsoft MS Graph API implementation which can use all the interesting MS AI features in M365 products to manage CRUD patterns for the graph features across products.
This app shows initial implementation of security, authentication, scopes, and access to Outlook, Calendar, Tasks, Onedrive and other apps for CRUD pattern as AI agent service skills to integrate with your AI workflow.
Below are initial screens showing integration:
URL: https://huggingface.co/spaces/awacke1/MSGraphAPI
Discussion: https://huggingface.co/spaces/awacke1/MSGraphAPI/discussions/5
Best of AI on
@Azure
and
@Microsoft
on
@HuggingFace
:
https://huggingface.co/microsoft
https://microsoft.com/en-us/research/
Spare Parts
# π M365 Products with MS Graph Integration & AI Features
st.sidebar.title("π M365 Products")
st.sidebar.write("Toggle integration for each product:")
# ποΈ Product Integration Toggles
products = {
"π§ Outlook": {
"ai_capabilities": "Copilot for enhanced email writing, calendar management, and scheduling.",
"graph_api": "Access to mail, calendar, contacts, and events."
},
"π OneNote": {
"ai_capabilities": "Content suggestion, note organization, and OCR for extracting text from images.",
"graph_api": "Manage notebooks, sections, and pages."
},
"π Excel": {
"ai_capabilities": "Copilot for advanced data analysis, data insights, and formula generation.",
"graph_api": "Create and manage worksheets, tables, charts, and workbooks."
},
"π Word": {
"ai_capabilities": "Copilot for document drafting, summarization, and grammar improvements.",
"graph_api": "Document content access, templates, and file management."
},
"ποΈ SharePoint": {
"ai_capabilities": "Intelligent search, document tagging, and metadata extraction.",
"graph_api": "Access to sites, lists, files, and document libraries."
},
"π
Teams": {
"ai_capabilities": "Copilot for meeting summaries, transcription, and chat suggestions.",
"graph_api": "Manage chats, teams, channels, and meetings."
},
"π¬ Viva": {
"ai_capabilities": "Personalized learning insights, well-being insights, and productivity suggestions.",
"graph_api": "Access to user analytics and learning modules."
},
"π Power Platform": {
"ai_capabilities": "Automation with AI Builder, data insights, and custom AI models.",
"graph_api": "Automation workflows, app creation, and data visualization."
},
"π§ Copilot": {
"ai_capabilities": "Embedded across Word, Excel, Outlook, Teams, and more for AI-driven productivity.",
"graph_api": "Underpins Copilot's access to data and integrations."
},
"ποΈ OneDrive": {
"ai_capabilities": "Intelligent file organization and search.",
"graph_api": "File and folder access, sharing, and metadata."
},
"π‘ PowerPoint": {
"ai_capabilities": "Design suggestions, presentation summarization, and speaker coaching.",
"graph_api": "Presentation creation, slide management, and templates."
},
"π Microsoft Bookings": {
"ai_capabilities": "Automated scheduling and reminders.",
"graph_api": "Booking calendars, services, and appointment details."
},
"π Loop": {
"ai_capabilities": "Real-time collaboration and content suggestions.",
"graph_api": "Access to shared workspaces and collaborative pages."
},
"π£οΈ Translator": {
"ai_capabilities": "Real-time language translation and text-to-speech.",
"graph_api": "Integrated into communication and translation services."
},
"π To Do & Planner": {
"ai_capabilities": "Task prioritization and smart reminders.",
"graph_api": "Task creation, management, and synchronization."
},
"π Azure OpenAI Service": {
"ai_capabilities": "Access to GPT models for custom AI implementations.",
"graph_api": "Used indirectly for building custom AI models into workflows."
}
}
# π³οΈ Create toggles for each product
selected_products = {}
for product, info in products.items():
selected = st.sidebar.checkbox(product)
if selected:
st.sidebar.write(f"**AI Capabilities:** {info['ai_capabilities']}")
st.sidebar.write(f"**Graph API:** {info['graph_api']}")
selected_products[product] = True
# π Sidebar navigation
st.sidebar.title("Navigation")
menu = st.sidebar.radio("Go to", [
"1οΈβ£ Dashboard",
"π Landing Page",
"π
Upcoming Events",
"π Schedule",
"π Agenda",
"π Event Details",
"β Add Event",
"π Filter By"
])
# Define product to scope mapping
PRODUCT_SCOPES = {
"π§ Outlook": ['Mail.Read', 'Mail.Send', 'Calendars.ReadWrite'],
"π OneNote": ['Notes.Read', 'Notes.Create'],
"π Excel": ['Files.ReadWrite.All'],
"π Word": ['Files.ReadWrite.All'],
"ποΈ SharePoint": ['Sites.Read.All', 'Sites.ReadWrite.All'],
"π
Teams": ['Team.ReadBasic.All', 'Channel.ReadBasic.All'],
"π¬ Viva": ['Analytics.Read'],
"π Power Platform": ['Flow.Read.All'],
"π§ Copilot": ['Cognitive.Read'],
"ποΈ OneDrive": ['Files.ReadWrite.All'],
"π‘ PowerPoint": ['Files.ReadWrite.All'],
"π Microsoft Bookings": ['Bookings.Read.All', 'Bookings.ReadWrite.All'],
"π Loop": ['Files.ReadWrite.All'],
"π£οΈ Translator": ['Translation.Read'],
"π To Do & Planner": ['Tasks.ReadWrite'],
"π Azure OpenAI Service": ['AzureAIServices.ReadWrite.All']
}
import os
import streamlit as st
import requests
import msal
from datetime import datetime, timedelta
import calendar
# Configuration
APPLICATION_ID_KEY = os.getenv('APPLICATION_ID_KEY')
CLIENT_SECRET_KEY = os.getenv('CLIENT_SECRET_KEY')
AUTHORITY_URL = 'https://login.microsoftonline.com/common'
REDIRECT_URI = 'https://huggingface.co/spaces/awacke1/MSGraphAPI'
# Define product to scope mapping and links
PRODUCT_SCOPES = {
"π§ Outlook": {'scopes': ['Mail.Read', 'Mail.Send'], 'link': 'https://outlook.office.com/mail/'},
"π
Calendar": {'scopes': ['Calendars.ReadWrite'], 'link': 'https://outlook.office.com/calendar/'},
"π Tasks": {'scopes': ['Tasks.ReadWrite'], 'link': 'https://to-do.office.com/tasks/'},
"ποΈ OneDrive": {'scopes': ['Files.ReadWrite.All'], 'link': 'https://onedrive.live.com/'},
# ... (other products)
}
BASE_SCOPES = ['User.Read']
def get_msal_app():
return msal.ConfidentialClientApplication(
client_id=APPLICATION_ID_KEY,
client_credential=CLIENT_SECRET_KEY,
authority=AUTHORITY_URL
)
def get_access_token(code):
client_instance = get_msal_app()
try:
result = client_instance.acquire_token_by_authorization_code(
code=code,
scopes=st.session_state.get('request_scopes', BASE_SCOPES),
redirect_uri=REDIRECT_URI
)
if 'access_token' in result:
return result['access_token']
else:
raise Exception(f"Error acquiring token: {result.get('error_description')}")
except Exception as e:
st.error(f"Exception in get_access_token: {str(e)}")
raise
def make_api_call(access_token, endpoint, method='GET', data=None):
headers = {'Authorization': f'Bearer {access_token}', 'Content-Type': 'application/json'}
url = f'https://graph.microsoft.com/v1.0/{endpoint}'
if method == 'GET':
response = requests.get(url, headers=headers)
elif method == 'POST':
response = requests.post(url, headers=headers, json=data)
else:
raise ValueError(f"Unsupported method: {method}")
if response.status_code in [200, 201]:
return response.json()
else:
st.error(f"API call failed: {response.status_code} - {response.text}")
return None
def handle_outlook_integration(access_token):
st.subheader("π§ Outlook Integration")
st.markdown(f"[Open Outlook]({PRODUCT_SCOPES['π§ Outlook']['link']})")
emails = make_api_call(access_token, 'me/messages?$top=10&$orderby=receivedDateTime desc')
if emails and 'value' in emails:
for email in emails['value']:
with st.expander(f"From: {email['from']['emailAddress']['name']} - Subject: {email['subject']}"):
st.write(f"Received: {email['receivedDateTime']}")
st.write(f"Body: {email['bodyPreview']}")
else:
st.write("No emails found or unable to fetch emails.")
def handle_calendar_integration(access_token):
st.subheader("π
Calendar Integration")
st.markdown(f"[Open Calendar]({PRODUCT_SCOPES['π
Calendar']['link']})")
# Get the current month's start and end dates
now = datetime.now()
start_of_month = now.replace(day=1, hour=0, minute=0, second=0, microsecond=0)
end_of_month = start_of_month.replace(month=start_of_month.month % 12 + 1, day=1) - timedelta(days=1)
events = make_api_call(access_token, f"me/calendarView?startDateTime={start_of_month.isoformat()}&endDateTime={end_of_month.isoformat()}&$orderby=start/dateTime")
if events and 'value' in events:
# Create a calendar view
cal = calendar.monthcalendar(now.year, now.month)
st.write(f"Calendar for {now.strftime('%B %Y')}")
# Create a placeholder for each day
day_placeholders = {}
for week in cal:
cols = st.columns(7)
for i, day in enumerate(week):
if day != 0:
day_placeholders[day] = cols[i].empty()
day_placeholders[day].write(f"**{day}**")
# Populate the calendar with events
for event in events['value']:
start_date = datetime.fromisoformat(event['start']['dateTime'][:-1]) # Remove 'Z' from the end
day = start_date.day
if day in day_placeholders:
day_placeholders[day].write(f"{start_date.strftime('%H:%M')} - {event['subject']}")
else:
st.write("No events found or unable to fetch events.")
st.write("Add a new event:")
event_subject = st.text_input("Event Subject")
event_date = st.date_input("Event Date")
event_time = st.time_input("Event Time")
if st.button("Add Event"):
event_start = datetime.combine(event_date, event_time)
event_end = event_start + timedelta(hours=1)
new_event = {
"subject": event_subject,
"start": {
"dateTime": event_start.isoformat(),
"timeZone": "UTC"
},
"end": {
"dateTime": event_end.isoformat(),
"timeZone": "UTC"
}
}
result = make_api_call(access_token, 'me/events', method='POST', data=new_event)
if result:
st.success("Event added successfully!")
else:
st.error("Failed to add event.")
def handle_tasks_integration(access_token):
st.subheader("π Tasks Integration")
st.markdown(f"[Open Tasks]({PRODUCT_SCOPES['π Tasks']['link']})")
tasks = make_api_call(access_token, 'me/todo/lists')
if tasks and 'value' in tasks:
default_list = next((list for list in tasks['value'] if list['wellknownListName'] == 'defaultList'), None)
if default_list:
tasks = make_api_call(access_token, f"me/todo/lists/{default_list['id']}/tasks")
if tasks and 'value' in tasks:
for task in tasks['value']:
st.write(f"Task: {task['title']}")
st.write(f"Status: {'Completed' if task['status'] == 'completed' else 'Not Completed'}")
st.write("---")
else:
st.write("No tasks found or unable to fetch tasks.")
else:
st.write("Default task list not found.")
else:
st.write("Unable to fetch task lists.")
st.write("Add a new task:")
task_title = st.text_input("Task Title")
if st.button("Add Task"):
new_task = {
"title": task_title
}
result = make_api_call(access_token, f"me/todo/lists/{default_list['id']}/tasks", method='POST', data=new_task)
if result:
st.success("Task added successfully!")
else:
st.error("Failed to add task.")
def handle_onedrive_integration(access_token):
st.subheader("ποΈ OneDrive Integration")
st.markdown(f"[Open OneDrive]({PRODUCT_SCOPES['ποΈ OneDrive']['link']})")
files = make_api_call(access_token, 'me/drive/root/children')
if files and 'value' in files:
for file in files['value']:
st.write(f"Name: {file['name']}")
st.write(f"Type: {'Folder' if 'folder' in file else 'File'}")
st.write(f"Last Modified: {file['lastModifiedDateTime']}")
st.write("---")
else:
st.write("No files found or unable to fetch files.")
def main():
st.title("π¦ MS Graph API with AI & Cloud Integration for M365")
st.sidebar.title("π M365 Products")
st.sidebar.write("Select products to integrate:")
selected_products = {}
for product in PRODUCT_SCOPES.keys():
selected = st.sidebar.checkbox(product)
if selected:
selected_products[product] = True
request_scopes = BASE_SCOPES.copy()
for product in selected_products:
request_scopes.extend(PRODUCT_SCOPES[product]['scopes'])
request_scopes = list(set(request_scopes))
st.session_state['request_scopes'] = request_scopes
if 'access_token' not in st.session_state:
client_instance = get_msal_app()
auth_url = client_instance.get_authorization_request_url(
scopes=request_scopes,
redirect_uri=REDIRECT_URI
)
st.write('π Please [click here]({}) to log in and authorize the app.'.format(auth_url))
query_params = st.query_params
if 'code' in query_params:
code = query_params.get('code')
st.write('π Authorization Code Obtained:', code[:10] + '...')
try:
access_token = get_access_token(code)
st.session_state['access_token'] = access_token
st.success("Access token acquired successfully!")
st.rerun()
except Exception as e:
st.error(f"Error acquiring access token: {str(e)}")
st.stop()
else:
access_token = st.session_state['access_token']
user_info = make_api_call(access_token, 'me')
if user_info:
st.sidebar.write(f"π Hello, {user_info.get('displayName', 'User')}!")
if selected_products:
for product in selected_products:
if product == "π§ Outlook":
handle_outlook_integration(access_token)
elif product == "π
Calendar":
handle_calendar_integration(access_token)
elif product == "π Tasks":
handle_tasks_integration(access_token)
elif product == "ποΈ OneDrive":
handle_onedrive_integration(access_token)
# Add more product integrations here
else:
st.write("No products selected. Please select products from the sidebar.")
if __name__ == "__main__":
main()
My goal is to find a business solution that not only helps streamline project managementβalthough thatβs the primary aimβbut also makes overall business operations more cohesive. I want to avoid spending excessive time ensuring information flows smoothly between departments and instead ensure all specialists work together seamlessly. In short, Iβm looking for something that optimizes processes and eliminates unnecessary steps.
What about ERP? In my opinion, itβs an optimal solution for businesses of any size, whether itβs a small business or a startup. The key factor is the companyβs readiness to implement a new system. Currently, Iβm actively working with IFS Cloud, and my choice is partly influenced by a partnership with Novacura https://www.novacura.com/ifs-services-ams-2/ , which offers a full range of services aimed at optimizing and customizing IFS Cloud to fit business needs. Not only is the cloud system itself effective, but the availability of specialists to assist when needed adds a lot of value.