Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions lib/ads/campaigns.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export { parseCampaignRequest, parseCampaignPatch, isRefSlug, domainOf, type Cam
import { getOrCreateDefaultOrg } from "@/lib/orgs";
import { generateAdCreatives, cleanSummary, creativesFromCopy, templateCopy, summaryDomain, type AdCreative, type AdSummary } from "@/lib/ads/creative";
import { extractSiteBrand, type SiteBrand } from "@/lib/ads/brand";
import { queueCampaignVideo } from "@/lib/ads/video/jobs";
import { DEFAULT_BID_CREDITS } from "@/lib/ads/pricing";
import { cleanTopics, promoState, type PromoState } from "@/lib/ads/trending";
import { grantTrendingPromo, promoForCampaign, promosForCampaigns } from "@/lib/ads/promos";
Expand Down Expand Up @@ -262,6 +263,34 @@ export async function createCampaignForUrl(input: {
return { ok: false, status: 500, error: creativeError.message };
}

// Queue the five-second pre-roll. This lives here rather than only in the
// dashboard action because this is the shared creator: the public API at
// /api/ads/v1/campaigns runs through it, which is how myna and the rest of
// the automation file ads. With the queueing only in the server action, every
// automatically created campaign got display creatives and no video, and
// nothing said so — the campaign simply had no pre-roll forever.
//
// Same rule as the promo below: a render is an extra output of creating a
// campaign, never a precondition for one. queueCampaignVideo returns null on
// every failure rather than throwing.
await queueCampaignVideo(sb, {
campaignId: campaign.id,
ownerId: userId,
domain,
creatives: generated.creatives.map((c) => ({
format: c.format,
headline: c.headline ?? "",
ctaText: c.ctaText ?? "",
bgColor: c.bgColor ?? null,
fgColor: c.fgColor ?? null,
accentColor: c.accentColor ?? null,
fontFamily: c.fontFamily ?? null,
logoUrl: c.logoUrl ?? null,
imageUrl: c.imageUrl ?? null,
})),
bumpRevision: false,
});

// Turning trending targeting on is what earns the 90 days. Granted after the
// campaign exists so the entitlement can name it, and a failure to grant
// never fails the campaign: the ads still run, they simply bill normally,
Expand Down