The Microsoft 365 Document Collaboration Partner Program (MDCPP) allows eligible communication and collaboration independent software vendors (ISVs) to integrate Microsoft 365 experiences into their communication and collaboration platforms. The program makes integration with the following experiences available.
- Office for the Web: Outside of a meeting experience, users can collaborate and edit Word, Excel, and PowerPoint documents from SharePoint and OneDrive for Business.
- Live: Meeting participants can interact and collaborate with PowerPoint Live and Excel Live. Not yet available through the SDK.
To learn more about the program, see the Introducing the new Microsoft 365 Document Collaboration Partner Program blog post.
The MDCPP SDK enables you to embed these experiences in your collaboration application. The API is divided into the following:
The documentAPI supports the Office for the Web experience. The user experience is as follows:
- Enable a user to work on a Microsoft 365 document through the Office for the Web experience hosted in your collaboration application. The Excel, PowerPoint, and Word documents must be located in SharePoint or OneDrive for Business.
The MeetingAPI is to support the Live experience. The following are the user experiences.
- Present: Present a document to your audience. Presenters will receive a rich presenter view and their actions will be broadcast to the audience. Attendees will receive an individualized view to see and navigate the content along with the presenter or on their own. (This experience isn't yet supported. It will be supported for PowerPoint presentations as part of this program soon.)
- Collaborate: Engage your audience in a collaborate work session. Presenters and attendees will receive an edit view of the document where they can collaborate in real time. Attendees can see and follow the presenter's current location. (This experience isn't yet supported. It will be supported for Excel workbooks as part of this program soon.)
Ensure that your Azure application has at least the following permissions, set to Delegated.
Microsoft service | Permission | Description | MDCPP scenario |
---|---|---|---|
SharePoint | AllSites.Read | Read items in all site collections. | Required for the Present and Join experiences. |
SharePoint | AllSites.Write | Read and write items in all site collections. | Required for the Office for the Web experience, or if supporting all experiences. |
SharePoint | MyFiles.Read | Read user files. | Required for the Present and Join experiences. |
SharePoint | MyFiles.Write | Read and write user files. | Required for the Office for the Web experience, or if supporting all experiences. |
To install the MDCPP SDK, run the following command.
npm install @microsoft/document-collaboration-sdk --save
To enable the user to choose a OneDrive for Business or SharePoint file, you can leverage the OneDrive File Picker. For more information, see the OneDrive File Picker documentation.
If you use this option, you'll get a post message when the user chooses a file. This callback will include some file properties. You can extract the following properties for use in the MDCPP APIs.
-
item.sharepointIds.siteUrl
: This is the siteUrl field in the documentInfo input. -
item.listItemUniqueId
: This should be used in the sourceDoc field in the documentInfo input.
const command = message.data.data;
switch (command.command) {
case "pick":
const ids = command.items[0].sharepointIds;
const spoUrl = ids.siteUrl;
const sourceDoc = ids.listItemUniqueId;
...
}
- The user must use the appId that was provided to the MDCPP program administrator.
- The app must be able to obtain a valid user token to the OneDrive for Business or SharePoint resource.
- If you use the OneDrive File Picker, you can use the same token acquisition code here.
- The user has been signed in with a Microsoft 365 account.
import * as Microsoft from "@microsoft/document-collaboration-sdk";
import uuidv4 from "uuid/v4";
function launchDocument(
siteUrl: string,
documentId: string)
{
Microsoft.initializeDocument({
hostName: "MDCPPPrototype",
hostClientType: "web"
});
const container = window.document.createElement("div");
container.style.height = "100%";
window.document.body.appendChild(container);
Microsoft.launch({
documentInfo: {
documentIdentifier: {
siteUrl: siteUrl,
sourceDoc: documentId
}
},
sessionInfo: {
hostCorrelationId: uuidv4()
},
container,
fetchAccessToken: async (resourceUrl: string, claim?: string[]) => {
let scopes: string[] = [];
if (claim && claim.length > 0) {
claim.forEach((val) => {
scopes.push(`${resourceUrl}/${val}`);
});
} else {
scopes.push(resourceUrl);
}
let token = await getTokenImpl({ scopes });
return token;
}
})
.then((response: Microsoft.BootInfo) => {
console.log('Launch API finished {0}, {1}', response.isBootSuccess, response.errorInfo );
})
.catch((e : any) => {
console.log(e);
});
}
You can alternatively launch the document by passing in its shareUrl. The beginning of your function could look like the following:
function launchDocument(
shareUrl: string)
{
Microsoft.initializeDocument({
hostName: "MDCPPPrototype",
hostClientType: "web"
});
const container = window.document.createElement("div");
container.style.height = "100%";
window.document.body.appendChild(container);
Microsoft.launch({
documentInfo: {
shareUrl: shareUrl
},
sessionInfo: {
...
- The Presenter has chosen a OneDrive for Business or SharePoint file to present.
- The app must be able to obtain a valid user token to the OneDrive for Business or SharePoint resource.
- If you use the OneDrive File Picker, you can use the same token acquisition code here.
- The user has been signed in with a Microsoft 365 account.
- The file must be a supported Present file type.
- PowerPoint: pptx, ppt, ppsx, potx, potm, pptm, ppsm, pps, pot, odp
import * as Microsoft from "@microsoft/document-collaboration-sdk";
import uuidv4 from "uuid/v4";
function launchPresenter(
meetingId: string,
userId: string,
participantId: string,
userDisplayName: string,
siteUrl: string,
itemId: string)
{
Microsoft.initializeMeeting( {
hostName: "MCPPPrototype",
hostClientType: "desktop"
});
const container = window.document.createElement("div");
container.style.height = "100%";
window.document.body.appendChild(container);
Microsoft.startPresentation({
meetingInfo: {
id: meetingId
},
userInfo: {
userId: userId,
participantId: participantId,
displayName: userDisplayName
},
documentInfo: {
siteUrl: siteUrl,
sourceDoc: itemId
},
sessionInfo: {
// Use your preferred GUID generator package to get a unique ID for logging.
hostCorrelationId: uuidv4()
},
container,
fetchAccessToken: async (resourceUrl: string, claim?: string[]) => {
let scopes: string[] = [];
if (claim && claim.length > 0) {
claim.forEach((val) => {
scopes.push(`${resourceUrl}/${val}`);
});
} else {
scopes.push(resourceUrl);
}
let token = await getTokenImpl({ scopes });
return token;
}
})
.then((response: Microsoft.BootInfo) => {
console.log('Present API finished {0}, {1}, {2}, {3}', response.isBootSuccess, response.joinInfo, meetingId, response.errorInfo );
})
.catch((e : any) => {
console.log(e);
});
}
- The Presenter has called startPresentation and received a joinInfo string.
- The joinInfo string has been sent to an attendee in the meeting.
import * as Microsoft from "@microsoft/document-collaboration-sdk";
import uuidv4 from "uuid/v4";
function launchAttendee(
meetingId: string,
userId: string,
participantId: string,
userDisplayName: string,
joinInfo: string)
{
Microsoft.initializeMeeting({
hostName: "MCPPPrototype",
hostClientType: "desktop"
});
const container = window.document.createElement("div");
container.style.height = "100%";
window.document.body.appendChild(container);
Microsoft.joinPresentation({
meetingInfo: {
id: meetingId
},
userInfo: {
userId: userId,
participantId: participantId,
displayName: userDisplayName
},
sessionInfo: {
// Use your preferred GUID generator package to get a unique ID for logging.
hostCorrelationId: uuidv4()
},
container,
joinInfo
})
.then((response: Microsoft.BootInfo) => {
console.log('Attendee join success: {0}, {1}, {2}', response.isBootSuccess, meetingId, response.errorInfo);
})
.catch((err: any) => {
console.log(err);
})
}