Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Outlook event-based activation examples are immature #747

Open
cut2run opened this issue Apr 3, 2024 · 1 comment
Open

Outlook event-based activation examples are immature #747

cut2run opened this issue Apr 3, 2024 · 1 comment

Comments

@cut2run
Copy link

cut2run commented Apr 3, 2024

Note: This repo is only for questions related to its samples. If you have questions about how to use office.js or the Office developer platform, please post your question on https://stackoverflow.com. Tag your question with office-js or outlook-web-addins

Question

The recent Outlook-set-signature example is a great attempt to display how to use webpack to build event-based activation add-on. When following the example, it was easy to understand, how to build with the packager the entire add-on, including taskpane and event-based parts to include appropriate dependencies, do multi-scripting, etc. However, the most complicated part to understand and very hard to find any information for was left uncovered. So let me explain ...

The example completely covers how to build the entry point to be used in webcontrol runtime environment. Basically, this is similar to creating the entry point for taskpane and we use the packager (webpack) to produce the HTML file with appropriate dependencies. For example, when built, autorunweb.html would include not just the main script autorun.js but all required dependencies (for example polyfill.js lib; may include jQuery as well, but the example uses external source, which is fine for demonstration purpose to include at least one 3rd party library) ...

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
    <title></title>
    <script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.9.1.min.js" type="text/javascript"></script>
    <script src="https://appsforoffice.microsoft.com/lib/1.1/hosted/office.js" type="text/javascript"></script>
    <script type="text/javascript" src="c0e7e140f196d28264f7.js"></script>
    <script type="text/javascript" src="67ee10aad35201b16094.js"></script>
<script defer src="polyfill.js"></script><script defer src="autorun.js"></script></head>
<body>
    <!-- NOTE: The body is empty on purpose. Since this is invoked via a button, there is no UI to render. -->
</body>
</html>

To finish with the introduction let's assume the autorun.js REQUIRED polifill.js and will fail without it. Or we can assume jQuery is required as well in order main script to work. So, this runtime (web-browser control) will handle the load of all of the required dependencies and the produced HTML file will properly work under Outlook on Web, Mac new UI, etc.

Finally to the question. Outlook desktop on Windows uses JS runtime instead. The entry point MUST be the single JS file, which the example has in the manifest. So far we just following the Event-based activation behavior and limitations where stated ...

Only the JavaScript file referenced in the manifest is supported for event-based activation. You must bundle your event-handling JavaScript code into this single file.

But when we look close on the example provided you just copied the main file without any processing and manifest pointed to this file...
Webpack command:

      {
        from: "src/runtime/Js/autorunshared.js",
        to: "[name]" + "[ext]",
      },

Manifest:

      "id": "runtime_1",
      "type": "general",
      "code": {
          "page": "https://localhost:3000/autorunweb.html",
          "script": "https://localhost:3000/autorunshared.js"
      },

If we still assume the autorunshared.js requires polifill.js or the entire jQuery library, the script will fail and I assume your example as well. It works only because the code really doesn't require the polifill or jQuery, I assume Outlook JS runtime will not have those dependencies, as it loads only the single JS file. Am I missing something? The example doesn't really explain how to load the required dependencies for the main JS file.

What I've done so far when trying to work on our company add-on ...

We are using webpack from the very first version of our add-on (years ago), as the Yeoman Generator is actually generates the add-on template this way. To add the event-based extension point I used the webpack to generate the single JS file with all of the required dependencies (kinda fat JS file). There are a lot of 3rd party dependencies for our code, such as polifill, jQuery, bootstrap, phonelib, etc. The HTML entry point is clean and following the the documentation ...

<!doctype html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    <title>Email Encryption</title>
    <script src="https://appsforoffice.microsoft.com/lib/1.1/hosted/office.js"></script>
    <script src="scripts/launchEvents.min.js?8d9b468ac9f81535ccad"></script>
</head>

<body>This page is left blank intentionally.</body>

</html>

When the page loaded everything work as expected, even when webpack handling "unpacking" of this fat launchEvents.min.js file on the fly. When I pointed to the same ``launchEvents.min.js` JS file for Outlook Desktop JS runtime. It doesn't work and failing by timeout.

manifest.xml

<Runtimes>
<!-- HTML file including reference to or inline JavaScript event handlers.
     This is used by Outlook on the web and Outlook on the new Mac UI. -->
<Runtime resid="LaunchEventsFile.Url">
  <!-- JavaScript file containing event handlers. This is used by Outlook on Windows. -->
  <Override type="javascript" resid="LaunchEventsJS.Url"/>
</Runtime>
</Runtimes>
<DesktopFormFactor>
<FunctionFile resid="FunctionsFile.Url" />
<ExtensionPoint xsi:type="LaunchEvent">
  <LaunchEvents>
    <LaunchEvent Type="OnMessageSend" FunctionName="onLaunchEventMessageSendHandler" SendMode="PromptUser"/>
  </LaunchEvents>
  <!-- Identifies the runtime to be used (also referenced by the Runtime element). -->
  <SourceLocation resid="LaunchEventsFile.Url"/>
</ExtensionPoint>

....

<bt:Url id="LaunchEventsFile.Url" DefaultValue="https://localhost:3000/launchEvents.html" />
<bt:Url id="LaunchEventsJS.Url" DefaultValue="https://localhost:3000/scripts/launchEvents.min.js" />

It looks like it does loading the JS, but most likely cannot find the association entry ...

Office.actions.associate("onLaunchEventMessageSendHandler", onLaunchEventMessageSendHandler);

because it's "hidden" by webpack packaging as any other 3rd party dependencies. May be I am wrong, but I have a hard time to find any "mature" example on how the single JS file have to look like when combined with 3rd party dependencies by webpack. And ALL your Outlook event-based examples are not helpful.

I am not asking you to extend the example (it might be a great idea for someone else in the future), but at least would you provide with any information on how this single JS must be packaged with webpack when there are some 3rd party dependencies. In your case for example the dependency for poolifill.js.

Sorry for the long essay, just wanted to make it clear.

@AlexJerabek
Copy link
Collaborator

Assigning @samantharamon to investigate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants