Fix MAX attachment send and self push echoes

This commit is contained in:
sevenhill
2026-07-04 23:46:00 +03:00
parent 8e16469d94
commit b022218a1f
3 changed files with 216 additions and 30 deletions
+125 -18
View File
@@ -2610,7 +2610,6 @@ async function clearSidebarSearch(p) {
input.dispatchEvent(new Event("change", { bubbles: true }));
}
}).catch(() => {});
await p.keyboard.press("Escape").catch(() => {});
await p.waitForTimeout(150);
}
@@ -2830,7 +2829,7 @@ async function openDomChatByExternalId(p, externalChatId) {
const rect = match.button.getBoundingClientRect();
return {
opened: false,
x: Math.round(rect.left + Math.min(rect.width - 8, Math.max(8, rect.width * 0.35))),
x: Math.round(rect.left + Math.min(rect.width - 8, Math.max(8, rect.width * 0.50))),
y: Math.round(rect.top + rect.height / 2)
};
}, {
@@ -3659,7 +3658,13 @@ async function uploadAttachmentFile(p, path, caption) {
return false;
}
await waitForAttachmentPreview(p, 8000);
await p.waitForTimeout(2000);
const previewReady = await waitForAttachmentPreview(p, 10000);
console.info(`[send/attachment] file selected; previewReady=${previewReady} url=${p.url()}`);
if (!previewReady) {
return false;
}
if (caption.trim()) {
await fillComposerText(p, caption.trim(), false);
await p.waitForTimeout(300);
@@ -3731,6 +3736,90 @@ async function attachFileViaUploadButton(p, filePath) {
return false;
}
try {
const fileChooserPromise = p.waitForEvent("filechooser", { timeout: 800 }).catch(() => null);
await p.mouse.click(point.x, point.y);
const fileChooser = await fileChooserPromise;
if (fileChooser) {
await fileChooser.setFiles(filePath);
return true;
}
return await attachFileViaMenuItem(p, filePath);
} catch {
return false;
}
}
async function attachFileViaMenuItem(p, filePath) {
const preferMedia = /\.(jpe?g|png|webp|gif|heic|mp4|mov|webm)$/i.test(filePath);
const deadline = Date.now() + 3500;
let point = null;
while (Date.now() < deadline && !point) {
point = await p.evaluate(({ preferMedia }) => {
const isVisible = (element) => {
if (!(element instanceof HTMLElement)) return false;
const style = window.getComputedStyle(element);
const rect = element.getBoundingClientRect();
return style.visibility !== "hidden" &&
style.display !== "none" &&
rect.width > 0 &&
rect.height > 0 &&
rect.bottom >= 0 &&
rect.right >= 0 &&
rect.top <= window.innerHeight &&
rect.left <= window.innerWidth;
};
const cleanText = (value) => String(value || "")
.replace(/\s+/g, " ")
.trim()
.toLowerCase();
const menuItems = Array.from(document.querySelectorAll("[role='menuitem'], button[class*='actionsMenuItem' i]"))
.filter((element) => !element.disabled && isVisible(element))
.filter((element) => !element.closest?.("[data-testid='composer'], [class*='composer' i]"))
.map((element) => {
const rect = element.getBoundingClientRect();
const text = cleanText([
element.getAttribute("aria-label"),
element.getAttribute("title"),
element.getAttribute("data-testid"),
element.className,
element.innerText,
element.textContent
].join(" "));
const media = /photo|video|media|\u0444\u043e\u0442\u043e|\u0432\u0438\u0434\u0435\u043e/.test(text);
const file = /file|\u0444\u0430\u0439\u043b/.test(text);
return { element, rect, text, media, file };
})
.filter((item) => item.media || item.file)
.sort((a, b) => {
const aPreferred = preferMedia ? a.media : a.file;
const bPreferred = preferMedia ? b.media : b.file;
return Number(bPreferred) - Number(aPreferred) ||
a.rect.top - b.rect.top ||
a.rect.left - b.rect.left;
});
const item = menuItems[0]?.element || null;
if (!item) {
return null;
}
const rect = item.getBoundingClientRect();
return {
x: Math.round(rect.left + rect.width / 2),
y: Math.round(rect.top + rect.height / 2)
};
}, { preferMedia }).catch(() => null);
if (!point) {
await p.waitForTimeout(100);
}
}
if (!point) {
return false;
}
try {
const fileChooserPromise = p.waitForEvent("filechooser", { timeout: 5000 }).catch(() => null);
await p.mouse.click(point.x, point.y);
@@ -3767,6 +3856,31 @@ async function waitForAttachmentPreview(p, timeoutMs = 8000) {
const rect = element.getBoundingClientRect();
return rect.left > window.innerWidth * 0.30 && rect.top > window.innerHeight * 0.45;
};
const isPendingUploadSurface = (element) => {
if (element.closest?.("aside, [class*='messageWrapper' i], [class*='bubble' i], [class*='message--' i], [role='listitem']")) {
return false;
}
const surface = element.closest?.([
"[data-testid='composer']",
"[class*='composer' i]",
"[role='dialog']",
"[class*='modal' i]",
"[class*='preview' i]",
"[class*='attach' i]",
"[class*='upload' i]",
"[class*='file' i]",
"[class*='media' i]"
].join(","));
if (surface) {
return true;
}
const rect = element.getBoundingClientRect();
return rect.left > window.innerWidth * 0.38 &&
rect.top > window.innerHeight * 0.55 &&
rect.bottom > window.innerHeight * 0.70;
};
const previewSelectors = [
"[class*='preview' i]",
"[class*='attach' i]",
@@ -3778,24 +3892,17 @@ async function waitForAttachmentPreview(p, timeoutMs = 8000) {
];
const hasPreview = previewSelectors
.flatMap((selector) => Array.from(document.querySelectorAll(selector)))
.some((element) => isVisible(element) && bottomArea(element));
const sendButton = Array.from(document.querySelectorAll("button, [role='button']"))
.some((button) => {
if (button.disabled || !isVisible(button) || !bottomArea(button)) {
.some((element) => isVisible(element) && bottomArea(element) && isPendingUploadSurface(element));
const hasFileName = Array.from(document.querySelectorAll("div, span, p"))
.some((element) => {
if (!isVisible(element) || !bottomArea(element) || !isPendingUploadSurface(element)) {
return false;
}
const text = [
button.getAttribute("aria-label"),
button.getAttribute("title"),
button.getAttribute("data-testid"),
button.className,
button.innerText,
button.textContent
].join(" ").toLowerCase();
return /send|submit|\u043e\u0442\u043f\u0440\u0430\u0432/.test(text);
const text = String(element.innerText || element.textContent || "").trim();
return /\.(jpe?g|png|webp|gif|heic|mp4|mov|webm|mp3|ogg|m4a|wav|pdf|docx?|xlsx?|zip|rar|7z)\b/i.test(text);
});
return hasPreview || sendButton;
return hasPreview || hasFileName;
}).catch(() => false);
if (ready) {
@@ -3805,7 +3912,7 @@ async function waitForAttachmentPreview(p, timeoutMs = 8000) {
await p.waitForTimeout(250);
}
console.warn("[send/attachment] attachment preview was not detected before sending; continuing with send attempt");
console.warn("[send/attachment] attachment preview was not detected before sending");
return false;
}