diff --git a/.github/workflows/sync-shorts.yml b/.github/workflows/sync-shorts.yml deleted file mode 100644 index 4b9581763..000000000 --- a/.github/workflows/sync-shorts.yml +++ /dev/null @@ -1,42 +0,0 @@ -name: Sync YouTube Shorts to Sanity - -on: - workflow_dispatch: - inputs: - dataset: - description: "Target Sanity Dataset" - required: true - default: "production" - type: choice - options: - - production - - dev - schedule: - - cron: "30 6 * * *" - -jobs: - sync-shorts: - runs-on: ubuntu-latest - environment: production - - steps: - - uses: actions/checkout@v4 - - - uses: pnpm/action-setup@v4 - - - uses: actions/setup-node@v4 - with: - node-version-file: ".nvmrc" - cache: "pnpm" - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Sync Shorts from Automated Videos - run: node scripts/sync-shorts-from-automated-videos.mjs - env: - SANITY_AUTH_TOKEN: ${{ secrets.SANITY_AUTH_TOKEN }} - SANITY_API_WRITE_TOKEN: ${{ secrets.SANITY_API_WRITE_TOKEN }} - SANITY_STUDIO_PROJECT_ID: ${{ vars.SANITY_STUDIO_PROJECT_ID || 'hfh83o0w' }} - SANITY_STUDIO_DATASET: ${{ inputs.dataset || 'production' }} - YOUTUBE_API_KEY: ${{ secrets.YOUTUBE_API_KEY }} diff --git a/apps/sanity/extract.json b/apps/sanity/extract.json index b18ae4394..d3376aa8b 100644 --- a/apps/sanity/extract.json +++ b/apps/sanity/extract.json @@ -702,36 +702,6 @@ } } }, - { - "type": "type", - "name": "automatedVideo.reference", - "value": { - "type": "object", - "attributes": { - "_ref": { - "type": "objectAttribute", - "value": { - "type": "string" - } - }, - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "reference" - } - }, - "_weak": { - "type": "objectAttribute", - "value": { - "type": "boolean" - }, - "optional": true - } - }, - "dereferencesTo": "automatedVideo" - } - }, { "type": "type", "name": "category.reference", @@ -812,13 +782,6 @@ }, "optional": true }, - "description": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, "youtube": { "type": "objectAttribute", "value": { @@ -826,13 +789,6 @@ }, "optional": true }, - "shortVideoUrl": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, "thumbnail": { "type": "objectAttribute", "value": { @@ -888,14 +844,6 @@ }, "optional": true }, - "sourceAutomatedVideo": { - "type": "objectAttribute", - "value": { - "type": "inline", - "name": "automatedVideo.reference" - }, - "optional": true - }, "publishedAt": { "type": "objectAttribute", "value": { @@ -910,52 +858,6 @@ }, "optional": true }, - "statistics": { - "type": "objectAttribute", - "value": { - "type": "object", - "attributes": { - "youtube": { - "type": "objectAttribute", - "value": { - "type": "object", - "attributes": { - "viewCount": { - "type": "objectAttribute", - "value": { - "type": "number" - }, - "optional": true - }, - "likeCount": { - "type": "objectAttribute", - "value": { - "type": "number" - }, - "optional": true - }, - "commentCount": { - "type": "objectAttribute", - "value": { - "type": "number" - }, - "optional": true - }, - "favoriteCount": { - "type": "objectAttribute", - "value": { - "type": "number" - }, - "optional": true - } - } - }, - "optional": true - } - } - }, - "optional": true - }, "categories": { "type": "objectAttribute", "value": { @@ -1281,6 +1183,36 @@ } } }, + { + "type": "type", + "name": "automatedVideo.reference", + "value": { + "type": "object", + "attributes": { + "_ref": { + "type": "objectAttribute", + "value": { + "type": "string" + } + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "reference" + } + }, + "_weak": { + "type": "objectAttribute", + "value": { + "type": "boolean" + }, + "optional": true + } + }, + "dereferencesTo": "automatedVideo" + } + }, { "name": "videoAnalytics", "type": "document", diff --git a/apps/sanity/functions/sync-youtube-analytics/index.ts b/apps/sanity/functions/sync-youtube-analytics/index.ts index 897580c7e..04d73730b 100644 --- a/apps/sanity/functions/sync-youtube-analytics/index.ts +++ b/apps/sanity/functions/sync-youtube-analytics/index.ts @@ -70,69 +70,13 @@ export const handler = scheduledEventHandler(async ({ context }) => { useCdn: false, }); - // Step 0: Sync any published automatedVideo Shorts into standalone `_type == "short"` documents - const autoShortDocs = await client.fetch< - Array<{ - _id: string; - _createdAt: string; - title: string; - slug?: { current?: string }; - youtubeShortId: string; - shortUrl?: string; - hook?: string; - }> - >( - `*[_type == "automatedVideo" && defined(youtubeShortId) && !(_id in path("drafts.**"))]{ - _id, - _createdAt, - title, - slug, - youtubeShortId, - shortUrl, - "hook": script.hook - }`, - ); - - for (const autoShort of autoShortDocs) { - const shortId = `short-${autoShort.youtubeShortId}`; - const slugCurrent = - autoShort.slug?.current || - autoShort.title - .toLowerCase() - .replace(/[^a-z0-9]+/g, "-") - .replace(/(^-|-$)/g, "") - .slice(0, 90); - await client - .createIfNotExists({ - _id: shortId, - _type: "short", - title: autoShort.title, - slug: { _type: "slug", current: slugCurrent }, - description: autoShort.hook || undefined, - youtube: `https://www.youtube.com/shorts/${autoShort.youtubeShortId}`, - shortVideoUrl: autoShort.shortUrl || undefined, - sourceAutomatedVideo: { - _type: "reference", - _ref: autoShort._id, - }, - publishedAt: autoShort._createdAt, - duration: 60, - }) - .catch((err) => { - console.warn( - `[Sync YouTube Analytics] Could not createIfNotExists short ${shortId}:`, - err, - ); - }); - } - - // Query all posts, podcasts, and shorts with YouTube URLs + // Query all posts and podcasts with YouTube URLs console.log( `[Sync YouTube Analytics] Fetching documents with YouTube URLs in project ${projectId}, dataset ${dataset}...`, ); const docs = await client.fetch( - `*[_type in ["post", "podcast", "short"] && (defined(youtube) || defined(listenLinks.youtube)) && !(_id in path("drafts.**"))]{ + `*[_type in ["post", "podcast"] && (defined(youtube) || defined(listenLinks.youtube)) && !(_id in path("drafts.**"))]{ _id, _type, title, diff --git a/apps/sanity/schemas/documents/short.ts b/apps/sanity/schemas/documents/short.ts index ee25af8b2..e7a294842 100644 --- a/apps/sanity/schemas/documents/short.ts +++ b/apps/sanity/schemas/documents/short.ts @@ -27,25 +27,12 @@ export default defineType({ }, validation: (rule) => rule.required(), }), - defineField({ - name: "description", - title: "Description / Hook", - type: "text", - rows: 3, - description: "Short hook or summary for SEO/AEO and card previews", - }), defineField({ name: "youtube", title: "YouTube", type: "string", description: "YouTube Shorts video ID or URL", }), - defineField({ - name: "shortVideoUrl", - title: "Direct MP4 Video URL", - type: "url", - description: "Direct Sanity CDN or R2 MP4 URL for native vertical video playback", - }), defineField({ name: "thumbnail", title: "Thumbnail", @@ -62,13 +49,6 @@ export default defineType({ to: [{ type: "podcast" }], description: "Long-form episode this Short was clipped from", }), - defineField({ - name: "sourceAutomatedVideo", - title: "Source Automated Video", - type: "reference", - to: [{ type: "automatedVideo" }], - description: "Automated video pipeline run that produced this Short", - }), defineField({ name: "publishedAt", title: "Published At", @@ -80,24 +60,6 @@ export default defineType({ type: "number", description: "Duration in seconds", }), - defineField({ - name: "statistics", - title: "Statistics", - type: "object", - fields: [ - defineField({ - name: "youtube", - title: "YouTube Statistics", - type: "object", - fields: [ - defineField({ name: "viewCount", title: "Views", type: "number" }), - defineField({ name: "likeCount", title: "Likes", type: "number" }), - defineField({ name: "commentCount", title: "Comments", type: "number" }), - defineField({ name: "favoriteCount", title: "Favorites", type: "number" }), - ], - }), - ], - }), defineField({ name: "categories", title: "Categories", diff --git a/apps/sanity/schemas/singletons/engineConfig.ts b/apps/sanity/schemas/singletons/engineConfig.ts index ad1f2c9aa..9c570a9f3 100644 --- a/apps/sanity/schemas/singletons/engineConfig.ts +++ b/apps/sanity/schemas/singletons/engineConfig.ts @@ -327,8 +327,8 @@ export default defineType({ type: 'string', fieldset: 'aiGeneration', description: - 'The Google Gemini model used for script generation and content analysis (e.g., gemini-2.5-flash, gemini-2.5-pro)', - initialValue: 'gemini-2.5-flash', + 'The Google Gemini model used for script generation and content analysis', + initialValue: 'gemini-2.0-flash', }), defineField({ name: 'infographicModel', diff --git a/apps/sanity/schemas/singletons/pipelineConfig.ts b/apps/sanity/schemas/singletons/pipelineConfig.ts index cea163aec..2d0ab77f8 100644 --- a/apps/sanity/schemas/singletons/pipelineConfig.ts +++ b/apps/sanity/schemas/singletons/pipelineConfig.ts @@ -10,8 +10,8 @@ export default defineType({ name: "geminiModel", title: "Gemini Model", type: "string", - description: "The Google Gemini model used for script generation and content analysis (e.g., gemini-2.5-flash, gemini-2.5-pro)", - initialValue: "gemini-2.5-flash", + description: "The Google Gemini model used for script generation and content analysis (e.g., gemini-2.0-flash, gemini-2.5-pro)", + initialValue: "gemini-2.0-flash", }), defineField({ name: "elevenLabsVoiceId", diff --git a/apps/site/src/components/Header.astro b/apps/site/src/components/Header.astro index 7adc07387..008031a3c 100644 --- a/apps/site/src/components/Header.astro +++ b/apps/site/src/components/Header.astro @@ -5,13 +5,7 @@ import ThemeToggle from "./ThemeToggle.astro"; import SearchModal from "./SearchModal.astro"; const settings = await Astro.locals.sanity.loadQuery(settingsQuery); -const rawNavLinks = settings?.navLinks ?? []; -const navLinks = rawNavLinks.some((link) => link?.path === "/shorts") - ? rawNavLinks - : [ - ...rawNavLinks, - { _key: "shorts-nav", path: "/shorts", title: "Shorts", sideOnly: false }, - ]; +const navLinks = settings?.navLinks ?? []; // The Next header split these across a desktop