import { env } from "cloudflare:workers";
import { invalidateUnread } from "../user-inbox";
import { resolveMentions } from "../mentions";
import { isArtifactsError } from "../git/artifacts";
import { loadRepoById, repoReadableSql } from "../repos";
import { all, first, placeholders, run } from "../db";
import { randomId } from "../crypto";
import { issueParticipants } from "../issues";
import { CAPS } from "../limits";
import { indexRepoCode } from "../code/search-index";
import { deliverEmail, emailTemplates, queueEmail } from "../email";
import { replyAddressFor } from "../email-reply";
import { expandRecipients, planDeliveries } from "../notification-prefs";
import { deliverDirect, sendBudgetedEmail } from "../notify/deliver";
import { emailFooter } from "../notify/prefs";
import { publicUrl } from "./emit";
import type { NotifyMessage, QueueMessage } from "./emit";
import { triggerWorkflowsForEvent } from "../ci/event-triggers";
import { enqueueIntegrationDispatch } from "../integrations/queue";
import { publishRepoEvent } from "../mcp/events";
import { deliverWebhook } from "../webhooks/legacy";
const BASE_RETRY_SECONDS = 15;
const MAX_RETRY_SECONDS = 3600;
function hostOf(url: string): string | null {
try {
return url ? new URL(url).hostname.toLowerCase() : null;
} catch {
return null;
}
}
/** Webhooks may not target the forge's own hostnames (or subdomains), so deliveries cannot reflect internal pages. */
const IPV4_LITERAL = /^\d{1,3}(\.\d{1,3}){3}$/;
const BLOCKED_SUFFIXES = [".localhost", ".local", ".internal", ".workers.dev"];
/**
* Webhook targets must be public hosts: not this forge or its Pages/Sites domains, not IP literals
* (loopback, private, link-local or metadata addresses), not single-label or internal names.