Editing Excel 365 by hand and reading with graph api latency - microsoft-graph-api

I have an excel on line documents that can be edited by users in the Excel 365 web application.
I have an application that read this excel file with the graph api.
I have successfully managed to read the data from the file but when a user change the excel file and Excel says it has been saved, if I read the file immediately with my application I have old data.
I have to wait for 30s to have the updated data. Is there anything I can do to avoid this latency.
Here is my call to get the data :
var range = await _graphClient.Drives[_driveId].Items[_itemId].Workbook.Worksheets[workseetName]
.Range(rangeAddress).UsedRange(true)
.Request()
.GetAsync();

I posted a similar question on the graph API github repo. They responded here:
https://github.com/microsoftgraph/msgraph-cli/issues/215#issuecomment-1379391739
They suggest using the etag property to determine whether the workbook has changed since that last access. https://learn.microsoft.com/en-us/graph/api/resources/driveitem?view=graph-rest-1.0
They also suggest using the Excel session. https://learn.microsoft.com/en-us/graph/api/resources/excel?view=graph-rest-1.0#sessions-and-persistence
However in my personal testing the session method didn't fix the delay in excel saving the data in the backend.
They also mentioned:
"I cannot guarantee that these will work. I don't think this API was designed with real-time co-authoring in mind."

Related

Programatically Retrieve all Office 365 Unified Audit Logs

I would like to programmatically retrieve and process all logs available from the Office 365 Unified Audit Logs for the purpose of forensic investigation. From the front end, these logs are available through the Office 365 Compliance Admin Center.
I have tried the following options to access these logs from a script, with no success:
Microsoft 365 Management API - This contains the correct data, but is of limited usefulness for forensic investigations due to the short 7 day retention period.
Microsoft Graph - This does not contain all the relevant data - you cannot access the Unified Audit Logs directly through Graph, and the usage reports do not cover all items contained in the Audit Logs (e.g. Exchange actions).
Search-UnifiedAuditLog on Exchange Online PowerShell - Microsoft themselves recommend not to use this programmatically, and I've experienced extremely unreliable results and unmanageable rate-limiting when trying to do so.
So is there something I'm missing here, or is there no way to programmatically retrieve all items from the Unified Audit Logs for the entire retention period? (generally 90 days).
As far as I know the only way to do this is to use the Management API on a regular basis and output the results to some solution for long term storage (Azure Log Analytics Workspace comes to mind, or SIEM like Splunk / Graylog). I.e. write a script that retrieves logs for the last week, and run it at least weekly.
I'll explain how to retrieve logs manually and also show a tool which already exists for this at the bottom of the post.
Manually:
1: Enable Audit logging on the tenant if not already enabled
2: Create an App registration in Azure AD and for getting single tenant audit logs choose "Accounts in this organizational directory only (xyz only - Single tenant)"
3: Create a 'secret key' from within the newly created App Registration. Store it somewhere safe as it's only shown once. From the overview page of the App Registration also store the "Tenant ID" and "Application (Client) ID". You will need all three.
4: From within the new App Registration go to "API permissions" and add 'Application type' permissions for: 'ActivityFeed.Read' and 'ActivityFeed.ReadDlp'.
5: For the following steps you will need to start calling the Office API's, for which you will need a bearer token in the header. To obtain this send the following POST request:
URL: https://login.microsoftonline.com/***tenant_ID***/oauth2/token
Headers: "{'Content-Type': 'application/x-www-form-urlencoded'}"
Data: "grant_type=client_credentials&client_id=Application_ID&client_secret=Secret_Key&resource=https://manage.office.com"
You will receive a JSON response which contains 'access_token'. For all the upcoming API calls, use the following header:
"{'Content-Type': 'application/x-www-form-urlencoded', 'Authorization': 'bearer access_token'}"
6: Subscribe to the audit log feeds you would like to retrieve. The following exist: 'Audit.General', 'Audit.AzureActiveDirectory', 'Audit.Exchange', 'Audit.SharePoint', 'DLP.All'. The POST for Exchange for example would look like: "https://manage.office.com/api/v1.0/tenant_ID/activity/feed/subscriptions/start?contentType=Audit.Exchange"
7: You are now ready to start retrieving actual logs. Individual logs live inside content blobs, which live inside pages, which live inside feeds (e.g. the Audit.Exchange feed). Therefore, for each feed you would like to retrieve logs from, you must collect all the content blobs (iterating through the pages of them) and then retrieve the actual content from that blob.
To retrieve a page of content blobs use the following URL (change bolded content to your situation): "https://manage.office.com/api/v1.0/tenant_ID/activity/feed/subscriptions/content?contentType=Audit.Exhange&startTime=2022-04-13T09:42:52&endTime=2022-04-14T08:42:52"
This will give you a JSON response with content blobs inside. In the response header check "NextPageUri"; if it contains a URL, call that URL for the next page of content.
Now that you have content blobs, use them to retrieve the actual logs. Each content blob is a JSON dict, which contains a "contentUri" field. Call that URL to retrieve a JSON response with the actual logs inside.
You can do this in most programming/scripting languages, but for larger amounts of logs you will want to retrieve logs in parallel, or it will take a long time.
With a tool
In case you want to use an existing tool, this one is free, works on Linux and Windows, and supports multiple outputs.

Upload Single file with create and modify dates

When uploading single file into one drive for business I can't find a way to add a create and modify date.
when I use resumeable upload for file more then 4 Mb it is working but not for single small files.
using the Microsoft graph .NET SDK
var client = await GetGraphClient(request);
var stream = new FileStream(request.LocalPath, FileMode.Open, FileAccess.Read, FileShare.Read);
client.Me.Drive.Root.ItemWithPath($"{ds.FolderPath}/{request.File.Name}").Content.Request().PutAsync<DriveItem>(stream);
how do I upload with this method a file with create and modify date??
There's currently no way to do this in a single request with OneDrive Business - you'll have to follow the put-to-content request with a metadata update that includes the timestamps.
In the future the goal is to align with OneDrive Personal and allow multipart requests that include both the metadata and the file content, but this is not yet available.

Google Speech API gRPC sync request processes first word(s) only

Google Speech API via gRPC recognizes first few words only. Tested using several short (<10s) audio files in several (wav, flac) formats.
I am trying to get Google's speech API to work with Delphi using gRPC. (Calling the Speech API from Delphi using JSON works OK, but does not support streaming)
As Google does not support Delphi as gRPC client, I use Grijjy's protocolbuffers for Serializing/Deserializing audio request/response, and Grijjy's scalable sockets for the http/2 request.
As I think the code is too large to share here, I created a MVCE. A zip file containing source code (Delphi 10.3), executable and audio file can be found here. The audio file contains the text "How old is the Brooklyn Bridge", which is flawlessly recognized when calling the Speech API via JSON.
To run the executable, only a Google API key is necessary. Necessary support file nghttp2.dll is included. After sending a request, a messagebox is displayed containing the deserialized response. I checked this is the complete Google response by checking response data size. The response only shows "how old", where I would have expected a full recognized sentence. No errors are returned, confidence factor is also returned.
To compile the source code, Grijjy's code as mentioned above must downloaded from Github and the folder(s) containing the downloaded code made available to the Delphi project.
Also, for Google to accept the request, in grijjy.http, line 1215 needs to modified from
FInternalHeaders.AddOrSet('host', FURI.Host);
to
FInternalHeaders.AddOrSet(':authority', FURI.Host);
(I failed to create a pull request for this earlier today, will try again later)
During my debugging efforts, I also checked response headers (200 OK), also tried other files (same issue).
For now, I do not know how to continue. Any ideas regarding how to get find the cause (or even better, a solution:-) of this issue would be highly appreciated.

MS Graph Excel API - call to /workbook/createSession causes workbook to be read-only in Excel client

A call made to createSession like below makes the workbook read-only in the Excel client:
https://graph.microsoft.com/v1.0/me/drive/items/<workbookid>/workbook/createSession
Is this expected behavior? It seems to last for about 15 minutes and then the workbook can be edited again in the Excel client.
Is there a way to explicitly end the session via code, eg. REST API, and release the read-only lock?
Thanks,
Jim
The closeSession action should release the session and allow editing.
However, I'm seeing an error with closeSession API. This may be temporary issue.. We'll follow-up once it it resolved.
POST https://graph.microsoft.com/v1.0/me/drive/root:/sample.xlsx:/workbook/closeSession

How can I download a OneDrive file with Office365 REST API into a Ruby variable?

I'm building a Ruby on Rails app, and I'd like to integrate some Office365 features.
For instance : I would like to download a file from OneDrive and then attach it to an Email in order to send it via Outlook rest API.
I found this get Item content OneDrive REST API but I dont understand how to use it.
I understand that I have to send a GET request (formated as explained in msdn.microsoft.com) with Rails, which will then provide me a "a pre-authenticated download URL" to download the file.
Then I will have to send a second GET request with this a pre-authenticated download URL to start the download, but I don't understand how to deal with the Response in order to save the file into a variable.
How can I retrieve the file into a variable of my Ruby on Rails App, so that I can attach it to an Email with an Outlook REST API to send it from my own Rail controller ?
Also this workflow is really not optimized in term of Bandwidth and Processing (3 REST API request + 1 download + 1 upload), it will work.
However if it exist a single REST API that direclty attach a OneDrive file to an email to send it, that would ease a lot my life, save energy, save money from Microsoft datacenter, and spare the planet ecology.
Any tutorial, examples, or more explanatory doc would be much appreciated.
--- EDIT ---
Adding link to the email is not wished as the email may have to be send to someone outside of Office365 users, and public link are a security issue for confidential documents.
Any help is welcome.
There isn't a single REST API call you can make currently to do what you want, although being able to easily attach a file from OneDrive to a new email message is a great scenario for Microsoft Graph API, it just isn't supported right now.
If you want to attach the file, you need to do as you mentioned, download the contents of the file, and then upload it again as an attachment to the message.
However, I'd recommend sending a link to the file instead, even though you mentioned you don't want to do that. OneDrive for Business now supports "company shareable links" which are scoped to just the user's organization instead of being available totally anonymously.
Something else to consider: The security concerns of sending an anonymous link aren't that different than sending an attached file. In fact, the anonymous link can be more secure, because access to the file can be monitored and revoked in the future (unlike the attachment, which will always be out there).

Resources