All checks were successful
Build and Deploy WebMCP Stack / build-and-push (push) Successful in 39s
210 lines
5.3 KiB
JavaScript
210 lines
5.3 KiB
JavaScript
// WebMCP Contact Form Tools
|
|
// Implementation based on GoogleChromeLabs webmcp-tools demo
|
|
|
|
// Extend Navigator interface if needed, but in JS we can just check
|
|
if (typeof window !== "undefined") {
|
|
// Assuming modelContext might be added by extension
|
|
}
|
|
|
|
const registeredTools = {
|
|
submitContact: false,
|
|
getContactFormData: false,
|
|
resetContactForm: false,
|
|
};
|
|
|
|
function dispatchAndWait(
|
|
eventName,
|
|
detail = {},
|
|
successMessage = "Action completed successfully",
|
|
timeoutMs = 5000,
|
|
) {
|
|
return new Promise((resolve, reject) => {
|
|
const requestId = Math.random().toString(36).substring(2, 15);
|
|
const completionEventName = `tool-completion-${requestId}`;
|
|
|
|
const timeoutId = setTimeout(() => {
|
|
window.removeEventListener(completionEventName, handleCompletion);
|
|
reject(
|
|
new Error(
|
|
`Timed out waiting for UI to update (requestId: ${requestId})`,
|
|
),
|
|
);
|
|
}, timeoutMs);
|
|
|
|
const handleCompletion = () => {
|
|
clearTimeout(timeoutId);
|
|
window.removeEventListener(completionEventName, handleCompletion);
|
|
resolve(successMessage);
|
|
};
|
|
|
|
window.addEventListener(completionEventName, handleCompletion);
|
|
|
|
// Dispatch original event with requestId
|
|
const event = new CustomEvent(eventName, {
|
|
detail: { ...detail, requestId },
|
|
});
|
|
window.dispatchEvent(event);
|
|
});
|
|
}
|
|
|
|
async function submitContact(params) {
|
|
const data = {
|
|
name: params.name,
|
|
email: params.email,
|
|
subject: params.subject,
|
|
message: params.message,
|
|
};
|
|
|
|
try {
|
|
const response = await fetch("api/send-email.php", {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
"X-Source": "web_form",
|
|
},
|
|
body: JSON.stringify(data),
|
|
});
|
|
|
|
const result = await response.json();
|
|
|
|
if (result.success) {
|
|
return result.message;
|
|
} else {
|
|
throw new Error(result.message || "Failed to send message.");
|
|
}
|
|
} catch (error) {
|
|
throw new Error(`Error submitting contact: ${error.message}`);
|
|
}
|
|
}
|
|
|
|
const submitContactTool = {
|
|
execute: submitContact,
|
|
name: "submitContact",
|
|
description:
|
|
"Submits the contact form with the provided information. All fields are required.",
|
|
inputSchema: {
|
|
type: "object",
|
|
properties: {
|
|
name: {
|
|
type: "string",
|
|
description: "Full name of the person submitting the form",
|
|
minLength: 1,
|
|
maxLength: 100,
|
|
},
|
|
email: {
|
|
type: "string",
|
|
description: "Email address of the person",
|
|
format: "email",
|
|
minLength: 1,
|
|
maxLength: 100,
|
|
},
|
|
subject: {
|
|
type: "string",
|
|
description: "Subject of the message",
|
|
minLength: 1,
|
|
maxLength: 200,
|
|
},
|
|
message: {
|
|
type: "string",
|
|
description: "The message content",
|
|
minLength: 1,
|
|
maxLength: 1000,
|
|
},
|
|
},
|
|
required: ["name", "email", "subject", "message"],
|
|
},
|
|
outputSchema: {
|
|
type: "string",
|
|
description:
|
|
"A message describing the result of the contact form submission",
|
|
},
|
|
annotations: {
|
|
readOnlyHint: "false",
|
|
},
|
|
};
|
|
|
|
function getContactFormData() {
|
|
const form = document.getElementById("contactForm");
|
|
if (!form) {
|
|
return { error: "Contact form not found" };
|
|
}
|
|
const formData = new FormData(form);
|
|
const data = {};
|
|
for (let [key, value] of formData.entries()) {
|
|
data[key] = value;
|
|
}
|
|
return data;
|
|
}
|
|
|
|
const getContactFormDataTool = {
|
|
execute: getContactFormData,
|
|
name: "getContactFormData",
|
|
description: "Retrieves the current data from the contact form fields.",
|
|
inputSchema: {},
|
|
outputSchema: {
|
|
type: "object",
|
|
description: "The current form data or an error message",
|
|
},
|
|
annotations: {
|
|
readOnlyHint: "true",
|
|
},
|
|
};
|
|
|
|
async function resetContactForm() {
|
|
return dispatchAndWait(
|
|
"resetContactForm",
|
|
{},
|
|
"Contact form reset successfully.",
|
|
);
|
|
}
|
|
|
|
const resetContactFormTool = {
|
|
execute: resetContactForm,
|
|
name: "resetContactForm",
|
|
description: "Resets all fields in the contact form to their default values.",
|
|
inputSchema: {},
|
|
outputSchema: {
|
|
type: "string",
|
|
description: "A message confirming the form reset",
|
|
},
|
|
annotations: {
|
|
readOnlyHint: "false",
|
|
},
|
|
};
|
|
|
|
function registerContactFormTools() {
|
|
const modelContext = window.navigator.modelContext;
|
|
if (modelContext) {
|
|
if (!registeredTools.submitContact) {
|
|
modelContext.registerTool(submitContactTool);
|
|
registeredTools.submitContact = true;
|
|
}
|
|
if (!registeredTools.getContactFormData) {
|
|
modelContext.registerTool(getContactFormDataTool);
|
|
registeredTools.getContactFormData = true;
|
|
}
|
|
if (!registeredTools.resetContactForm) {
|
|
modelContext.registerTool(resetContactFormTool);
|
|
registeredTools.resetContactForm = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
function unregisterContactFormTools() {
|
|
const modelContext = window.navigator.modelContext;
|
|
if (modelContext) {
|
|
modelContext.unregisterTool(submitContactTool.name);
|
|
modelContext.unregisterTool(getContactFormDataTool.name);
|
|
modelContext.unregisterTool(resetContactFormTool.name);
|
|
|
|
registeredTools.submitContact = false;
|
|
registeredTools.getContactFormData = false;
|
|
registeredTools.resetContactForm = false;
|
|
}
|
|
}
|
|
|
|
// Auto-register if modelContext is available
|
|
if (typeof window !== "undefined" && window.navigator.modelContext) {
|
|
registerContactFormTools();
|
|
}
|