The Kladde produces offers as PDFs. So far they go to customers by mail (lesson 2.8.5), but in the office they are stored nowhere you could find them again. This lesson changes that: the Kladde files the PDF in a Microsoft 365 document library, creates a link that only people from its own tenant can open, and announces the offer in a Teams channel. Along the way you learn what Graph offers for files, how far a sharing link reaches, how to limit an application to one site, and why sending into a channel without a signed-in person calls for a decision of its own.

What you bring: the Kladde from K2 with the ports and the pattern from lesson 2.8.5 (IMailSender, DeliveryOutcome), the outbox from lesson 2.8.4, and the terms from lessons W4.1.2 and W4.2.1: delegated permission, application permission, consent. Adjust the project names to your Kladde.

On the status of this lesson. No text and no command of this lesson was run against a Microsoft 365 tenant: not run against a tenant. Requests, permission tables and responses come from the Microsoft Learn pages listed at the end under "Further reading". Where a page does not answer a question, the text says "open", and the exercises with a tenant say what you check there. Everything that needs a tenant runs only in a test tenant, never in a production tenant. Whether Microsoft offers you a developer tenant for Microsoft 365 and under what conditions, you clarify with Microsoft; the lesson says nothing about it.

Files in Graph: drive, driveItem and the way there

Graph presents OneDrive and the SharePoint document libraries the same way: a drive is a storage space, and every file and every folder in it is a driveItem. You reach a driveItem in two ways: by its ID (/drive/items/{item-id}) or by its path (/drive/root:/Folder/File). The path form is convenient but hangs on the names: if the file is renamed or moved, the path changes. The ID stays. The Kladde therefore writes with a path (that is how the file comes into being) and afterward remembers the ID that the response delivers.

The pages on uploading name five entry points for the same call:

http
PUT /drives/{drive-id}/items/{parent-id}:/{filename}:/content
PUT /groups/{group-id}/drive/items/{parent-id}:/{filename}:/content
PUT /me/drive/items/{parent-id}:/{filename}:/content
PUT /sites/{site-id}/drive/items/{parent-id}:/{filename}:/content
PUT /users/{user-id}/drive/items/{parent-id}:/{filename}:/content

me means the signed-in person. A background service of the Kladde has none; it takes one of the other forms, most precisely drives/{drive-id}, because the library's ID is in the configuration and does not change. You find the ID of a site's library in the test tenant in Graph Explorer (lesson W4.1.1), the ID of the site itself with GET /sites/{hostname}:/sites/{path}; the format of this ID (three parts, separated by commas) comes up again shortly under Sites.Selected.

Which permission the call requires

For each call, the pages name the permission with the least privilege and the higher ones. For the two ways of uploading that you are about to meet:

Call Delegated (work or school account) Application
Upload a file (PUT .../content) Files.ReadWrite Files.ReadWrite.All
Upload session (createUploadSession) Files.ReadWrite Sites.ReadWrite.All
Sharing link (createLink) Files.ReadWrite Files.ReadWrite.All

Two things stand out. First, every application permission in the table is one with .All: it applies to all files or all sites of the tenant, not to the one library the Kladde needs. The remedy is Sites.Selected, the section after next. Second, two pages carry a note: an application without a signed-in person does not replace the content of a file that is protected with a sensitivity label; for that, Microsoft requires a delegated permission. For new offer PDFs that does not matter, but for overwriting existing files in a library with labels it very much does.

The tables of the two upload pages do not name Sites.Selected. On the page that creates a permission on a driveItem (POST .../permissions), however, Sites.Selected appears among the higher permissions. Open: whether an upload succeeds with Sites.Selected alone, you decide in the test tenant (exercise 2), not from the table.