YouTube Data API Integration
Relevant source files
The following files were used as context for generating this wiki page:- apps/api/src/features/youtube/youtube.service.ts
- apps/api/src/features/youtube/youtube.router.ts
- packages/types/src/youtube/youtube-video.type.ts
- packages/types/src/youtube/youtube-comment.type.ts
- apps/web/src/features/youtube/views/channel-analyzer.view.tsx
- apps/web/src/features/search/views/video-search.view.tsx
- apps/web/src/features/youtube/components/video-detail.component.tsx
The YouTube Data API integration is a core backend module responsible for fetching channel, video, and comment data from the YouTube Data API v3. It serves as the primary data source for the application's analysis features, providing the raw data needed for both user-facing displays and the AI Analysis module.
This system is encapsulated within the apps/api package, specifically in the youtube feature directory. It exposes its functionality to the frontend via a set of tRPC procedures. The integration is designed with a clear separation of concerns: a service layer (youtube.service.ts) handles all business logic and communication with the external API, while a router layer (youtube.router.ts) defines the API endpoints and their inputs.
Architecture Overview
The integration follows a classic client-server model. The React frontend (apps/web) initiates data requests through tRPC calls. These calls are handled by the Express backend (apps/api), which then communicates with the YouTube Data API v3 to fetch the required information. The data is then formatted into shared TypeScript types and returned to the client.
The following diagram illustrates the high-level data flow from the user interface to the YouTube API and back.
Backend Service
All interactions with the YouTube Data API are managed by the YoutubeService. This service uses the fetch API to make requests to https://www.googleapis.com/youtube/v3 and requires a YOUTUBE_API_KEY from the environment variables.
Sources: apps/api/src/features/youtube/youtube.service.ts:5, 8
Key Functions
resolveChannelId(identifier: string)
This function is responsible for converting a user-provided identifier (which can be a channel handle like @username or a channel name) into a canonical YouTube Channel ID (e.g., UC...). It employs a multi-step fallback strategy.
- Check if ID: It first checks if the identifier already matches the format of a channel ID.
- Resolve Handle: If not, it attempts to resolve it as a channel handle by calling the
/channelsendpoint with theforHandleparameter. - Search Fallback: If the handle resolution fails, it falls back to using the
/searchendpoint to find a channel that matches the identifier string.
The following flowchart shows the logic for resolving a channel identifier.
fetchChannelVideos(channelId: string)
This function retrieves the top 20 videos for a given channel, ordered by view count. It's a two-step process:
- It first calls the
/searchendpoint to get a list of video IDs belonging to the channel. - It then takes these video IDs and makes a single call to the
/videosendpoint with thepartparameter set tosnippet,statisticsto fetch detailed information for all videos at once.
Sources: apps/api/src/features/youtube/youtube.service.ts:66-118
fetchVideoComments(videoId: string)
Fetches the top 20 comments for a specific video by calling the /commentThreads endpoint. It requests plain text format for the comments.
Sources: apps/api/src/features/youtube/youtube.service.ts:175-214
searchVideos(query: string, sortBy: VideoSortOption, maxResults: number)
Performs a global search for videos on YouTube. It maps the internal sortBy option to the order parameter supported by the YouTube API (date, viewCount, relevance). For sorting by likes or comments, which the API's order parameter doesn't support directly on search, the function fetches results ordered by relevance and then performs the sorting locally.
Sources: apps/api/src/features/youtube/youtube.service.ts:233-315
API Endpoints (tRPC Router)
The youtubeRouter exposes the service functions as tRPC procedures. All procedures are protected, meaning they require authentication. Inputs are validated using Zod schemas.
Sources: apps/api/src/features/youtube/youtube.router.ts
| Procedure | Input Schema | Description | Service Function Called |
|---|---|---|---|
resolveChannel | z.object({ identifier: z.string().min(1) }) | Resolves a channel handle/name to a channel ID. | resolveChannelId |
getVideos | z.object({ channelId: z.string().min(1) }) | Fetches top videos for a given channel ID. | fetchChannelVideos |
getComments | z.object({ videoId: z.string().min(1) }) | Fetches top comments for a given video ID. | fetchVideoComments |
searchVideos | videoSearchParamsSchema | Searches videos globally with sorting options. | searchVideos |
Sources: apps/api/src/features/youtube/youtube.router.ts:10-47
Data Models
The data structures for YouTube entities are defined in the @repo/types shared package, ensuring type consistency between the frontend and backend.
YouTubeVideo
This type represents a single YouTube video with its associated metadata and statistics.
| Field | Type | Description |
|---|---|---|
id | string | The unique ID of the video. |
title | string | The video title. |
description | string | The video description. |
thumbnailUrl | string | URL of the high-resolution thumbnail. |
viewCount | string | Total number of views. |
likeCount | string | Total number of likes. |
commentCount | string | Total number of comments. |
publishedAt | string | ISO 8601 date string of when the video was published. |
channelTitle | string | The title of the channel that published the video. |
Sources: packages/types/src/youtube/youtube-video.type.ts
YouTubeComment
This type represents a top-level comment on a video.
| Field | Type | Description |
|---|---|---|
id | string | The unique ID of the comment thread. |
authorDisplayName | string | The display name of the comment author. |
authorProfileImageUrl | string | URL of the author's profile image. |
textDisplay | string | The plain text content of the comment. |
likeCount | string | The number of likes the comment has received. |
publishedAt | string | ISO 8601 date string of when the comment was published. |
Sources: packages/types/src/youtube/youtube-comment.type.ts
Frontend Integration
The apps/web frontend consumes the YouTube data via the tRPC client. Components like ChannelAnalyzerView, VideoSearchView, and VideoDetail use hooks and utility functions to trigger the backend procedures and manage the data fetching state.
The following sequence diagram shows a typical interaction, where a user enters a channel handle in the ChannelAnalyzerView and the application fetches and displays the channel's videos.
A similar flow occurs in VideoDetail.component.tsx to load comments for a specific video using the youtube.getComments procedure.
Sources: apps/web/src/features/youtube/components/video-detail.component.tsx:30-38
Conclusion
The YouTube Data API integration is a well-structured and essential module that powers the core functionality of the Adfluens application. By centralizing API interactions in a dedicated backend service and exposing them through a type-safe tRPC API, the system maintains a clean architecture that is easy to maintain and extend. The use of shared types ensures data consistency across the full stack, from the external API to the user's screen.