# YouTube Data API Setup Guide

This guide provides step-by-step instructions for setting up YouTube Data API integration for managing video comments.

---

## Table of Contents

1. [Overview](#overview)
2. [Prerequisites](#prerequisites)
3. [Google Cloud Console Setup](#google-cloud-console-setup)
4. [Environment Configuration](#environment-configuration)
5. [OAuth Redirect URI Configuration](#oauth-redirect-uri-configuration)
6. [Permissions & Scopes](#permissions--scopes)
7. [Development vs Production](#development-vs-production)
8. [Troubleshooting](#troubleshooting)

---

## Overview

**API Version:** YouTube Data API v3
**API Service Name:** `youtube`
**API Version:** `v3`
**Auth Method:** OAuth 2.0

### Features Supported
- Fetch channel videos
- Read video comments
- Reply to comments
- Automatic token refresh

---

## Prerequisites

- A Google account with a YouTube channel
- Access to [Google Cloud Console](https://console.cloud.google.com/)
- Videos uploaded to your YouTube channel

---

## Google Cloud Console Setup

### Step 1: Create a New Project

1. Navigate to [Google Cloud Console](https://console.cloud.google.com/)
2. Click on the project selector dropdown at the top
3. Click **"New Project"**
4. Enter project details:
   - **Project Name:** e.g., "PX360 YouTube Integration"
   - **Organization:** Select your organization (if applicable)
5. Click **"Create"**
6. Select your new project

### Step 2: Enable YouTube Data API

1. Go to **"APIs & Services"** → **"Library"**
2. Search for **"YouTube Data API v3"**
3. Click on it and click **"Enable"**

### Step 3: Configure OAuth Consent Screen

1. Go to **"APIs & Services"** → **"OAuth consent screen"**
2. Select **"External"** user type (unless you have a Google Workspace account)
3. Click **"Create"**
4. Fill in the required fields:
   - **App Name:** Your application name
   - **User Support Email:** Your support email
   - **App Logo:** Upload your logo
   - **Application Home Page:** Your website URL
   - **Authorized Domains:** Your domain(s)
   - **Developer Contact Email:** Your email
5. Click **"Save and Continue"**
6. Add scopes (click "Add or Remove Scopes"):
   - `https://www.googleapis.com/auth/youtube.readonly`
   - `https://www.googleapis.com/auth/youtube.force-ssl`
7. Click **"Save and Continue"**
8. Add test users (for development)
9. Click **"Save and Continue"**

### Step 4: Create OAuth 2.0 Credentials

1. Go to **"APIs & Services"** → **"Credentials"**
2. Click **"Create Credentials"** → **"OAuth client ID"**
3. Select **"Web application"**
4. Configure:
   - **Name:** e.g., "PX360 YouTube Client"
   - **Authorized JavaScript origins:**
     - Development: `http://127.0.0.1:8000`
     - Production: `https://yourdomain.com`
   - **Authorized redirect URIs:**
     - Development: `http://127.0.0.1:8000/social/callback/YT/`
     - Production: `https://yourdomain.com/social/callback/YT/`
5. Click **"Create"**
6. **Download the JSON file** - This is your credentials file

### Step 5: Save Credentials File

1. Rename the downloaded JSON file to `yt_client_secrets.json`
2. Place it in your project's `secrets/` directory:
   ```
   your_project/
   ├── secrets/
   │   ├── gmb_client_secrets.json
   │   └── yt_client_secrets.json
   └── ...
   ```

The JSON file structure:
```json
{
  "web": {
    "client_id": "xxxxx.apps.googleusercontent.com",
    "project_id": "your-project-id",
    "auth_uri": "https://accounts.google.com/o/oauth2/auth",
    "token_uri": "https://oauth2.googleapis.com/token",
    "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
    "client_secret": "your-client-secret",
    "redirect_uris": ["http://127.0.0.1:8000/social/callback/YT/"]
  }
}
```

---

## Environment Configuration

### Django Settings (settings.py)

```python
# YouTube Data API Configuration
import os
from pathlib import Path

BASE_DIR = Path(__file__).resolve().parent.parent.parent

# YouTube API Configuration
YOUTUBE_CLIENT_SECRETS_FILE = BASE_DIR / 'secrets' / 'yt_client_secrets.json'
YOUTUBE_REDIRECT_URI = 'https://yourdomain.com/social/callback/YT/'
```

### Environment Variables (.env)

```env
YOUTUBE_REDIRECT_URI=https://yourdomain.com/social/callback/YT/
```

---

## OAuth Redirect URI Configuration

The redirect URI must match exactly what's configured in Google Cloud Console.

### Development

```
http://127.0.0.1:8000/social/callback/YT/
http://localhost:8000/social/callback/YT/
```

### Production

```
https://yourdomain.com/social/callback/YT/
```

> ⚠️ **Note:** Google accepts both HTTP and HTTPS for `localhost`/`127.0.0.1`, but production must use HTTPS.

---

## Permissions & Scopes

The application requests the following OAuth scopes:

| Scope | Description | Required |
|-------|-------------|----------|
| `https://www.googleapis.com/auth/youtube.readonly` | Read channel, videos, comments | ✅ Yes |
| `https://www.googleapis.com/auth/youtube.force-ssl` | Post replies to comments | ✅ Yes |

### Code Reference

```python
# apps/social/utils/youtube.py
YOUTUBE_SCOPES = [
    'https://www.googleapis.com/auth/youtube.readonly',
    'https://www.googleapis.com/auth/youtube.force-ssl'
]

YOUTUBE_API_SERVICE_NAME = 'youtube'
YOUTUBE_API_VERSION = 'v3'
```

---

## Development vs Production

### Development Setup

| Setting | Value |
|---------|-------|
| `YOUTUBE_REDIRECT_URI` | `http://127.0.0.1:8000/social/callback/YT/` |
| Protocol | HTTP allowed for localhost |
| App Verification | Not required for testing |
| User Access | Only added test users |

### Production Setup

| Setting | Value |
|---------|-------|
| `YOUTUBE_REDIRECT_URI` | `https://yourdomain.com/social/callback/YT/` |
| Protocol | **HTTPS required** |
| App Verification | Required for sensitive scopes |
| User Access | Any Google account |

### Google App Verification

For production, if your app requests sensitive scopes (like YouTube), you may need verification:

1. Submit your app for verification in Google Cloud Console
2. Provide a demo video showing the integration
3. Wait for Google's review (can take several days)

---

## YouTube API Quotas

YouTube Data API has strict quota limits:

### Default Quota

| Resource | Daily Quota |
|----------|-------------|
| Total API Units | 10,000 units/day |
| Search | 100 units/request |
| Videos List | 1 unit/request |
| Comments List | 1 unit/request |
| Comments Insert | 50 units/request |

### Quota Calculation Example

```
Daily sync of 50 videos:
- 50 video list requests = 50 units
- Comments for each video (avg 5 pages) = 250 units
- Total: ~300 units/day (well within limits)
```

### Requesting Higher Quota

If you need more quota:

1. Go to Google Cloud Console → **"IAM & Admin"** → **"Quotas"**
2. Filter by "YouTube Data API"
3. Click **"Edit Quotas"**
4. Submit a request explaining your use case

---

## Troubleshooting

### Common Error: "Access Denied - Requested client not authorized"

**Cause:** OAuth consent screen not configured or app not verified.

**Solution:**
1. Ensure OAuth consent screen is properly configured
2. Add user as a test user if app is in testing mode
3. Submit app for verification if needed for production

---

### Common Error: "Invalid Grant"

**Cause:** Authorization code expired or already used.

**Solution:**
- Authorization codes are single-use and expire quickly
- Ensure your code handles the callback immediately
- Check that redirect URI matches exactly

---

### Common Error: "Quota Exceeded"

**Cause:** Daily API quota exceeded.

**Solution:**
1. Check quota usage in Google Cloud Console
2. Optimize API calls to use fewer units
3. Request quota increase if needed
4. Wait for quota reset (daily at midnight Pacific Time)

---

### Common Error: "Comments Disabled for This Video"

**Cause:** Video owner has disabled comments.

**Solution:**
- This is expected behavior for some videos
- Application handles this gracefully
- Skip videos with disabled comments

---

### Common Error: "No Uploads Playlist ID Found"

**Cause:** Channel has no uploaded videos or credentials incomplete.

**Solution:**
1. Ensure the YouTube channel has uploaded videos
2. Check that the uploads playlist ID is stored in credentials
3. Re-authenticate if needed

---

### Common Error: "Token Refresh Failed"

**Cause:** Refresh token expired or revoked.

**Solution:**
- Google OAuth tokens expire after 6 months of inactivity
- User must re-authenticate
- Ensure `offline` access type is requested

---

### Common Error: "Comment Thread Not Found"

**Cause:** Comment was deleted or video was removed.

**Solution:**
- Application handles 404 errors gracefully
- Skip deleted comments during sync

---

## API Rate Limits & Best Practices

### Rate Limits

| Resource | Limit |
|----------|-------|
| Requests per second | Varies by endpoint |
| Daily quota units | 10,000 (default) |

### Best Practices

1. **Batch Requests:** Minimize API calls by fetching multiple items
2. **Pagination:** Use page tokens for large result sets
3. **Caching:** Cache video/comment data locally
4. **Delta Sync:** Only fetch new comments since last sync
5. **Error Handling:** Gracefully handle quota and rate limit errors

---

## Token Lifecycle

| Token Type | Lifetime | Notes |
|------------|----------|-------|
| Access Token | ~1 hour | Short-lived |
| Refresh Token | 6 months | Expires with inactivity |
| Offline Access | Indefinite | Requires `offline` access type |

> ⚠️ **Note:** If a refresh token expires, the user must re-authenticate.

---

## Verification

After setup, verify the integration:

1. Ensure `yt_client_secrets.json` is in place
2. Navigate to `/social/` in your application
3. Click "Connect YouTube"
4. Authorize with your Google account
5. Verify your channel is detected
6. Check if videos are fetched
7. Test replying to a comment

### Testing in Django Shell

```python
from apps.social.services.youtube import YouTubeService
from apps.social.models import SocialAccount

account = SocialAccount.objects.filter(platform='YT').first()

# Test getting videos
videos = YouTubeService.fetch_user_videos(account)
print(f"Found {len(videos)} videos")

# Test getting comments
if videos:
    video_id = videos[0]['id']
    comments = YouTubeService.fetch_video_comments(account, video_id)
    print(f"Found {len(comments)} comments for video {video_id}")
```

---

## Sharing Credentials with Google Business

If you're already using Google Business API, you can use the same Google Cloud project:

1. Both APIs use OAuth 2.0 with similar configuration
2. You can create separate OAuth clients or use the same one
3. The `secrets/` directory can contain multiple credential files:
   - `gmb_client_secrets.json` (Google Business)
   - `yt_client_secrets.json` (YouTube)

### Single OAuth Client for Both

You can use a single OAuth client for both services:

1. Enable both APIs in Google Cloud Console
2. Request scopes for both services during OAuth
3. Use the same credentials file
4. Update settings to point to the same file:

```python
# If using single OAuth client
GOOGLE_CLIENT_SECRETS_FILE = BASE_DIR / 'secrets' / 'google_client_secrets.json'
GMB_CLIENT_SECRETS_FILE = GOOGLE_CLIENT_SECRETS_FILE
YOUTUBE_CLIENT_SECRETS_FILE = GOOGLE_CLIENT_SECRETS_FILE
```

---

## Support Resources

- [YouTube Data API Documentation](https://developers.google.com/youtube/v3)
- [YouTube API Code Samples](https://developers.google.com/youtube/v3/code_samples)
- [OAuth 2.0 for Web Server Applications](https://developers.google.com/identity/protocols/oauth2/web-server)
- [YouTube API Quota Calculator](https://developers.google.com/youtube/v3/determine_quota_cost)
- [Google Cloud Console Support](https://support.google.com/cloud/)

---

*Last Updated: February 2026*
*API Version: YouTube Data API v3*