/**
* Google Search Script
* This script performs a Google search and extracts results including AI answers,
* organic results, related questions, and related searches
*/
// Export metadata about the script
export const metadata = {
name: "google-search",
version: "1.0.0",
description:
"Search Google and extract AI answers, organic results, PAA questions, and related searches",
inputSchema: {
type: "object",
properties: {
query: {
type: "string",
description: "The search query/keyword",
default: "chatgpt"
},
language: {
type: "string",
description: "Language code for search results (e.g., en, ja, zh-CN)",
default: "en"
},
page: {
type: "number",
description: "Page index (0 for first page, 1 for second, etc.)",
default: 0,
minimum: 0
}
},
required: ["query"]
},
type: "puppeteer",
defaultTimeout: 30000,
fsEnabled: false,
networkEnabled: true,
domainsAllowed: ["google.com"],
};
// Export the main run method
// The page object is automatically provided in the context
export const main = async function (input) {
try {
// Note: "page" here refers to the Puppeteer browser page object
const page = global.page;
if (!page) {
throw new Error("Page object is not available");
}
const keyword = input?.query || "chatgpt";
const language = input?.language || "en";
const pageIndex = (input?.page !== undefined && input?.page !== null) ? input.page : 0;
const start = pageIndex * 10;
const url = `https://www.google.com/search?q=${encodeURIComponent(keyword)}&hl=${language}&start=${start}`;
await page.goto(url, {waitUntil: "networkidle2"});
await page.waitForSelector("div#search");
const data = await page.evaluate(() => {
const result = {
aiAnswer: null,
results: [],
questions: [],
relatedSearches: []
};
const answer = document.querySelector(
"#search div[data-attrid]:not([data-attrid=\"title\"]):not([data-attrid=\"subtitle\"])"
);
if (answer) {
result.aiAnswer = answer.innerText.trim();
}
const anchors = document.querySelectorAll("#search a h3");
anchors.forEach((h3) => {
const a = h3.closest("a");
if (a && a.href && h3.innerText.trim()) {
const snippetNode = a.parentElement?.parentElement?.querySelector(
"div[data-sncf] span, div:not([class]) span"
);
const snippet = snippetNode ? snippetNode.innerText.trim() : "";
result.results.push({
title: h3.innerText.trim(),
link: a.href,
snippet
});
}
});
return result;
});
return {
result: {
content: [{
type: "text",
text: JSON.stringify(data, null, 2),
}]
}
};
} catch (error) {
return {
error: {
message: error.message || "Unknown error occurred",
}
};
}
};