diff --git a/docs/develop/event-based-activation.md b/docs/develop/event-based-activation.md new file mode 100644 index 0000000000..3b96a5d672 --- /dev/null +++ b/docs/develop/event-based-activation.md @@ -0,0 +1,248 @@ +--- +title: Implement event-based activation in Excel, PowerPoint, and Word add-ins +description: Learn how to develop an Excel, PowerPoint, and Word add-in that implements event-based activation. +ms.date: 06/30/2025 +ms.topic: how-to +ms.localizationpriority: medium +--- + +# Implement event-based activation in Excel, PowerPoint, and Word add-ins + +Event-based activation automatically launches a centrally deployed Word, Excel, or PowerPoint add-in whenever a document is created or opened. This allows the add-in to validate, insert, or refresh critical content without any manual operations. The add-in is opened in the background to avoid disrupting the user. + +> [!NOTE] +> For information on how to implement event-based activation for Outlook add-ins, see [Configure your Outlook add-in for event-based activation](../outlook/autolaunch.md). + +## Supported events and clients + +| Event name | Description | Supported clients and channels | +| ----- | ----- | ----- | +| `OnDocumentOpened` | Occurs when a user opens a document or creates a new document, spreadsheet, or presentation. | | + +## Behavior and limitations + +As you develop an event-based add-in, be mindful of the following feature behaviors and limitations. + +- Office on Mac on is not supported. +- The unified manifest is not supported. +- Event-based add-ins work only when deployed by an administrator. If users install them directly from AppSource or the Office Store, they will not automatically launch. Admin deployments are done by uploading the manifest to the Microsoft 365 admin center. +- If a user installs multiple add-ins that handle the same activation event, only one add-in will be activated. There is no deterministic way to know which add-in will be activated. For example, if multiple add-ins that handle `OnDocumentOpened`, only one of those handlers will run. +- APIs that interact with the UI or display UI elements are not supported for Word, PowerPoint, and Excel on Windows. This is because the event handler runs in a JavaScript-only runtime. For more information, see [Runtimes in Office Add-ins](../testing/runtimes.md). + +## Walkthrough: Automatically act when the document opens + +The following sections walk you through how to develop a Word add-in that automatically changes the document header when a new or existing document opens. While this specific sample is for Word, the manifest configuration is the same for Excel and PowerPoint. + +> [!IMPORTANT] +> This sample requires you to have a Microsoft 365 subscription with the supported version of Word. + +### Create a new add-in + +Create a new add-in by following the [Word add-in quick start](../quickstarts/word-quickstart-yo.md?tabs=yeoman). This will give you a working Office Add-in to which you can add the event-based activation code. + +### Configure the manifest + +To enable an event-based add-in, you must configure the following elements in the `VersionOverridesV1_0` node of the manifest. + +- In the [Runtimes](/javascript/api/manifest/runtimes) element, make a new [Override element for Runtime](/javascript/api/manifest/override#override-element-for-runtime). Override the "javascript" type and reference the JavaScript file containing the function you want to trigger with the event. +- In the [DesktopFormFactor](/javascript/api/manifest/desktopformfactor) element, add a [FunctionFile](/javascript/api/manifest/functionfile) element for the JavaScript file with the event handler. +- In the [ExtensionPoint](/javascript/api/manifest/extensionpoint) element, set the `xsi:type` to `LaunchEvent`. This enables the event-based activation feature in your add-in. +- In the [LaunchEvent](/javascript/api/manifest/launchevent) element, set the `Type` to `OnDocumentOpened` and specify the JavaScript function name of the event handler in the `FunctionName` attribute. + +Use the following sample manifest code to update your project. + +1. In your code editor, open the quick start project you created. +1. Open the **manifest.xml** file located at the root of your project. +1. Select the entire **\** node (including the open and close tags) and replace it with the following XML. + + ```xml + + + + + + + + + + + + + <Description resid="GetStarted.Description"/> + <LearnMoreUrl resid="GetStarted.LearnMoreUrl"/> + </GetStarted> + <FunctionFile resid="Commands.Url"/> + <ExtensionPoint xsi:type="LaunchEvent"> + <LaunchEvents> + <LaunchEvent Type="OnDocumentOpened" FunctionName="changeHeader"></LaunchEvent> + </LaunchEvents> + <SourceLocation resid="WebViewRuntime.Url"/> + </ExtensionPoint> + <ExtensionPoint xsi:type="PrimaryCommandSurface"> + <OfficeTab id="TabHome"> + <Group id="CommandsGroup"> + <Label resid="CommandsGroup.Label"/> + <Icon> + <bt:Image size="16" resid="Icon.16x16"/> + <bt:Image size="32" resid="Icon.32x32"/> + <bt:Image size="80" resid="Icon.80x80"/> + </Icon> + <Control xsi:type="Button" id="TaskpaneButton"> + <Label resid="TaskpaneButton.Label"/> + <Supertip> + <Title resid="TaskpaneButton.Label"/> + <Description resid="TaskpaneButton.Tooltip"/> + </Supertip> + <Icon> + <bt:Image size="16" resid="Icon.16x16"/> + <bt:Image size="32" resid="Icon.32x32"/> + <bt:Image size="80" resid="Icon.80x80"/> + </Icon> + <Action xsi:type="ShowTaskpane"> + <TaskpaneId>ButtonId1</TaskpaneId> + <SourceLocation resid="Taskpane.Url"/> + </Action> + </Control> + </Group> + </OfficeTab> + </ExtensionPoint> + </DesktopFormFactor> + </Host> + </Hosts> + <Resources> + <bt:Images> + <bt:Image id="Icon.16x16" DefaultValue="https://localhost:3000/assets/icon-16.png"/> + <bt:Image id="Icon.32x32" DefaultValue="https://localhost:3000/assets/icon-32.png"/> + <bt:Image id="Icon.80x80" DefaultValue="https://localhost:3000/assets/icon-80.png"/> + </bt:Images> + <bt:Urls> + <bt:Url id="GetStarted.LearnMoreUrl" DefaultValue="https://go.microsoft.com/fwlink/?LinkId=276812"/> + <bt:Url id="Commands.Url" DefaultValue="https://localhost:3000/commands.html"/> + <bt:Url id="Taskpane.Url" DefaultValue="https://localhost:3000/taskpane.html"/> + <bt:Url id="WebViewRuntime.Url" DefaultValue="https://localhost:3000/commands.html"/> + <bt:Url id="JsRuntimeWord.Url" DefaultValue="https://localhost:3000/commands.js"/> + </bt:Urls> + <bt:ShortStrings> + <bt:String id="GetStarted.Title" DefaultValue="Get started with your sample add-in!"/> + <bt:String id="CommandsGroup.Label" DefaultValue="Event-based add-in activation"/> + <bt:String id="TaskpaneButton.Label" DefaultValue="My add-in"/> + </bt:ShortStrings> + <bt:LongStrings> + <bt:String id="GetStarted.Description" DefaultValue="Your sample add-in loaded successfully. Go to the HOME tab and click the 'Show Task Pane' button to get started."/> + <bt:String id="TaskpaneButton.Tooltip" DefaultValue="Click to show the task pane"/> + </bt:LongStrings> + </Resources> + </VersionOverrides> + ``` + +1. Save your changes. + +### Implement the event handler + +To enable your add-in to act when the `OnDocumentOpened` event occurs, you must implement a JavaScript event handler. In this section, you'll create the `changeHeader` function, which adds a "Public" header to new documents or a "Highly Confidential" header to existing documents that already have content. + +1. In the **./src/commands** folder, open the file named **commands.js**. +1. Replace the entire contents of **commands.js** with the following JavaScript code. + + ```javascript + /* + * Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. + * See LICENSE in the project root for license information. + */ + /* global global, Office, self, window */ + + Office.onReady(() => { + // If needed, Office.js is ready to be called + }); + + async function changeHeader(event) { + Word.run(async (context) => { + const body = context.document.body; + body.load("text"); + await context.sync(); + + if (body.text.length == 0) { + // For new or empty documents, make a "Public" header. + const header = context.document.sections.getFirst().getHeader(Word.HeaderFooterType.primary); + const firstPageHeader = context.document.sections.getFirst().getHeader(Word.HeaderFooterType.firstPage); + header.clear(); + firstPageHeader.clear(); + + header.insertParagraph("Public - The data is for the public and shareable externally", "Start"); + firstPageHeader.insertParagraph("Public - The data is for the public and shareable externally", "Start"); + header.font.color = "#07641d"; + firstPageHeader.font.color = "#07641d"; + await context.sync(); + } else { + // For existing documents, make a "Highly Confidential" header. + const header = context.document.sections.getFirst().getHeader(Word.HeaderFooterType.primary); + const firstPageHeader = context.document.sections.getFirst().getHeader(Word.HeaderFooterType.firstPage); + header.clear(); + firstPageHeader.clear(); + header.insertParagraph("Highly Confidential - The data must be secret or in some way highly critical", "Start"); + firstPageHeader.insertParagraph("Highly Confidential - The data must be secret or in some way highly critical", "Start"); + header.font.color = "#f8334d"; + firstPageHeader.font.color = "#f8334d"; + await context.sync(); + } + }); + + // Calling event.completed is required. event.completed lets the platform know that processing has completed. + event.completed(); + } + + async function paragraphChanged() { + await Word.run(async (context) => { + const results = context.document.body.search("110"); + results.load("length"); + await context.sync(); + if (results.items.length == 0) { + const header = context.document.sections.getFirst().getHeader(Word.HeaderFooterType.primary); + header.clear(); + header.insertParagraph("Public - The data is for the public and shareable externally", "Start"); + const font = header.font; + font.color = "#07641d"; + + await context.sync(); + } else { + const header = context.document.sections.getFirst().getHeader(Word.HeaderFooterType.primary); + header.clear(); + header.insertParagraph("Highly Confidential - The data must be secret or in some way highly critical", "Start"); + const font = header.font; + font.color = "#f8334d"; + + await context.sync(); + } + }); + } + + async function registerOnParagraphChanged(event) { + Word.run(async (context) => { + let eventContext = context.document.onParagraphChanged.add(paragraphChanged); + await context.sync(); + }); + // Calling event.completed is required. event.completed lets the platform know that processing has completed. + event.completed(); + } + + + Office.actions.associate("changeHeader", changeHeader); + Office.actions.associate("registerOnParagraphChanged", registerOnParagraphChanged); + ``` + +1. Save your changes. + +### Test and validate your add-in + +1. Run `npm start` to build your project and launch the web server. **Ignore the Word document that is opened**. +1. Manually sideload your add-in in Word on the web by following the guidance at [Sideload Office Add-ins to Office on the web](../testing/sideload-office-add-ins-for-testing.md#manually-sideload-an-add-in-to-office-on-the-web). Use the **manifest.xml** in the root of the project. +1. Try opening both new and existing Word documents in Word on the web. Headers should automatically be added when they open. + +## Deploy your add-in + +Event-based add-ins work only when deployed by an administrator. If users install them directly from AppSource or the Office Store, they will not automatically launch. To perform an admin deployment, upload the manifest to the Microsoft 365 admin center by taking the following actions. + +1. In the admin portal, expand the **Settings** section in the navigation pane then select **Integrated apps**. +1. On the **Integrated apps** page, choose the **Upload custom apps** action. + +For more information about how to deploy an add-in, please refer to [Deploy and publish Office Add-ins in the Microsoft 365 admin center](/microsoft-365/admin/manage/office-addins). diff --git a/docs/outlook/one-outlook.md b/docs/outlook/one-outlook.md index 5c2c06a458..53195ed8f1 100644 --- a/docs/outlook/one-outlook.md +++ b/docs/outlook/one-outlook.md @@ -1,7 +1,7 @@ --- title: Develop Outlook add-ins for the new Outlook on Windows description: Learn how to develop add-ins that are compatible with the new Outlook on Windows. -ms.date: 06/26/2025 +ms.date: 07/01/2025 ms.localizationpriority: medium --- @@ -64,7 +64,7 @@ Test your Outlook web add-in in the new Outlook on Windows today! To switch to t - Have a Microsoft 365 work or school account connected to Exchange Online. The new client doesn't currently support on-premises, hybrid, or sovereign Exchange accounts. > [!NOTE] - > While you can add non-Microsoft mail accounts, such as Gmail, to the new Outlook on Windows, you can only use Outlook add-ins with a Microsoft account. + > While you can add non-Microsoft mail accounts, such as Gmail, to the new Outlook on Windows, you can only use Outlook add-ins with a Microsoft account. For more information, see the "Supported accounts" section of the [Outlook add-ins overview](outlook-add-ins-overview.md#supported-accounts). - Have a minimum OS installation of Windows 10 Version 1809 (Build 17763). diff --git a/docs/outlook/outlook-add-ins-overview.md b/docs/outlook/outlook-add-ins-overview.md index bf1118c44f..932e938ee0 100644 --- a/docs/outlook/outlook-add-ins-overview.md +++ b/docs/outlook/outlook-add-ins-overview.md @@ -1,7 +1,7 @@ --- title: Outlook add-ins overview description: Outlook add-ins extend or customize the Outlook UI and are developed by Microsoft and partners using our web-based platform. -ms.date: 06/05/2025 +ms.date: 07/01/2025 ms.topic: overview ms.custom: scenarios:getting-started ms.localizationpriority: high @@ -92,6 +92,22 @@ However, add-ins won't activate on IRM-protected items when: Outlook add-ins are supported in Outlook on the web, Outlook on Windows (new and classic), Outlook on Mac, Outlook on iOS, Outlook on Android, and Outlook.com. Not all of the newest features are supported in all clients at the same time. For details about feature support on clients and servers, see [Requirement sets supported by Exchange servers and Outlook clients](/javascript/api/requirement-sets/outlook/outlook-api-requirement-sets#requirement-sets-supported-by-exchange-servers-and-outlook-clients) and articles specific to those features. +## Supported accounts + +On supported Outlook clients, add-ins can run on Outlook.com (consumer or personal) and Microsoft 365 business mailbox accounts. For more information on Microsoft accounts, see [What's the difference between a Microsoft account and a work or school account?](https://support.microsoft.com/account-billing/72f10e1e-cab8-4950-a8da-7c45339575b0). + +While non-Microsoft mailbox accounts, such as Gmail and Yahoo Mail, can be added to certain Outlook clients, Outlook add-ins aren't always supported on these accounts. The following table outlines add-in support on non-Microsoft accounts for each Outlook client. + +|Outlook client|Add-in support on non-Microsoft accounts| +|-----|-----| +|Web|Not supported.| +|new Outlook on Windows|Not supported.| +|classic Outlook on Windows|Not supported.| +|Mac|<ul><li>If a non-Microsoft account was added using the IMAP CloudCache option, add-ins are supported.</li><li>If a non-Microsoft account was added using the IMAP Direct option, add-ins aren't supported.</li></ul>| +|Mobile (Android and iOS)|Not supported.| + +When using non-Microsoft accounts that support add-ins in Outlook, note that you must first select a folder or item in the non-Microsoft mailbox to load the add-in. + ## Get started building Outlook add-ins To get started building Outlook add-ins, try the following: diff --git a/docs/outlook/outlook-mobile-addins.md b/docs/outlook/outlook-mobile-addins.md index 9136e9202f..824b4786ef 100644 --- a/docs/outlook/outlook-mobile-addins.md +++ b/docs/outlook/outlook-mobile-addins.md @@ -1,7 +1,7 @@ --- title: Add-ins for Outlook on mobile devices description: Outlook mobile add-ins are supported on all Microsoft 365 business accounts and Outlook.com accounts. -ms.date: 06/19/2025 +ms.date: 07/01/2025 ms.localizationpriority: medium --- @@ -9,7 +9,7 @@ ms.localizationpriority: medium Add-ins now work in Outlook on mobile devices, using the same APIs available for other Outlook endpoints. If you've built an add-in for Outlook already, it's easy to get it working on Outlook mobile. -Outlook mobile add-ins are supported on all Microsoft 365 business accounts and Outlook.com accounts. However, support is not currently available on Gmail accounts. +Outlook mobile add-ins are supported on all Microsoft 365 business accounts and Outlook.com accounts. However, support isn't currently available for non-Microsoft accounts, such as Gmail. For more information, see the "Supported accounts" section of [Outlook add-ins overview](outlook-add-ins-overview.md#supported-accounts). **An example task pane in Outlook on iOS** diff --git a/docs/outlook/outlook-on-send-addins.md b/docs/outlook/outlook-on-send-addins.md index 195c28b4d5..63b2b2d678 100644 --- a/docs/outlook/outlook-on-send-addins.md +++ b/docs/outlook/outlook-on-send-addins.md @@ -1,7 +1,7 @@ --- title: On-send feature for Outlook add-ins description: Provides a way to handle an item or block users from certain actions, and allows an add-in to set certain properties on send. -ms.date: 06/05/2025 +ms.date: 07/02/2025 ms.localizationpriority: medium --- @@ -395,17 +395,6 @@ The on-send add-ins will run during send if the Exchange server is online and re > [!NOTE] > On Mac in any offline state, the **Send** button (or the **Send Update** button for existing meetings) is disabled and a notification displayed that their organization doesn't allow send when the user is offline. -## Add-in availability when offline in new Outlook on Windows - -When a user turns on the [offline setting](https://support.microsoft.com/office/2460e4a8-16c7-47fc-b204-b1549275aac9) in the new Outlook on Windows, they can continue to access their emails and calendar if they lose internet connection. While some functionalities remain available, Outlook add-ins and the Microsoft 365 and Copilot store aren't available when offline. The following table describes the behavior of on-send add-ins when a machine is offline or has an intermittent connection. - -| Scenario | On-send add-in behavior | -| ----- | ----- | -| No internet connection when Outlook is launched | Because Outlook can't determine which add-ins are installed while offline, on-send add-ins can't activate when the `ItemSend` event occurs. To ensure that mail items are still checked for compliance before they're sent, administrators can configure the **OnSendAddinsEnabled** mailbox policy in Exchange Online PowerShell. When configured, outgoing items are saved to the **Drafts** folder instead of the **Outbox** folder to prevent them from being automatically sent when the machine reconnects to the internet. For more information, see [Install Outlook add-ins that use on-send](#install-outlook-add-ins-that-use-on-send). | -| A connection is established after launching Outlook while offline | Outlook will be able to identify which on-send add-ins are installed. When a user selects **Send** on a mail item that was blocked by the **OnSendAddinsEnabled** mailbox policy, the on-send add-in runs to check for compliance. | -| Machine loses connection while Outlook is in use | If a user loses connection as they select **Send**, a dialog is shown to notify them that they're offline. The mail item is then saved to the **Drafts** folder to prevent it from being automatically sent when the machine reconnects to the internet. | -| A connection is reestablished | Installed on-send add-ins resume handling the `ItemSend` event when it occurs. Mail items that were moved to the **Outbox** folder are sent. When items in the **Drafts** folder are sent, on-send add-ins are activated to ensure that the mail items are compliant. | - ### User can edit item while on-send add-ins are working on it While on-send add-ins are processing an item, the user can edit the item by adding, for example, inappropriate text or attachments. If you want to prevent the user from editing the item while your add-in is processing on send, you can implement a workaround using a dialog. This workaround can be used in Outlook on the web (classic), Windows (classic), and Mac. diff --git a/docs/toc.yml b/docs/toc.yml index 603a9f25b6..42bbe8efe0 100644 --- a/docs/toc.yml +++ b/docs/toc.yml @@ -119,6 +119,8 @@ items: displayName: manifest - name: Configure your add-in to use a shared runtime href: develop/configure-your-add-in-to-use-a-shared-runtime.md + - name: Implement event-based activation + href: develop/event-based-activation.md - name: Run code on document open href: develop/run-code-on-document-open.md - name: Manifest