Come aggiungere funzioni personalizzate al plugin AI di ONLYOFFICE
Il plugin AI di ONLYOFFICE ha introdotto una nuova architettura pensata per gli sviluppatori. Se vuoi estendere le capacità del plugin, ad esempio aggiungendo una funzione AI specifica, non è più necessario modificare un file enorme e monolitico.
Ora il plugin dispone di un workspace dedicato situato nella cartella .dev. Questa guida ti mostrerà esattamente come usare questo workspace per aggiungere una nuova funzione personalizzata.
Come esempio, costruiremo la funzione Describe image per il Document Editor.

Il flusso di sviluppo
Il concetto principale è semplice: lavori in .dev, e uno script genera il codice di produzione.
- .dev/helpers/: Questo è il tuo sandbox. Qui crei nuovi file.
- helpers.js: Questo è il file di produzione che il plugin legge realmente. Non modificarlo direttamente. Viene generato automaticamente.
Passo 1: Scegli l’ambito dell’editor
All’interno di .dev/helpers/ troverai tre cartelle corrispondenti agli editor ONLYOFFICE:
- word/ (Document Editor)
- cell/ (Spreadsheet Editor)
- slide/ (Presentation Editor)
Poiché la nostra funzione describe image è per documenti di testo, lavoreremo in .dev/helpers/word/.
Passo 2: Crea la tua funzione
Crea un nuovo file chiamato describe-image.js all’interno di .dev/helpers/word/.
Il plugin utilizza una classe specifica chiamata RegisteredFunction per definire le capacità. Questa struttura indica all’AI cosa fa la funzione e come richiamarla.
Consiglio: Assicurati che la sintassi sia corretta (attenzione a eventuali parentesi mancanti).
Il codice:
(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;
})();
Passo 3: Compila le tue modifiche
Questo è il passo più importante del nuovo flusso di lavoro. Il plugin non può ancora leggere direttamente il tuo nuovo file, devi eseguire lo script helper per unire il tuo file nella logica principale del plugin.
- Apri il terminale.
- Vai nella directory helpers:
cd .dev/helpers
3. Esegui lo script Python di build:
python3 helpers.py
Lo script helpers.py cercherà nelle cartelle word/, cell/ e slide/, troverà il tuo nuovo describe-image.js e lo unirà nel file principale helpers.js.
Passo 4: Testa la tua funzione
- Ricarica il plugin in ONLYOFFICE.
- Seleziona un’immagine nel tuo documento.
- Chiedi all’AI: “Descrivi questa immagine” o “Scrivi una didascalia per questa.”
L’AI riconoscerà ora la tua nuova funzione personalizzata ed eseguirà la logica che hai scritto.
Crea il tuo account ONLYOFFICE gratuito
Visualizza, modifica e collabora su documenti, fogli, diapositive, moduli e file PDF online.


