# Google Drive API Setup Guide This guide will walk you through setting up Google Drive API with OAuth2 for your Streamflix application. ## 📋 Overview The error you're experiencing (`invalid_grant - Token has been expired or revoked`) means your **refresh token is no longer valid**. This can happen due to: - Token expired (happens after 7 days if app is in testing mode and not used) - Token was manually revoked - OAuth consent screen settings changed - User changed their password - App credentials were regenerated **About Refresh Tokens**: Refresh tokens can be permanent OR temporary depending on your Google Cloud Project configuration: - ✅ **Production apps with verified domain**: Refresh tokens don't expire - âš ī¸ **Testing mode apps**: Tokens expire after 7 days if not used - âš ī¸ **Sensitive/Restricted scopes**: May require re-authentication periodically --- ## 🚀 Complete Setup Process ### Step 1: Create Google Cloud Project 1. Go to [Google Cloud Console](https://console.cloud.google.com/) 2. Click **"Select a project"** → **"New Project"** 3. Enter project name: `streamflix-api` (or any name) 4. Click **"Create"** 5. Wait for project creation and select it ### Step 2: Enable Google Drive API 1. In the Google Cloud Console, go to **"APIs & Services"** → **"Library"** 2. Search for **"Google Drive API"** 3. Click on it and press **"Enable"** 4. Wait for the API to be enabled ### Step 3: Configure OAuth Consent Screen 1. Go to **"APIs & Services"** → **"OAuth consent screen"** 2. Choose **"External"** user type (unless you have a Google Workspace) 3. Click **"Create"** #### Fill in App Information: - **App name**: `Streamflix API` - **User support email**: Your email - **App logo**: (Optional) - **Application home page**: `http://localhost:5119` (or your domain) - **Authorized domains**: Leave empty for localhost testing - **Developer contact information**: Your email 4. Click **"Save and Continue"** #### Add Scopes: 1. Click **"Add or Remove Scopes"** 2. Manually add these scopes: ``` https://www.googleapis.com/auth/drive.file https://www.googleapis.com/auth/drive.appdata ``` Or use restricted scope (full access): ``` https://www.googleapis.com/auth/drive ``` 3. Click **"Update"** → **"Save and Continue"** #### Test Users (IMPORTANT for Testing mode): 1. Click **"Add Users"** 2. Add YOUR Google account email (the one that owns the Drive folders) 3. Click **"Save and Continue"** 4. Review and click **"Back to Dashboard"** > âš ī¸ **CRITICAL - Refresh Token Expiration**: > > **Testing Mode** (default): Refresh tokens **EXPIRE after 7 days** when using Drive scopes > > **To get PERMANENT refresh tokens, you have 2 options:** > > 1. **Option 1 - Publish to Production (Recommended for Development)**: > - Go to OAuth consent screen > - Click **"Publish App"** button > - Change status from "Testing" to **"In Production"** > - ✅ Tokens become permanent > - âš ī¸ Limited to 100 users (fine for personal/dev projects) > - â„šī¸ No verification needed unless using sensitive scopes > 2. **Option 2 - Keep Testing Mode**: > - You MUST re-authenticate every 7 days > - Only use this during active development > - Add your email as a test user (see above) ### Step 4: Create OAuth2 Credentials 1. Go to **"APIs & Services"** → **"Credentials"** 2. Click **"+ Create Credentials"** → **"OAuth client ID"** 3. Choose **"Web application"** 4. Fill in: - **Name**: `Streamflix OAuth Client` - **Authorized JavaScript origins**: ``` http://localhost:5119 ``` - **Authorized redirect URIs**: ``` http://localhost:5119/google-drive/oauth2callback ``` 5. Click **"Create"** 6. 🎉 You'll get your **Client ID** and **Client Secret** - save these! ```env GOOGLE_OAUTH2_CLIENT_ID="YOUR_CLIENT_ID_HERE.apps.googleusercontent.com" GOOGLE_OAUTH2_CLIENT_SECRET="YOUR_CLIENT_SECRET_HERE" ``` ### Step 5: Set Up Redirect URI in Your App Update your `.env` file: ```env GOOGLE_OAUTH2_CLIENT_ID="paste_your_client_id_here" GOOGLE_OAUTH2_CLIENT_SECRET="paste_your_client_secret_here" GOOGLE_OAUTH2_REDIRECT_URI="http://localhost:5119/google-drive/oauth2callback" # Leave REFRESH_TOKEN empty for now - we'll get it in the next step GOOGLE_OAUTH2_REFRESH_TOKEN="" ``` ### Step 6: Get Folder IDs from Google Drive 1. Go to [Google Drive](https://drive.google.com/) 2. Create your folder structure: ``` 📁 Streamflix ├── 📁 images ├── 📁 videos └── 📁 documents ``` 3. For each folder: - Open the folder - Look at the URL: `https://drive.google.com/drive/folders/FOLDER_ID_HERE` - Copy the **FOLDER_ID_HERE** part 4. Update your `.env`: ```env GOOGLE_DRIVE_FOLDER_MAIN="main_folder_id" GOOGLE_DRIVE_FOLDER_IMAGES="images_folder_id" GOOGLE_DRIVE_FOLDER_VIDEOS="videos_folder_id" GOOGLE_DRIVE_FOLDER_DOCUMENTS="documents_folder_id" ``` ### Step 7: Authenticate and Get Refresh Token 1. Start your application: ```bash npm run start:dev ``` 2. Open your browser and visit: ``` http://localhost:5119/google-drive/auth ``` 3. You'll be redirected to Google's consent screen: - Sign in with YOUR Google account (the one with the Drive folders) - Click **"Allow"** to grant permissions - You should see a success message with your refresh token 4. Copy the refresh token and update your `.env`: ```env GOOGLE_OAUTH2_REFRESH_TOKEN="1//0g...your_refresh_token_here" ``` 5. Restart your application for changes to take effect --- ## 🔑 Complete Environment Variables Your final `.env` should look like: ```env # Google OAuth2 Credentials GOOGLE_OAUTH2_CLIENT_ID="329990410282-xxxxx.apps.googleusercontent.com" GOOGLE_OAUTH2_CLIENT_SECRET="GOCSPX-xxxxx" GOOGLE_OAUTH2_REDIRECT_URI="http://localhost:5119/google-drive/oauth2callback" GOOGLE_OAUTH2_REFRESH_TOKEN="1//0g...your_new_refresh_token" # Google Drive Folders GOOGLE_DRIVE_FOLDER_MAIN="1bZoXVD_cCaXeAivVO3WGiiHHoOC4_t9s" GOOGLE_DRIVE_FOLDER_IMAGES="1lBHfbnMYG6W0F4aOc6pS7-aMRIE5JwEf" GOOGLE_DRIVE_FOLDER_VIDEOS="1tVkcbiI1nQM2CpaDNYEvOcwo1RS4Rs58" GOOGLE_DRIVE_FOLDER_DOCUMENTS="139gWgAJ8-tpt8c96LvWP5M7pdO1agOnZ" ``` --- ## 🔧 Troubleshooting ### Error: "invalid_grant - Token has been expired or revoked" **Solution**: Your refresh token is invalid. Follow Step 7 again to get a new one. ### Error: "Access Not Configured" **Solution**: Make sure Google Drive API is enabled (Step 2). ### Error: "redirect_uri_mismatch" **Solution**: 1. Check that the redirect URI in your `.env` exactly matches the one in Google Cloud Console 2. Both must be identical (including `http://` vs `https://` and trailing slashes) ### Refresh Token Expires After 7 Days **Root Cause**: Your app is in "Testing" publishing status, which causes tokens to expire after 7 days when using Drive scopes. **Solution - Make Tokens Permanent**: 1. Go to [OAuth Consent Screen](https://console.cloud.google.com/apis/credentials/consent) 2. Click **"Publish App"** button 3. Confirm to change status to **"In Production"** 4. ✅ Done! Your tokens are now permanent (no verification needed) 5. Re-authenticate ONE more time to get a permanent token **Note**: You can have up to 100 users without verification. For 100+ users, you'll need to submit for verification. ### Can't Find OAuth Callback Route **Solution**: Make sure you have the OAuth callback controller endpoint. Check [google-drive.controller.ts](src/shared/modules/upload/google-drive/google-drive.controller.ts) for `/auth` and `/oauth2callback` routes. --- ## đŸŽ¯ Quick Fix for Your Current Issue Since your current refresh token is expired, do this NOW: 1. **Visit**: `http://localhost:5119/google-drive/auth` 2. **Sign in** with your Google account 3. **Copy** the new refresh token 4. **Update** `.env` with the new token: ```env GOOGLE_OAUTH2_REFRESH_TOKEN="new_token_here" ``` 5. **Restart** your application --- ## 📚 Understanding Refresh Tokens ### How Long Do Refresh Tokens Last? | App Status | Token Lifetime | Notes | | ----------------------------- | -------------------------------- | ---------------------------------------------- | | **Testing Mode** | âš ī¸ **7 days** (for Drive scopes) | Must re-authenticate every 7 days | | **Production (Not Verified)** | ✅ **Permanent\*** | Limited to 100 users, but tokens don't expire! | | **Production & Verified** | ✅ **Permanent\*** | No user limit, no expiration | \*Permanent tokens can still be revoked if: - User changes password - User manually revokes access - Suspicious activity detected - OAuth credentials regenerated ### Best Practices 1. **For Development (Recommended)**: - ✅ **Publish app to "In Production" status** (even without verification) - This gives you permanent tokens immediately - Limited to 100 users, which is fine for personal/dev use - No more token expiration hassles! 2. **For Public/Commercial Production**: - Publish to production - Submit for verification (required for 100+ users) - Implement token refresh logic (already in your code) - Store tokens securely - Monitor for `invalid_grant` errors and prompt re-authentication 3. **Only Use Testing Mode If**: - You're actively developing and changing scopes frequently - You don't mind re-authenticating every 7 days - You're just experimenting 4. **Only Use Testing Mode If**: - You're actively developing and changing scopes frequently - You don't mind re-authenticating every 7 days - You're just experimenting 5. **Security**: - Never commit `.env` to version control - Use environment variables in production - Rotate credentials if exposed --- ## ✅ Verification After setup, test your integration: ```bash # Make a test upload request curl -X POST http://localhost:5119/your-upload-endpoint \ -F "file=@test-image.jpg" ``` You should see logs like: ``` [GoogleDriveService] ✅ OAuth2 client initialized with refresh token [GoogleDriveService] Uploading file: test-image.jpg [GoogleDriveService] ✅ Upload successful ``` --- ## 🆘 Need More Help? - [Google OAuth2 Documentation](https://developers.google.com/identity/protocols/oauth2) - [Google Drive API Documentation](https://developers.google.com/drive/api/guides/about-sdk) - [OAuth Playground](https://developers.google.com/oauthplayground/) - Test OAuth flows --- ## 📝 Summary 1. ✅ Create Google Cloud Project 2. ✅ Enable Google Drive API 3. ✅ Configure OAuth Consent Screen 4. ✅ **Publish App to Production** (to make tokens permanent) 5. ✅ Create OAuth2 Credentials 6. ✅ Get Drive Folder IDs 7. ✅ Authenticate and get Refresh Token 8. ✅ Update `.env` with all credentials 9. ✅ Restart application Your refresh token is **stored in `.env`** and will be used automatically to generate new access tokens. **Pro Tip**: Publish your app to "In Production" status (even without verification) to make refresh tokens permanent! This works for up to 100 users without any verification process. --- ## đŸŽ¯ Quick Summary: Testing vs Production | Setting | Testing Mode | Production Mode (Not Verified) | Production Mode (Verified) | | ------------------------- | ----------------------- | ------------------------------ | -------------------------- | | **Token Lifetime** | âš ī¸ 7 days | ✅ Permanent | ✅ Permanent | | **User Limit** | 100 test users | 100 users | Unlimited | | **Verification Required** | No | No | Yes | | **Use Case** | Active development only | Personal/Dev projects | Public apps | | **Recommended For You** | ❌ No | ✅ **YES** | Only if 100+ users | **Bottom Line**: Click "Publish App" to switch from Testing → Production. Your tokens become permanent immediately, no verification needed (unless you exceed 100 users). | **Recommended For You** | ❌ No | ✅ **YES** | Only if 100+ users | **Bottom Line**: Click "Publish App" to switch from Testing → Production. Your tokens become permanent immediately, no verification needed (unless you exceed 100 users).