Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Ce didacticiel vous apprend à créer un complément Outlook qui peut être utilisé pour dans le mode composer un message pour insérer du contenu dans le corps d’un message.
Dans ce didacticiel, vous allez :
- Créer un projet de complément Outlook
- Définir les boutons qui apparaissent dans la fenêtre de composition du message
- Implémenter une expérience de première exécution qui collecte des informations et extrait des données à partir d’un service externe
- Implémenter un bouton de l’interface utilisateur qui appelle une fonction
- Implémenter un volet des tâches qui insère du contenu dans le corps d’un message
Conseil
Si vous voulez obtenir une version complète de ce didacticiel, consultez le dépôt d’exemples de compléments Office sur GitHub.
Configuration requise
Node.js (la dernière version LTS active). Visitez le siteNode.js pour télécharger et installer la version adaptée à votre système d’exploitation.
La dernière version deYeoman et du Générateur Yeoman Générateur de compléments Office. Pour installer ces outils globalement, exécutez la commande suivante via l’invite de commande.
npm install -g yo generator-officeRemarque
Même si vous avez précédemment installé le générateur Yeoman, nous vous recommandons de mettre à jour votre package vers la dernière version de npm.
Office connecté à un abonnement Microsoft 365 (y compris Office on the web).
Remarque
Si vous n’avez pas encore Office, vous pouvez peut-être bénéficier d’un abonnement Microsoft 365 E5 pour développeurs via le programme Microsoft 365 pour développeurs ; Pour plus d’informations, consultez la FAQ. Vous pouvez également vous inscrire à un essai gratuit d’un mois ou acheter un plan Microsoft 365.
Visual Studio Code (VS Code) ou votre éditeur de code préféré.
Outlook sur le web, sur Windows (nouveau ou classique) ou sur Mac.
Un compte GitHub .
Installation
Le complément de ce didacticiel lit les Gist à partir d’un compte GitHub et ajoute les Gist sélectionnés dans le corps d’un message. Procédez comme suit pour créer deux nouveaux gists que vous pouvez utiliser pour tester le complément que vous allez créer.
-
Dans la zoneDescription gist..., entrez Hello World Markdown.
Dans la zoneNom de fichier incluant l’extension... , entrez test.md.
Ajoutez la démarque suivante à la zone de texte multiligne.
# Hello World This is content converted from Markdown! Here's a JSON sample: ```json { "foo": "bar" } ```Sélectionnez le boutoncréer un gist public.
-
Dans la zoneDescription gist..., entrez Hello World Html.
Dans la zoneNom de fichier incluant l’extension..., entrez test.html.
Ajoutez la démarque suivante à la zone de texte multiligne.
<html> <head> <style> h1 { font-family: Calibri; } </style> </head> <body> <h1>Hello World!</h1> <p>This is a test</p> </body> </html>Sélectionnez le boutoncréer un gist public.
Créer un projet de complément Outlook
Exécutez la commande suivante pour créer un projet de complément à l’aide du générateur Yeoman. Un dossier contenant le projet sera ajouté au répertoire actuel.
yo officeRemarque
Lorsque vous exécutez la commande
yo office, il est possible que vous receviez des messages d’invite sur les règles de collecte de données de Yeoman et les outils CLI de complément Office. Utilisez les informations fournies pour répondre aux invites comme vous l’entendez.Lorsque vous y êtes invité, fournissez les informations suivantes pour créer votre projet de complément.
Les étapes de création du projet varient légèrement en fonction du type de manifeste.
Remarque
Le manifeste unifié pour Microsoft 365 vous permet de combiner un complément Office avec une application Teams dans une application pour Microsoft 365 en tant qu’unité unique de développement et de déploiement. Pour en savoir plus, voir Compléments Office avec le manifeste unifié. Pour obtenir un exemple d’application pour Microsoft 365 qui combine une application Teams et un complément Outlook, consultez Offres de remise.
Nous apprécions vos commentaires sur le manifeste unifié. Si vous avez des suggestions, veuillez créer un problème dans le référentiel pour la bibliothèque JavaScript Office.
Remarque
Le manifeste unifié pour Microsoft 365 n’est actuellement pas pris en charge dans Outlook sur Mac. Si vous utilisez Outlook sur Mac, sélectionnez l’onglet Manifeste des compléments uniquement et suivez ces instructions à la place. Pour plus d’informations, voir Prise en charge des compléments avec le manifeste unifié pour Microsoft 365.
Sélectionnez un type de projet -
Office Add-in Task Pane projectSélectionnez un type de script -
JavaScriptComment souhaitez-vous nommer votre complément ? -
Git the gistQuelle application client Office voulez-vous prendre en charge ? -
OutlookQuel manifeste voulez-vous utiliser ? -
unified manifest for Microsoft 365
Après avoir exécuté l’assistant, le générateur crée le projet et installe les composants Node de prise en charge.
Accédez au registre racine du projet.
cd "Git the gist"Ouvrez votre projet dans VS Code ou votre éditeur de code préféré.
Conseil
Dans Windows, vous pouvez accéder au répertoire racine du projet via la ligne de commande, puis entrer
code .pour ouvrir ce dossier dans VS Code. Sur Mac, vous devez ajouter la commandecodeau chemin d’accès avant de pouvoir utiliser cette commande pour ouvrir le dossier de projet dans VS Code.
Mise à jour du manifeste
Le manifeste d’un complément contrôle la manière dont il apparaît dans Outlook. Il définit la façon dont le complément est affiché dans la liste des compléments, les boutons qui apparaissent sur le ruban, et il configure les URL pour les fichiers HTML et JavaScript utilisés par le complément.
Spécifiez les informations de base
Effectuez les mises à jour suivantes dans le fichier manifeste pour spécifier des informations de base sur le complément.
Recherchez la
"description"propriété, remplacez la valeur par défaut et"full"les valeurs par la description"short"du complément, puis enregistrez le fichier."description": { "short": "Gets gists.", "full": "Allows users to access their GitHub gists." },Enregistrez le fichier.
Tester le complément généré
Avant d’aller plus loin, nous allons tester le complément base créé par le générateur pour confirmer que le projet est correctement configuré.
Remarque
Les compléments Office doivent utiliser le protocole HTTPS, et non HTTP, même pendant le développement. Si vous êtes invité à installer un certificat après avoir exécuté l’une des commandes suivantes, acceptez l’invite pour installer le certificat fourni par le générateur Yeoman. Il se peut également que vous deviez exécuter votre invite de commande ou votre terminal en tant qu'administrateur pour que les modifications soient effectuées.
S’il s’agit de votre premier développement d’un complément Office sur votre ordinateur, vous pouvez être invité dans la ligne de commande à accorder à l’affichage web Microsoft Edge une exemption de bouclage (« Autoriser le bouclage localhost pour l’affichage web Microsoft Edge ? »). Lorsque vous y êtes invité, entrez
Ypour autoriser l’exemption. Notez que vous aurez besoin de privilèges d’administrateur pour autoriser l’exemption. Une fois autorisé, vous ne devez pas être invité à demander une exemption lorsque vous chargerez une version test de compléments Office à l’avenir (sauf si vous supprimez l’exemption de votre ordinateur). Pour en savoir plus, voir « Impossible d’ouvrir ce complément à partir de localhost » lors du chargement d’un complément Office ou de l’utilisation de Fiddler.
Lorsque vous utilisez pour la première fois le générateur Yeoman pour développer un complément Office, votre navigateur par défaut ouvre une fenêtre dans laquelle vous êtes invité à vous connecter à votre compte Microsoft 365. Si aucune fenêtre de connexion n’apparaît et que vous rencontrez une erreur de chargement indépendant ou de délai d’expiration de la connexion, exécutez
atk auth login m365.
Exécutez la commande suivante dans le répertoire racine de votre projet. Lorsque vous exécutez cette commande, le serveur web local démarre et votre complément est téléchargé.
npm startRemarque
Lorsque vous utilisez pour la première fois le générateur Yeoman pour développer un complément Office, votre navigateur par défaut ouvre une fenêtre dans laquelle vous êtes invité à vous connecter à votre compte Microsoft 365. Si aucune fenêtre de connexion n’apparaît et que vous rencontrez une erreur de chargement indépendant ou de délai d’expiration de la connexion, exécutez
atk auth login m365avant d’exécuternpm startà nouveau.Si votre complément n’a pas été automatiquement chargé d’une version testée, suivez les instructions de la section Charger une version test des compléments Outlook pour tester le chargement manuel d’une version test du complément dans Outlook.
Dans Outlook, ouvrez un message existant et sélectionnez le bouton Afficher le volet Office.
Lorsque la boîte de dialogue WebView Stop On Load apparaît, sélectionnez OK.
Remarque
Si vous sélectionnez Annuler, la boîte de dialogue ne s’affiche plus lors de l’exécution de cette instance du complément. Toutefois, si vous redémarrez votre complément, la boîte de dialogue s’affichera à nouveau.
Si tout a été correctement configuré, le volet Office s’ouvre et affiche la page d’accueil du complément.
Lorsque vous souhaitez arrêter le serveur web local et désinstaller le complément, suivez les instructions applicables :
Pour arrêter le serveur, exécutez la commande suivante. Si vous avez utilisé
npm start, la commande suivante doit également désinstaller le complément.npm stopSi vous avez chargé manuellement un complément indépendant, consultez Supprimer un complément chargé d’une version indépendante.
Définir des boutons
À présent que vous avez vérifié que le complément base fonctionne, vous pouvez le personnaliser pour ajouter davantage de fonctionnalités. Par défaut, le manifeste définit uniquement les boutons de la fenêtre de lecture de message. Nous allons mettre à jour le manifeste pour supprimer les boutons de la fenêtre de lecture de message et définir deux nouveaux boutons pour la fenêtre composer un message :
Afficher la liste de résumé : bouton qui ouvre un volet Office
Insérer gist par défaut: bouton qui appelle une fonction
La procédure dépend du manifeste que vous utilisez.
Procédez comme suit :
Ouvrez le fichier manifest.json .
Dans le tableau, il y a deux objets d’exécution
"extensions.runtimes". Pour le second, avec le"id"de"CommandsRuntime", remplacez le"actions.id"par"insertDefaultGist". Il s’agit du nom d’une fonction que vous créez dans une étape ultérieure. Lorsque vous avez terminé, l’objet d’exécution doit ressembler à ce qui suit :{ "id": "CommandsRuntime", "type": "general", "code": { "page": "https://localhost:3000/commands.html" }, "actions": [ { "id": "insertDefaultGist", "type": "executeFunction" } ] }Remplacez l’élément du
"extensions.ribbons.contexts"tableau par"mailCompose". Cela signifie que les boutons s’affichent uniquement dans une nouvelle fenêtre de message ou de réponse."contexts": [ "mailCompose" ],Le
"extensions.ribbons.tabs.groups"tableau contient un objet groupe. Apportez les modifications suivantes à cet objet.- Modifiez la
"id"propriété en"msgComposeCmdGroup". - Changez la
"label"propriété en « Git l’essentiel ».
- Modifiez la
Ce même objet de groupe a un
"controls"tableau avec deux objets de contrôle. Nous devons apporter des modifications au JSON pour chacun d’eux. Dans la première, procédez comme suit.- Remplacez le
"id"par"msgComposeShowGistListTaskPane". - Remplacez le mot clé par « Afficher la
"label"liste de contenu ». - Remplacez le mot clé par « Afficher la
"supertip.title"liste de contenu ». - Remplacez cette option par
"supertip.description"« Affiche une liste de vos gist et vous permet d’insérer leur contenu dans le message actuel ».
- Remplacez le
Dans le deuxième objet de contrôle, procédez comme suit.
- Remplacez le
"id"par"msgComposeInsertDefaultGist". - Remplacez cette option par « Insérer un
"label"gist par défaut ». - Remplacez cette option par « Insérer un
"supertip.title"gist par défaut ». - Remplacez cette option
"supertip.description"par « Insère le contenu de l’essentiel que vous marquez comme par défaut dans le message actuel ». - Remplacez le
"actionId"par"insertDefaultGist". Cela correspond à celui"action.id""CommandsRuntime"que vous avez défini à l’étape précédente.
Lorsque vous avez terminé, la
"ribbons"propriété doit ressembler à ce qui suit :"ribbons": [ { "contexts": [ "mailCompose" ], "tabs": [ { "builtInTabId": "TabDefault", "groups": [ { "id": "msgComposeCmdGroup", "label": "Git the gist", "icons": [ { "size": 16, "file": "https://localhost:3000/assets/icon-16.png" }, { "size": 32, "file": "https://localhost:3000/assets/icon-32.png" }, { "size": 80, "file": "https://localhost:3000/assets/icon-80.png" } ], "controls": [ { "id": "msgComposeInsertGist", "type": "button", "label": "Display gist list", "icons": [ { "size": 16, "file": "https://localhost:3000/assets/icon-16.png" }, { "size": 32, "file": "https://localhost:3000/assets/icon-32.png" }, { "size": 80, "file": "https://localhost:3000/assets/icon-80.png" } ], "supertip": { "title": "Display gist list", "description": "Displays a list of your gists and allows you to insert their contents into the current message." }, "actionId": "TaskPaneRuntimeShow" }, { "id": "msgComposeInsertDefaultGist", "type": "button", "label": "Insert default gist", "icons": [ { "size": 16, "file": "https://localhost:3000/assets/icon-16.png" }, { "size": 32, "file": "https://localhost:3000/assets/icon-32.png" }, { "size": 80, "file": "https://localhost:3000/assets/icon-80.png" } ], "supertip": { "title": "Insert default gist", "description": "Inserts the content of the gist you mark as default into the current message." }, "actionId": "insertDefaultGist" } ] } ] } ] } ]- Remplacez le
Enregistrez les modifications dans le manifeste.
Réinstallez le complément.
Vous devez réinstaller le complément pour que les modifications du manifeste prennent effet.
Si le serveur Web est en cours d’exécution, exécutez la commande suivante.
npm stopExécutez la commande suivante pour démarrer le serveur web local et charger automatiquement votre complément.
npm start
Une fois que vous avez réinstallé le complément, vous pouvez vérifier qu’il a été correctement installé en recherchant les commandes Afficher la liste des éléments gist et Insérer l’image gist par défaut dans une fenêtre de rédaction de message. Notez que rien ne se produit si vous sélectionnez un des ces éléments, car vous n’avez pas encore terminé de générer ce complément.
Si vous exécutez ce complément dans Outlook classique sur Windows ou dans Outlook sur Mac, vous devez voir deux nouveaux boutons sur le ruban de la fenêtre de composition d’un message : Afficher la liste de gist et Insérer un gist par défaut.
Si vous exécutez ce complément dans Outlook sur le web ou la nouvelle version d’Outlook sur Windows, sélectionnez Applications dans le ruban de la fenêtre de composition d’un message, puis sélectionnez Utiliser l’essentiel pour afficher la liste des éléments essentiels et les options Insérer un fichier récapitulatif par défaut .
Conseil
Pour obtenir des instructions sur la localisation de votre complément sur le ruban, consultez Utiliser des compléments dans Outlook.
Mettre en œuvre une expérience de première exécution
Ce complément doit être capable de lire l’essentiel à partir d’un compte GitHub et d’identifier l’élément générique par défaut choisi. Pour atteindre ces objectifs, le complément vous invite à fournir votre nom d’utilisateur GitHub et à choisir un Gist par défaut dans votre collection d’Gist existants. Suivez les étapes décrites dans cette section pour implémenter une expérience de première exécution qui affiche une boîte de dialogue pour collecter ces informations.
Créer l’interface utilisateur de la boîte de dialogue
Commençons par créer l’interface utilisateur de la boîte de dialogue.
Dans le dossier ./src, créez un sous-dossier nommé settings.
Dans le dossier ./src/settings , créez un fichier nommé dialog.html.
Dans dialog.html, ajoutez le balisage suivant pour définir un formulaire de base avec une entrée de texte pour un nom d’utilisateur GitHub et une liste vide pour les gists qui seront renseignés via JavaScript.
<!doctype html> <html> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> <title>Settings</title> <!-- Office JavaScript API --> <script type="text/javascript" src="https://officeapis.public.onecdn.static.microsoft/1/office.js"></script> <!-- For more information on Fluent UI, visit https://developer.microsoft.com/fluentui. --> <link rel="stylesheet" href="https://res-1.cdn.office.net/files/fabric-cdn-prod_20230815.002/office-ui-fabric-core/11.1.0/css/fabric.min.css" /> <!-- Template styles --> <link href="dialog.css" rel="stylesheet" type="text/css" /> </head> <body class="ms-font-l"> <main> <section class="ms-font-m ms-fontColor-neutralPrimary"> <div class="not-configured-warning ms-MessageBar ms-MessageBar--warning"> <div class="ms-MessageBar-content"> <div class="ms-MessageBar-icon"> <i class="ms-Icon ms-Icon--Info"></i> </div> <div class="ms-MessageBar-text"> Oops! It looks like you haven't configured <strong>Git the gist</strong> yet. <br /> Please configure your GitHub username and select a default gist, then try that action again! </div> </div> </div> <div class="ms-font-xxl">Settings</div> <div class="ms-Grid"> <div class="ms-Grid-row"> <div class="ms-TextField"> <label class="ms-Label">GitHub Username</label> <input class="ms-TextField-field" id="github-user" type="text" value="" placeholder="Please enter your GitHub username" /> </div> </div> <div class="error-display ms-Grid-row"> <div class="ms-font-l ms-fontWeight-semibold">An error occurred:</div> <pre><code id="error-text"></code></pre> </div> <div class="gist-list-container ms-Grid-row"> <div class="list-title ms-font-xl ms-fontWeight-regular">Choose Default Gist</div> <form> <div id="gist-list"></div> </form> </div> </div> <div class="ms-Dialog-actions"> <div class="ms-Dialog-actionsRight"> <button class="ms-Dialog-action ms-Button ms-Button--primary" id="settings-done" disabled> <span class="ms-Button-label">Done</span> </button> </div> </div> </section> </main> <script type="text/javascript" src="../helpers/gist-api.js"></script> </body> </html>Vous avez peut-être remarqué que le fichier HTML fait référence à un fichier JavaScript, gist-api.js, qui n'existe pas encore. Ce fichier sera créé dans la section Fetch data from GitHub .
Enregistrez vos modifications.
Ensuite, créez un fichier dans le dossier ./src/settings nommé dialog.css.
Dans dialog.css, ajoutez le code suivant pour spécifier les styles utilisés par dialog.html.
body { background-color: #ffffff; } section { margin: 10px 20px; } .not-configured-warning { display: none; } .error-display { display: none; } .gist-list-container { margin: 10px -8px; display: none; } .list-title { border-bottom: 1px solid #a6a6a6; padding-bottom: 5px; } ul { margin-top: 10px; } .ms-ListItem-secondaryText, .ms-ListItem-tertiaryText { padding-left: 15px; }Enregistrez vos modifications.
Développer la fonctionnalité de la boîte de dialogue
Maintenant que vous avez défini la boîte de dialogue interface utilisateur, vous pouvez écrire du code pour l’utiliser.
Dans le dossier ./src/settings , créez un fichier nommé dialog.js.
Ajoutez le code suivant.
(function () { "use strict"; // The onReady function must be run each time a new page is loaded. Office.onReady(function () { function initializeDialog() { if (window.location.search) { // Check if warning should be displayed. const warn = getParameterByName("warn"); if (warn) { document.querySelector(".not-configured-warning").style.display = "block"; } else { // See if the config values were passed. // If so, pre-populate the values. const user = getParameterByName("gitHubUserName"); const gistId = getParameterByName("defaultGistId"); document.getElementById("github-user").value = user; loadGists(user, function (success) { if (success) { document.querySelectorAll(".ms-ListItem").forEach(function (item) { item.classList.remove("is-selected"); if (item.value === gistId) { item.classList.add("is-selected"); item.checked = true; } }); document.getElementById("settings-done").disabled = false; } }); } } // When the GitHub username changes, try to load gists. document.getElementById("github-user").addEventListener("change", function () { document.getElementById("gist-list").textContent = ""; const ghUser = document.getElementById("github-user").value; if (ghUser.length > 0) { loadGists(ghUser); } }); // When the Done button is selected, send the values back to the caller as a serialized object. document.getElementById("settings-done").addEventListener("click", function () { const settings = {}; settings.gitHubUserName = document.getElementById("github-user").value; const selectedGist = document.querySelector(".ms-ListItem.is-selected"); if (selectedGist) { settings.defaultGistId = selectedGist.value; sendMessage(JSON.stringify(settings)); } }); } if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", initializeDialog); } else { initializeDialog(); } }); // Load gists using the GitHub API and build the list. function loadGists(user, callback) { getUserGists(user, function (gists, error) { if (error) { document.querySelector(".gist-list-container").style.display = "none"; document.getElementById("error-text").textContent = JSON.stringify(error, null, 2); document.querySelector(".error-display").style.display = "block"; if (callback) callback(false); } else { document.querySelector(".error-display").style.display = "none"; buildGistList(document.getElementById("gist-list"), gists, onGistSelected); document.querySelector(".gist-list-container").style.display = "block"; if (callback) callback(true); } }); } function onGistSelected() { document.querySelectorAll(".ms-ListItem").forEach(function (item) { item.classList.remove("is-selected"); item.checked = false; }); const selectedItem = this.querySelector(".ms-ListItem"); selectedItem.classList.add("is-selected"); selectedItem.checked = true; document.querySelector(".not-configured-warning").style.display = "none"; document.getElementById("settings-done").disabled = false; } function sendMessage(message) { Office.context.ui.messageParent(message); } function getParameterByName(name, url) { return new URL(url || window.location.href).searchParams.get(name); } })();Enregistrez vos modifications.
Mettre à jour les paramètres de configuration webapck
Enfin, ouvrez le fichier webpack.config.js qui se trouve dans le répertoire racine du projet et effectuez les étapes suivantes.
Recherchez l’objet
entrydans l’objetconfiget ajoutez une nouvelle entrée pourdialog.dialog: "./src/settings/dialog.js",Une fois que vous avez effectué cette action, le nouvel
entryobjet ressemble à ceci :entry: { polyfill: ["core-js/stable", "regenerator-runtime/runtime"], taskpane: ["./src/taskpane/taskpane.js", "./src/taskpane/taskpane.html"], commands: "./src/commands/commands.js", dialog: "./src/settings/dialog.js", },Recherchez la matrice
pluginsau sein de l’objetconfig. Danspatternsle tableau denew CopyWebpackPluginl'objet, ajoutez de nouvelles entrées pour taskpane.css et dialog.css.{ from: "./src/taskpane/taskpane.css", to: "taskpane.css", }, { from: "./src/settings/dialog.css", to: "dialog.css", },Une fois que vous avez effectué cette action, l’objet
new CopyWebpackPluginse présente comme suit. Notez la légère différence si le complément utilise uniquement le manifeste du complément.new CopyWebpackPlugin({ patterns: [ { from: "./src/taskpane/taskpane.css", to: "taskpane.css", }, { from: "./src/settings/dialog.css", to: "dialog.css", }, { from: "assets/*", to: "assets/[name][ext][query]", }, { from: "manifest*.*", to: "[name]" + "[ext]", transform(content) { if (dev) { return content; } else { return content.toString().replace(new RegExp(urlDev, "g"), urlProd); } }, }, ]}),Dans le même tableau à
pluginsl'intérieur deconfigl'objet, ajoutez ce nouvel objet à la fin du tableau.new HtmlWebpackPlugin({ filename: "dialog.html", template: "./src/settings/dialog.html", chunks: ["polyfill", "dialog"] })Une fois que vous avez effectué cette opération, le nouveau
pluginstableau ressemble à ce qui suit. Notez la légère différence si le complément utilise uniquement le manifeste du complément.plugins: [ new HtmlWebpackPlugin({ filename: "taskpane.html", template: "./src/taskpane/taskpane.html", chunks: ["polyfill", "taskpane"], }), new CopyWebpackPlugin({ patterns: [ { from: "./src/taskpane/taskpane.css", to: "taskpane.css", }, { from: "./src/settings/dialog.css", to: "dialog.css", }, { from: "assets/*", to: "assets/[name][ext][query]", }, { from: "manifest*.*", to: "[name]." + buildType + "[ext]", transform(content) { if (dev) { return content; } else { return content.toString().replace(new RegExp(urlDev, "g"), urlProd); } }, }, ], }), new HtmlWebpackPlugin({ filename: "commands.html", template: "./src/commands/commands.html", chunks: ["polyfill", "commands"], }), new HtmlWebpackPlugin({ filename: "dialog.html", template: "./src/settings/dialog.html", chunks: ["polyfill", "dialog"] }) ],
Récupérer des données à partir de GitHub
Le fichier dialog.js que vous venez de créer spécifie que le module complémentaire doit charger les gists lorsque l'événement de modification se déclenche pour le champ du nom d'utilisateur GitHub. Pour récupérer vos Gists à partir de GitHub, vous allez utiliser l’API GitHub Gists.
Dans le dossier ./src, créez un nouveau sous-dossier nommé helpers.
Dans le dossier ./src/helpers , créez un fichier nommé gist-api.js.
Dans gist-api.js, ajoutez le code suivant pour récupérer vos gists à partir de GitHub et créer la liste des gists.
function getUserGists(user, callback) { const requestUrl = "https://api.github.com/users/" + encodeURIComponent(user) + "/gists"; fetchJson(requestUrl, callback); } function buildGistList(parent, gists, clickFunc) { gists.forEach(function (gist) { const listItem = document.createElement("div"); parent.appendChild(listItem); const radioItem = document.createElement("input"); radioItem.classList.add("ms-ListItem", "is-selectable"); radioItem.type = "radio"; radioItem.name = "gists"; radioItem.tabIndex = 0; radioItem.value = gist.id; listItem.appendChild(radioItem); const descPrimary = document.createElement("span"); descPrimary.classList.add("ms-ListItem-primaryText"); descPrimary.textContent = gist.description; listItem.appendChild(descPrimary); const descSecondary = document.createElement("span"); descSecondary.classList.add("ms-ListItem-secondaryText"); descSecondary.textContent = " - " + buildFileList(gist.files); listItem.appendChild(descSecondary); const updated = new Date(gist.updated_at); const descTertiary = document.createElement("span"); descTertiary.classList.add("ms-ListItem-tertiaryText"); descTertiary.textContent = " - Last updated " + updated.toLocaleString(); listItem.appendChild(descTertiary); listItem.addEventListener("click", clickFunc); }); } function buildFileList(files) { let fileList = ""; for (let file in files) { if (files.hasOwnProperty(file)) { if (fileList.length > 0) { fileList = fileList + ", "; } fileList = fileList + files[file].filename + " (" + files[file].language + ")"; } } return fileList; }Enregistrez vos modifications.
Exécutez la commande suivante pour regénérer le projet.
npm run build
Implémentation d’un bouton sans interface utilisateur
Le bouton Insérer un Gist par défaut de ce complément est un bouton sans interface utilisateur qui appelle une fonction JavaScript, plutôt que d’ouvrir un volet Office comme le font de nombreux boutons de complément. Lorsque vous sélectionnez le bouton Insérer un gist par défaut , la fonction JavaScript correspondante vérifie si le complément a été configuré.
Si le complément a déjà été configuré, la fonction charge le contenu du Gist que vous avez sélectionné par défaut et l’insère dans le corps du message.
Si le complément n’a pas encore été configuré, la boîte de dialogue des paramètres vous invite à entrer un nom d’utilisateur GitHub.
Mettre à jour le fichier de fonction (HTML)
Une fonction appelée par un bouton sans interface utilisateur doit être définie dans le fichier de fonction spécifié par l’élément <FunctionFile> dans le manifeste pour le facteur de formulaire correspondant. Le manifeste de ce complément spécifie https://localhost:3000/commands.html comme fichier de fonction.
Ouvrez le fichier ./src/commands/commands.html et remplacez l’intégralité du contenu par le balisage suivant.
<!doctype html> <html> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> <!-- Office JavaScript API --> <script type="text/javascript" src="https://officeapis.public.onecdn.static.microsoft/1/office.js"></script> <script type="text/javascript" src="../helpers/addin-config.js"></script> <script type="text/javascript" src="../helpers/gist-api.js"></script> </head> <body> <!-- NOTE: The body is empty on purpose. Since functions in commands.js are invoked via a button, there is no UI to render. --> </body> </html>Vous avez peut-être remarqué que le fichier HTML fait référence à un fichier JavaScript, addin-config.js , qui n'existe pas encore. Ce fichier sera créé dans la section Créer un fichier pour gérer les paramètres de configuration, plus loin dans ce tutoriel.
Enregistrez vos modifications.
Mettre à jour le fichier de fonction (JavaScript)
Ouvrez le fichier ./src/commands/commands.js et remplacez tout le contenu par le code suivant. Notez que si la fonction insertDefaultGist détermine que le complément n’a pas encore été configuré, elle ajoute le
?warn=1paramètre à l’URL de la boîte de dialogue. La boîte de dialogue des paramètres affiche ainsi la barre de message définie dans ./src/settings/dialog.html, pour vous indiquer pourquoi la boîte de dialogue s’affiche.let config; let btnEvent; // The onReady function must be run each time a new page is loaded. Office.onReady(); function showError(error) { Office.context.mailbox.item.notificationMessages.replaceAsync( "github-error", { type: "errorMessage", message: error, }, function (result) {} ); } let settingsDialog; function insertDefaultGist(event) { config = getConfig(); // Check if the add-in has been configured. if (config && config.defaultGistId) { // Get the default gist content and insert. try { getGist(config.defaultGistId, function (gist, error) { if (gist) { buildBodyContent(gist, function (content, error) { if (content) { Office.context.mailbox.item.body.setSelectedDataAsync( content, { coercionType: Office.CoercionType.Html }, function (result) { event.completed(); } ); } else { showError(error); event.completed(); } }); } else { showError(error); event.completed(); } }); } catch (err) { showError(err); event.completed(); } } else { // Save the event object so we can finish up later. btnEvent = event; // Not configured yet, display settings dialog with warn=1 to display warning. const url = new URL("dialog.html?warn=1", window.location.href).toString(); const dialogOptions = { width: 20, height: 40, displayInIframe: true }; Office.context.ui.displayDialogAsync(url, dialogOptions, function (result) { settingsDialog = result.value; settingsDialog.addEventHandler(Office.EventType.DialogMessageReceived, receiveMessage); settingsDialog.addEventHandler(Office.EventType.DialogEventReceived, dialogClosed); }); } } // Register the function. Office.actions.associate("insertDefaultGist", insertDefaultGist); function receiveMessage(message) { config = JSON.parse(message.message); setConfig(config, function (result) { settingsDialog.close(); settingsDialog = null; btnEvent.completed(); btnEvent = null; }); } function dialogClosed(message) { settingsDialog = null; btnEvent.completed(); btnEvent = null; }Enregistrez vos modifications.
Créer un fichier pour gérer les paramètres de configuration
Dans le dossier ./src/helpers, créez un fichier nommé addin-config.js et ajoutez le code suivant. Ce code utilise l’objet RoamingSettings pour obtenir et définir les valeurs de configuration.
function getConfig() { const config = {}; config.gitHubUserName = Office.context.roamingSettings.get('gitHubUserName'); config.defaultGistId = Office.context.roamingSettings.get('defaultGistId'); return config; } function setConfig(config, callback) { Office.context.roamingSettings.set('gitHubUserName', config.gitHubUserName); Office.context.roamingSettings.set('defaultGistId', config.defaultGistId); Office.context.roamingSettings.saveAsync(callback); }Enregistrez vos modifications.
Créer de nouvelles fonctions pour traiter les gists
Ouvrez le fichier ./src/helpers/gist-api.js et ajoutez les fonctions suivantes. Veuillez prendre en compte les éléments suivants:
Si l’essentiel contient du code HTML, le complément insère le code HTML tel quel dans le corps du message.
Si le Gist contient Markdown, le complément utilise l’API GitHub Markdown pour convertir le Markdown en HTML, puis insère le code HTML obtenu dans le corps du message.
Si le gist contient autre chose que du HTML ou Markdown, le complément l’insère dans le corps du message comme un extrait de code.
function getGist(gistId, callback) { const requestUrl = "https://api.github.com/gists/" + encodeURIComponent(gistId); fetchJson(requestUrl, callback); } function fetchJson(url, callback) { fetch(url, { headers: { Accept: "application/vnd.github+json" } }) .then(function (response) { if (!response.ok) { throw new Error("GitHub request failed: " + response.status + " " + response.statusText); } return response.json(); }) .then(function (data) { callback(data); }) .catch(function (error) { callback(null, error); }); } function buildBodyContent(gist, callback) { // Find the first non-truncated file in the gist and use it. for (let filename in gist.files) { if (gist.files.hasOwnProperty(filename)) { const file = gist.files[filename]; if (!file.truncated) { switch (file.language) { case "HTML": // Insert as is. callback(file.content); break; case "Markdown": // Use GitHub's renderer so gist Markdown matches github.com. fetch("https://api.github.com/markdown", { method: "POST", headers: { Accept: "application/vnd.github+json", "Content-Type": "application/json", }, body: JSON.stringify({ text: file.content, mode: "gfm" }), }) .then(function (response) { if (!response.ok) { throw new Error("GitHub Markdown request failed: " + response.status + " " + response.statusText); } return response.text(); }) .then(function (html) { callback(html); }) .catch(function (error) { callback(null, error); }); break; default: // Insert contents as a <code> block. const codeElement = document.createElement("code"); codeElement.textContent = file.content; const preElement = document.createElement("pre"); preElement.appendChild(codeElement); callback(preElement.outerHTML); } return; } } } callback(null, "No suitable file found in the gist"); }Enregistrez vos modifications.
Tester le bouton d'insertion par défaut du gist
Si le serveur web local n’est pas déjà en cours d’exécution, exécutez
npm startà partir de l’invite de commandes.Ouvrez Outlook et rédigez un nouveau message.
Dans la fenêtre composer un message, sélectionnez le boutonInsérer gist par défaut. Une boîte de dialogue s’affiche pour vous inviter à définir votre nom d’utilisateur GitHub.
Dans la boîte de dialogue des paramètres, entrez votre nom d’utilisateur GitHub, puis appuyez ou cliquez ailleurs dans la boîte de dialogue pour appeler l’événement de modification . Cette action charge votre liste de gists publics. Sélectionnez un gist comme valeur par défaut, puis sélectionnez Terminé.
Cliquez de nouveau sur le bouton Insérer un gist par défaut. Cette fois, le contenu du Gist par défaut est inséré dans le corps du message.
Remarque
Outlook classique sur Windows : Pour obtenir les derniers paramètres, vous devrez peut-être fermer et rouvrir la fenêtre de rédaction du message.
Implémentation d’un volet de tâches
Le bouton Afficher la liste des éléments essentiels de ce complément ouvre un volet Office et affiche les éléments essentiels de votre complément. Vous pouvez ensuite sélectionner l’un des éléments essentiels à insérer dans le corps du message. Si vous n’avez pas encore configuré le complément, vous serez invité à le faire.
Spécifier le code HTML pour le volet de tâches
Dans le projet que vous avez créé, le code HTML du volet de tâches est spécifié dans le fichier ./src/taskpane/taskpane.html. Ouvrez ce fichier et remplacez l’intégralité de son contenu par le balisage suivant.
<!doctype html> <html> <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>Contoso Task Pane Add-in</title> <!-- Office JavaScript API --> <script type="text/javascript" src="https://officeapis.public.onecdn.static.microsoft/1/office.js"></script> <!-- For more information on Fluent UI, visit https://developer.microsoft.com/fluentui. --> <link rel="stylesheet" href="https://res-1.cdn.office.net/files/fabric-cdn-prod_20230815.002/office-ui-fabric-core/11.1.0/css/fabric.min.css" /> <!-- Template styles --> <link href="taskpane.css" rel="stylesheet" type="text/css" /> </head> <body class="ms-font-l ms-landing-page"> <main class="ms-landing-page__main"> <section class="ms-landing-page__content ms-font-m ms-fontColor-neutralPrimary"> <div id="not-configured" style="display: none"> <div class="centered ms-font-xxl ms-u-textAlignCenter">Welcome!</div> <div class="ms-font-xl" id="settings-prompt"> Please choose the <strong>Settings</strong> icon at the bottom of this window to configure this add-in. </div> </div> <div id="gist-list-container" style="display: none"> <form> <div id="gist-list"></div> </form> </div> <div id="error-display" style="display: none" class="ms-u-borderBase ms-fontColor-error ms-font-m ms-bgColor-error ms-borderColor-error"></div> </section> <button class="ms-Button ms-Button--primary" id="insert-button" tabindex="0" disabled> <span class="ms-Button-label">Insert</span> </button> </main> <footer class="ms-landing-page__footer ms-bgColor-themePrimary"> <div class="ms-landing-page__footer--left"> <img src="../../assets/logo-filled.png" /> <h1 class="ms-font-xl ms-fontWeight-semilight ms-fontColor-white">Git the gist</h1> </div> <div id="settings-icon" class="ms-landing-page__footer--right" aria-label="Settings" tabindex="0"> <i class="ms-Icon enlarge ms-Icon--Settings ms-fontColor-white"></i> </div> </footer> <script type="text/javascript" src="../helpers/addin-config.js"></script> <script type="text/javascript" src="../helpers/gist-api.js"></script> </body> </html>Enregistrez vos modifications.
Spécifier le style CSS pour le volet de tâches
Dans le projet que vous avez créé, le style CSS du volet de tâches est spécifié dans le fichier ./src/taskpane/taskpane.css. Ouvrez ce fichier et remplacez l’intégralité de son contenu par le code suivant.
/* Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See full license in root of repo. */ html, body { width: 100%; height: 100%; margin: 0; padding: 0; overflow: auto; } body { position: relative; font-size: 16px; background-color: #ffffff; } main { height: 100%; overflow-y: auto; } footer { width: 100%; position: relative; bottom: 0; margin-top: 10px; } p, h1, h2, h3, h4, h5, h6 { margin: 0; padding: 0; } ul { padding: 0; } #settings-prompt { margin: 10px 0; } #error-display { padding: 10px; } #insert-button { margin: 0 10px; } .clearfix { display: block; clear: both; height: 0; } .pointerCursor { cursor: pointer; } .invisible { visibility: hidden; } .undisplayed { display: none; } .ms-Icon.enlarge { position: relative; font-size: 20px; top: 4px; } .ms-ListItem-secondaryText, .ms-ListItem-tertiaryText { padding-left: 15px; } .ms-landing-page { display: -webkit-flex; display: flex; -webkit-flex-direction: column; flex-direction: column; -webkit-flex-wrap: nowrap; flex-wrap: nowrap; height: 100%; } .ms-landing-page__main { display: -webkit-flex; display: flex; -webkit-flex-direction: column; flex-direction: column; -webkit-flex-wrap: nowrap; flex-wrap: nowrap; -webkit-flex: 1 1 0; flex: 1 1 0; height: 100%; } .ms-landing-page__content { display: -webkit-flex; display: flex; -webkit-flex-direction: column; flex-direction: column; -webkit-flex-wrap: nowrap; flex-wrap: nowrap; height: 100%; -webkit-flex: 1 1 0; flex: 1 1 0; padding: 20px; } .ms-landing-page__content h2 { margin-bottom: 20px; } .ms-landing-page__footer { display: -webkit-inline-flex; display: inline-flex; -webkit-justify-content: center; justify-content: center; -webkit-align-items: center; align-items: center; } .ms-landing-page__footer--left { transition: background ease 0.1s, color ease 0.1s; display: -webkit-inline-flex; display: inline-flex; -webkit-justify-content: flex-start; justify-content: flex-start; -webkit-align-items: center; align-items: center; -webkit-flex: 1 0 0px; flex: 1 0 0px; padding: 20px; } .ms-landing-page__footer--left:active { cursor: default; } .ms-landing-page__footer--left--disabled { opacity: 0.6; pointer-events: none; cursor: not-allowed; } .ms-landing-page__footer--left--disabled:active, .ms-landing-page__footer--left--disabled:hover { background: transparent; } .ms-landing-page__footer--left img { width: 40px; height: 40px; } .ms-landing-page__footer--left h1 { -webkit-flex: 1 0 0px; flex: 1 0 0px; margin-left: 15px; text-align: left; width: auto; max-width: auto; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } .ms-landing-page__footer--right { transition: background ease 0.1s, color ease 0.1s; padding: 29px 20px; } .ms-landing-page__footer--right:active, .ms-landing-page__footer--right:hover { background: #005ca4; cursor: pointer; } .ms-landing-page__footer--right:active { background: #005ca4; } .ms-landing-page__footer--right--disabled { opacity: 0.6; pointer-events: none; cursor: not-allowed; } .ms-landing-page__footer--right--disabled:active, .ms-landing-page__footer--right--disabled:hover { background: transparent; }Enregistrez vos modifications.
Spécifier le code JavaScript pour le volet de tâches
Dans le projet que vous avez créé, le code JavaScript du volet de tâches est spécifié dans le fichier ./src/taskpane/taskpane.js. Ouvrez ce fichier et remplacez l’intégralité de son contenu par le code suivant.
(function () { "use strict"; let config; let settingsDialog; Office.onReady(function () { function initializeTaskPane() { config = getConfig(); // Check if add-in is configured. if (config && config.gitHubUserName) { // If configured, load the gist list. loadGists(config.gitHubUserName); } else { // Not configured yet. document.getElementById("not-configured").style.display = ""; } // When insert button is selected, build the content and insert into the body. document.getElementById("insert-button").addEventListener("click", function () { const selectedGist = document.querySelector(".ms-ListItem.is-selected"); const gistId = selectedGist && selectedGist.value; getGist(gistId, function (gist, error) { if (gist) { buildBodyContent(gist, function (content, error) { if (content) { Office.context.mailbox.item.body.setSelectedDataAsync( content, { coercionType: Office.CoercionType.Html }, function (result) { if (result.status === Office.AsyncResultStatus.Failed) { showError("Could not insert gist: " + result.error.message); } } ); } else { showError("Could not create insertable content: " + error); } }); } else { showError("Could not retrieve gist: " + error); } }); }); // When the settings icon is selected, open the settings dialog. document.getElementById("settings-icon").addEventListener("click", function () { // Display settings dialog. const url = new URL("dialog.html", window.location.href); if (config) { // If the add-in has already been configured, pass the existing values to the dialog. url.searchParams.set("gitHubUserName", config.gitHubUserName); url.searchParams.set("defaultGistId", config.defaultGistId); } const dialogOptions = { width: 20, height: 40, displayInIframe: true }; Office.context.ui.displayDialogAsync(url.toString(), dialogOptions, function (result) { settingsDialog = result.value; settingsDialog.addEventHandler(Office.EventType.DialogMessageReceived, receiveMessage); settingsDialog.addEventHandler(Office.EventType.DialogEventReceived, dialogClosed); }); }); } if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", initializeTaskPane); } else { initializeTaskPane(); } }); function loadGists(user) { document.getElementById("error-display").style.display = "none"; document.getElementById("not-configured").style.display = "none"; document.getElementById("gist-list-container").style.display = ""; getUserGists(user, function (gists, error) { if (error) { } else { const gistList = document.getElementById("gist-list"); gistList.textContent = ""; buildGistList(gistList, gists, onGistSelected); } }); } function onGistSelected() { document.getElementById("insert-button").disabled = false; document.querySelectorAll(".ms-ListItem").forEach(function (item) { item.classList.remove("is-selected"); item.checked = false; }); const selectedItem = this.querySelector(".ms-ListItem"); selectedItem.classList.add("is-selected"); selectedItem.checked = true; } function showError(error) { document.getElementById("not-configured").style.display = "none"; document.getElementById("gist-list-container").style.display = "none"; const errorDisplay = document.getElementById("error-display"); errorDisplay.textContent = error; errorDisplay.style.display = ""; } function receiveMessage(message) { config = JSON.parse(message.message); setConfig(config, function (result) { settingsDialog.close(); settingsDialog = null; loadGists(config.gitHubUserName); }); } function dialogClosed(message) { settingsDialog = null; } })();Enregistrez vos modifications.
Tester le bouton « Afficher la liste récapitulative »
Si le serveur web local n’est pas déjà en cours d’exécution, exécutez
npm startà partir de l’invite de commandes.Ouvrez Outlook et rédigez un nouveau message.
Dans la fenêtre de rédaction du message, sélectionnez le bouton Afficher la liste des images . Un volet Office s’ouvre.
Dans le volet des tâches, sélectionnez le gistHello World Html, puis sélectionnez insérer pour insérer ce gist dans le corps du message.
Étapes suivantes
Ce didacticiel vous a appris à créer un complément Outlook qui peut être utilisé pour dans le mode composer un message pour insérer du contenu dans le corps d’un message. Pour en savoir plus sur le développement des compléments Outlook, passez à l’article suivant :
Exemples de code
- Didacticiel sur les compléments Outlook terminé : Résultat de l’achèvement de ce didacticiel.