Files
geo/apps/browser-extension/entrypoints/content.ts
T

162 lines
4.7 KiB
TypeScript
Raw Normal View History

import { browser } from "wxt/browser";
import { defineContentScript } from "wxt/utils/define-content-script";
2026-04-12 09:56:18 +08:00
import { syncDoubaoMonitoringRuntimeStateFromPage } from "../src/monitoring-adapters/doubao-state";
type PublisherRequestMessage = {
source: "geo-admin";
type: "geo.publisher.request";
requestId: string;
action: "ping" | "detectPlatforms" | "registerInstallation" | "bindAccount" | "publishArticle";
payload?: unknown;
};
2026-04-12 09:56:18 +08:00
type MonitoringRequestMessage = {
source: "geo-admin";
type: "geo.monitoring.request";
requestId: string;
action: "ping" | "detectPlatforms" | "syncHeartbeat" | "runCycle" | "kickoffCycle" | "getState";
};
type BackgroundSuccessResponse = {
ok: true;
data: unknown;
};
type BackgroundErrorResponse = {
ok: false;
error?: string;
};
2026-04-12 09:56:18 +08:00
type RuntimeSyncMessage = {
type: "geo.monitoring.runtime.sync";
platform: "doubao";
};
function isExtensionContextInvalidatedError(error: unknown): boolean {
const message =
typeof error === "string"
? error
: typeof error === "object" && error !== null && "message" in error && typeof error.message === "string"
? error.message
: String(error ?? "");
const normalized = message.toLowerCase();
return normalized.includes("extension context invalidated") || normalized.includes("context invalidated");
}
function isBackgroundResponse(value: unknown): value is BackgroundSuccessResponse | BackgroundErrorResponse {
return typeof value === "object" && value !== null && "ok" in value;
}
2026-04-12 09:56:18 +08:00
function registerDoubaoRuntimeSync(): void {
const hostname = window.location.hostname;
if (hostname !== "doubao.com" && hostname !== "www.doubao.com" && !hostname.endsWith(".doubao.com")) {
return;
}
const sync = () => {
void syncDoubaoMonitoringRuntimeStateFromPage().catch((error) => {
if (isExtensionContextInvalidatedError(error)) {
return;
}
console.warn("[geo-monitoring] failed to sync doubao runtime state", error);
});
};
sync();
window.addEventListener("pageshow", sync);
document.addEventListener("visibilitychange", () => {
if (!document.hidden) {
sync();
}
});
window.setInterval(sync, 15000);
}
export default defineContentScript({
matches: ["http://*/*", "https://*/*"],
main() {
2026-04-12 09:56:18 +08:00
registerDoubaoRuntimeSync();
browser.runtime.onMessage.addListener((message: RuntimeSyncMessage, _sender, sendResponse) => {
if (!message || message.type !== "geo.monitoring.runtime.sync" || message.platform !== "doubao") {
return undefined;
}
void syncDoubaoMonitoringRuntimeStateFromPage()
.then(() => {
sendResponse({ ok: true });
})
.catch((error) => {
sendResponse({
ok: false,
error: error instanceof Error ? error.message : "monitoring_runtime_sync_failed",
});
});
return true;
});
window.addEventListener("message", async (event: MessageEvent<PublisherRequestMessage | MonitoringRequestMessage>) => {
if (
event.source !== window ||
!event.data ||
(event.data.type !== "geo.publisher.request" && event.data.type !== "geo.monitoring.request")
) {
return;
}
if (event.data.source !== "geo-admin") {
return;
}
2026-04-12 09:56:18 +08:00
const { requestId, action } = event.data;
const payload = "payload" in event.data ? event.data.payload : undefined;
try {
const response = await browser.runtime.sendMessage({
2026-04-12 09:56:18 +08:00
type: event.data.type,
action,
payload,
});
const data = isBackgroundResponse(response)
? (() => {
if (!response.ok) {
throw new Error(response.error || "publisher_plugin_unknown_error");
}
return response.data;
})()
: response;
if (typeof data === "undefined") {
throw new Error("publisher_plugin_empty_response");
}
window.postMessage(
{
source: "geo-extension",
2026-04-12 09:56:18 +08:00
type: event.data.type === "geo.publisher.request" ? "geo.publisher.response" : "geo.monitoring.response",
requestId,
success: true,
data,
},
window.location.origin,
);
} catch (error) {
window.postMessage(
{
source: "geo-extension",
2026-04-12 09:56:18 +08:00
type: event.data.type === "geo.publisher.request" ? "geo.publisher.response" : "geo.monitoring.response",
requestId,
success: false,
error: error instanceof Error ? error.message : "publisher_plugin_unknown_error",
},
window.location.origin,
);
}
});
},
});