Comment ajouter des fonctionnalités personnalisées au plugin IA d’ONLYOFFICE

3 décembre 2025Par Dasha

Le plugin IA d’ONLYOFFICE a introduit une nouvelle architecture conviviale pour les développeurs. Si vous souhaitez étendre les capacités du plugin, par exemple pour ajouter une fonction IA spécifique, vous n’avez plus besoin de modifier un fichier monolithique volumineux.

À la place, le plugin dispose désormais d’un espace de travail dédié situé dans le dossier .dev. Ce guide vous montrera exactement comment utiliser cet espace de travail pour ajouter une nouvelle fonction personnalisée.

Nous allons créer la fonctionnalité « Décrire l’image » pour l’éditeur de documents à titre d’exemple.

How to add custom features to the ONLYOFFICE AI plugin

Le processus de développement

Le concept de base est simple : vous travaillez dans .dev, et un script génère le code de production.

  • .dev/helpers/ : C’est votre bac à sable. C’est ici que vous créez de nouveaux fichiers.
  • helpers.js : Il s’agit du fichier de production que le plugin lit réellement. Ne le modifiez pas directement. Il est généré automatiquement.

Étape 1 : Choisissez la portée de votre éditeur

Dans .dev/helpers/, vous trouverez trois dossiers correspondant aux éditeurs ONLYOFFICE :

  • word/ (éditeur de documents texte)
  • cell/ (éditeur de feuilles de calcul)
  • slide/ (éditeur de présentations)

Étant donné que notre fonction de description d’image est destinée aux documents texte, nous travaillerons dans .dev/helpers/word/.

Étape 2 : Créez votre propre fonction

Créez un nouveau fichier nommé describe-image.js dans .dev/helpers/word/.

Le plugin utilise une classe spécifique appelée RegisteredFunction pour définir les capacités. Cette structure indique à l’IA ce que fait la fonction et comment l’appeler.

Conseil : assurez-vous que votre syntaxe est correcte (vérifiez qu’il ne manque pas de parenthèses fermantes).

Le code :

(function () {
  let func = new RegisteredFunction({
    name: "describeImage",
    description:
      "Allows users to select an image and generate a meaningful title, description, caption, or alt text for it using AI.",
    // Define parameters so the AI knows what to ask for
    parameters: {
      type: "object",
      properties: {
        prompt: {
          type: "string",
          description:
            "instruction for the AI (e.g., 'Add a short title for this chart.')",
        },
      },
      required: ["prompt"],
    },
    // Provide examples to train the AI on usage
    examples: [
      {
        prompt: "Add a short title for this chart.",
        arguments: { prompt: "Add a short title for this chart." },
      },
      {
        prompt: "Write me a 1–2 sentence description of this photo.",
        arguments: {
          prompt: "Write me a 1–2 sentence description of this photo.",
        },
      },
      {
        prompt: "Generate a descriptive caption for this organizational chart.",
        arguments: {
          prompt:
            "Generate a descriptive caption for this organizational chart.",
        },
      },
      {
        prompt: "Provide accessibility-friendly alt text for this infographic.",
        arguments: {
          prompt:
            "Provide accessibility-friendly alt text for this infographic.",
        },
      },
    ],
  });

   // The actual logic executed inside the editor
  func.call = async function (params) {
    let prompt = params.prompt;

    async function insertMessage(message) {
      Asc.scope._message = String(message || "");
      // 3. Insert the result into the document
      await Asc.Editor.callCommand(function () {
        const msg = Asc.scope._message || "";
        const doc = Api.GetDocument();
        const selected =
          (doc.GetSelectedDrawings && doc.GetSelectedDrawings()) || [];
        if (selected.length > 0) {
          for (let i = 0; i < selected.length; i++) {
            const drawing = selected[i];
            const para = Api.CreateParagraph();
            para.AddText(msg);
            drawing.InsertParagraph(para, "after", true);
          }
        } else {
          const para = Api.CreateParagraph();
          para.AddText(msg);
          let range = doc.GetCurrentParagraph();
          range.InsertParagraph(para, "after", true);
        }
        Asc.scope._message = "";
      }, true);
    }

    try {
    // 1. Get the selected image
      let imageData = await new Promise((resolve) => {
        window.Asc.plugin.executeMethod(
          "GetImageDataFromSelection",
          [],
          function (result) {
            resolve(result);
          }
        );
      });

      if (!imageData || !imageData.src) {
        await insertMessage("Please select a valid image first.");
        return;
      }

      const whiteRectangleBase64 =
        "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8/5+hHgAHggJ/PchI7wAAAABJRU5ErkJggg==";
      if (imageData.src === whiteRectangleBase64) {
        await insertMessage("Please select a valid image first.");
        return;
      }

      let argPrompt = prompt + " (for the selected image)";
      // 2. Send image + prompt to the AI engine
      let requestEngine = AI.Request.create(AI.ActionType.Chat);
      if (!requestEngine) {
        await insertMessage("AI request engine not available.");
        return;
      }

      const allowVision = /(vision|gemini|gpt-4o|gpt-4v|gpt-4-vision)/i;
      if (!allowVision.test(requestEngine.modelUI.name)) {
        await insertMessage(
          "⚠ This model may not support images. Please choose a vision-capable model (e.g. GPT-4V, Gemini, etc.)."
        );
        return;
      }

      await Asc.Editor.callMethod("StartAction", [
        "Block",
        "AI (" + requestEngine.modelUI.name + ")",
      ]);
      await Asc.Editor.callMethod("StartAction", ["GroupActions"]);

      let messages = [
        {
          role: "user",
          content: [
            { type: "text", text: argPrompt },
            {
              type: "image_url",
              image_url: { url: imageData.src, detail: "high" },
            },
          ],
        },
      ];

      let resultText = "";
      await requestEngine.chatRequest(messages, false, async function (data) {
        if (data) {
          resultText += data;
        }
      });

      await Asc.Editor.callMethod("EndAction", ["GroupActions"]);
      await Asc.Editor.callMethod("EndAction", [
        "Block",
        "AI (" + requestEngine.modelUI.name + ")",
      ]);

      Asc.scope.text = resultText || "";

      if (!Asc.scope.text.trim()) {
        await insertMessage(
          "⚠ AI request failed (maybe the model cannot handle images)."
        );
        return;
      }
      await insertMessage(Asc.scope.text);
    } catch (e) {
      try {
        await Asc.Editor.callMethod("EndAction", ["GroupActions"]);
        await Asc.Editor.callMethod("EndAction", [
          "Block",
          "AI (describeImage)",
        ]);
      } catch (ee) {
        /* ignore */
      }
      console.error("describeImage error:", e);
      await insertMessage(
        "An unexpected error occurred while describing the image."
      );
    }
  };

  return func;
})();

Étape 3 : Compilez vos modifications

Il s’agit de l’étape la plus importante du nouveau flux de travail. Le plugin ne peut pas encore lire directement votre nouveau fichier. Vous devez exécuter le script d’aide pour fusionner votre nouveau fichier dans la logique principale du plugin.

  1. Ouvrez votre terminal.
  2. Accédez au répertoire des aides :
cd .dev/helpers

3. Exécutez le script de compilation Python :

python3 helpers.py

Le script helpers.py analysera les dossiers word/, cell/ et slide/, trouvera votre nouveau fichier describe-image.js et le fusionnera dans le fichier principal helpers.js.

Étape 4 : Testez votre fonctionnalité

  1. Rechargez le plugin dans ONLYOFFICE.
  2. Sélectionnez une image dans votre document.
  3. Demandez à l’IA : « Décrivez cette image » ou « Écrivez une légende pour cette image ».

L’IA reconnaîtra désormais votre nouvelle fonction personnalisée et exécutera la logique que vous venez d’écrire.

Créez votre compte ONLYOFFICE gratuit

Affichez, modifiez et coéditez des documents texte, feuilles de calcul, diapositives, formulaires et fichiers PDF en ligne.