Upload Session to Drive Skill
This skill uploads the current Claude Code session (.jsonl file) to Google Drive with automatic authentication and optional sharing.
⚠️ Prerequisites
REQUIRED: Google Drive API credentials file must be present before using this skill.
Location: data_sources/google_drive/credentials/credentials.json
Setup instructions: See data_sources/google_drive/00_README.md for:
- Creating OAuth2 credentials in Google Cloud Console
- Enabling Google Drive API
- Downloading and placing credentials.json file
First-time authentication:
- On first use, browser will open for Google OAuth authorization
- After authorization, token is cached in
credentials/token.pickle - Subsequent uses are fully automatic (no browser)
★ Insight ─────────────────────────────────────
How It Works:
- Auto-detects session ID - Uses $CLAUDE_SESSION_ID or finds latest session
- Auto-authentication - First run opens browser, subsequent runs use cached token
- Upload & Share - Uploads to Drive and optionally shares with email
- Returns link - Provides shareable Google Drive link
─────────────────────────────────────────────────
Quick Start: How This Skill Works
🔐 First Time Use
What happens:
- User invokes skill: "Upload this session to Drive"
- Skill checks if token exists
- If no token → Opens browser for Google OAuth
- User authorizes Google Drive access
- Token saved for future use
- Session uploaded to Drive
- Link returned to user
Note: Browser will open ONLY on first use. After that, fully automatic!
⚡ Subsequent Uses
What happens:
- User invokes skill: "Upload this session to Drive"
- Skill uses cached token (no browser!)
- Session uploaded immediately
- Link returned
📤 Usage Examples
Example 1: Simple upload
User: "Upload this session to Drive"
Claude: [Executes skill]
🔐 First time: Opening browser for Google Drive authentication...
✅ Authenticated!
📤 Uploading session f7a79beb-138f-4858-8edc-f18ffa076bf0...
✅ Session uploaded!
🔗 https://drive.google.com/file/d/1lKMV0oeGz29GWAFbQlYACSbPSOT2NlZU/view
Example 2: Upload and share
User: "Upload this session and share with colleague@improvado.io"
Claude: [Executes skill with email]
✅ Authenticated (using cached token)
📤 Uploading and sharing...
✅ Shared with colleague@improvado.io as reader
📧 Email notification sent
🔗 https://drive.google.com/file/d/1lKMV0oeGz29GWAFbQlYACSbPSOT2NlZU/view
Example 3: Upload to specific folder
User: "Upload to our team sessions folder"
Claude: [If folder ID configured]
✅ Uploading to "Claude Sessions" folder...
🔗 https://drive.google.com/file/d/...
Implementation
When this skill is invoked:
-
Get session ID:
- Check environment variable:
$CLAUDE_SESSION_ID - If not set, find most recent session in
~/.claude/projects/
- Check environment variable:
-
Find session file:
- Session files located in:
~/.claude/projects/-Users-as-Desktop-Impro-tcs-chrome-extension/ - File format:
{session_id}.jsonl
- Session files located in:
-
Authenticate Google Drive:
from data_sources.google_drive.drive_client import GoogleDriveClient client = GoogleDriveClient() # Check if first time token_path = f"{client.credentials_path}/token.pickle" if not os.path.exists(token_path): print("🔐 First time: Opening browser for Google Drive authentication...") print("Token will be saved for future automatic use.\n") # Authenticate (opens browser if needed, or reuses token) client.authenticate() -
Upload session:
# Simple upload result = client.upload_file(session_file_path) # Or upload and share if email_provided: result = client.upload_and_share( session_file_path, email, role='reader', notification_message=f'Claude Code session shared: {session_id}' ) -
Return result:
print(f"✅ Session uploaded!") print(f"🔗 {result['webViewLink']}") if email_provided: print(f"📧 Shared with {email}")
User Interaction Flow
Scenario 1: First Time User
User: "Upload this session to Drive"
Claude: I'll upload the current session to Google Drive.
[Invokes skill]
Skill Output:
🔐 First time: Opening browser for Google Drive authentication...
Token will be saved for future automatic use.
[Browser opens with Google OAuth page]
User: [Authorizes access in browser]
Skill Output:
✅ Token saved!
✅ Google Drive authenticated!
📤 Uploading session f7a79beb-138f-4858-8edc-f18ffa076bf0...
✅ File uploaded: f7a79beb-138f-4858-8edc-f18ffa076bf0.jsonl
🔗 Link: https://drive.google.com/file/d/1lKMV0oeGz29GWAFbQlYACSbPSOT2NlZU/view
Claude: ✅ Session successfully uploaded to Google Drive!
You can access it here: https://drive.google.com/file/d/1lKMV0oeGz29GWAFbQlYACSbPSOT2NlZU/view
The authentication token has been saved, so future uploads will be automatic (no browser required).
Scenario 2: Repeat User (Token Exists)
User: "Upload this session and share with team@improvado.io"
Claude: I'll upload and share this session with team@improvado.io.
[Invokes skill]
Skill Output:
✅ Authenticated with Google Drive API
📤 Uploading and sharing session...
✅ File uploaded: f7a79beb-138f-4858-8edc-f18ffa076bf0.jsonl
✅ File shared with team@improvado.io as reader
🔗 Link: https://drive.google.com/file/d/1lKMV0oeGz29GWAFbQlYACSbPSOT2NlZU/view
Claude: ✅ Session uploaded and shared!
- Link: https://drive.google.com/file/d/1lKMV0oeGz29GWAFbQlYACSbPSOT2NlZU/view
- Shared with: team@improvado.io (reader access)
- Email notification sent: Yes
They can now view the complete conversation history.
Python Script Reference
Location: .claude/skills/upload-session-to-drive/upload_session.py
Key Functions:
def get_current_session_id() -> str:
"""Get current session ID from env or latest file"""
def find_session_file(session_id: str) -> Path:
"""Find session .jsonl file in ~/.claude/projects/"""
def upload_to_drive(session_file: Path, email: str = None) -> dict:
"""Upload session to Drive with optional sharing"""
Session File Structure
Session files are stored in:
~/.claude/projects/{encoded-project-path}/{session-id}.jsonl
Example:
~/.claude/projects/-Users-as-Desktop-Impro-tcs-chrome-extension/f7a79beb-138f-4858-8edc-f18ffa076bf0.jsonl
File format: JSON Lines (one JSON object per line)
- Line 1: Session metadata (cwd, sessionId, version, gitBranch)
- Lines 2+: Conversation messages (user, assistant, tool_result)
Authentication Details
Credentials location:
data_sources/google_drive/credentials/
├── credentials.json # OAuth2 client (from Google Cloud Console)
└── token.pickle # Auto-generated auth token (cached)
First time setup (automatic):
- Skill calls
client.authenticate() - No token found → Opens browser
- User authorizes via Google OAuth page
- Token saved to
token.pickle - Future runs use cached token
Token refresh:
- Token auto-refreshes when expired
- Uses refresh_token from OAuth flow
- No browser needed for refresh
Sharing Options
Role types:
reader- Can view file (default)writer- Can edit filecommenter- Can add comments
Notification:
- Email notification sent automatically
- Custom message supported
- Recipient gets link in email
Configuration (Optional)
Create .claude/skills/upload-session-to-drive/config.json:
{
"shared_folder_id": "folder_id_here",
"default_role": "reader",
"default_recipients": ["team@improvado.io"]
}
Troubleshooting
Issue: "Credentials file not found"
Cause: Missing credentials.json from Google Cloud Console
Solution:
- Go to https://console.cloud.google.com/
- Create project → Enable Google Drive API
- Create OAuth 2.0 Client ID (Desktop app)
- Download as
credentials.json - Place in
data_sources/google_drive/credentials/credentials.json
Issue: Browser doesn't open for auth
Cause: Port blocked or redirect URI misconfigured
Solution:
- Check Google Cloud Console → OAuth Client → Redirect URIs
- Add
http://localhost:*(or specific port) - Try again
Issue: "Token expired" error
Cause: Token corrupted or refresh failed
Solution:
# Delete token to re-authenticate
rm data_sources/google_drive/credentials/token.pickle
# Run skill again - browser will open for new auth
Issue: Session file not found
Cause: Session ID incorrect or file doesn't exist
Solution:
- Check current session ID:
/get_session_id - Verify file exists:
ls ~/.claude/projects/-Users-as-Desktop-Impro-tcs-chrome-extension/ - Use correct session ID
Security Notes
- ✅ Token stored locally (not in git)
- ✅ Token auto-refreshes securely
- ✅ OAuth2 standard authentication
- ✅ Session files readable as text (JSONL format)
- ⚠️ Anyone with Drive link can view (if shared)
- ⚠️ Session files contain full conversation history
Related Tools
Session management:
/get_session_id- Get current session IDdata_sources/claude_code/21_universal_session_resume.py- Resume sessionsdata_sources/claude_code/22_list_all_sessions.py- List all sessions
Drive operations:
data_sources/google_drive/drive_client.py- Core Drive client- Can manually upload:
python drive_client.py(example in__main__)
Technical Details
Dependencies:
google-authgoogle-auth-oauthlibgoogle-api-python-client
OAuth Scopes:
https://www.googleapis.com/auth/drive- Full Drive access
File MIME type:
.jsonlfiles detected asapplication/jsonortext/plain
Upload method:
- Uses
MediaFileUploadwithresumable=True - Supports large files via chunked upload