import streamlit as st
import googleapiclient.discovery
import google.generativeai as genai
from datetime import datetime, timedelta
# Configure page
st.set_page_config(
page_title="YouTube Content Strategist",
page_icon="đ",
layout="wide",
initial_sidebar_state="expanded"
)
# Custom CSS
st.markdown("""
""", unsafe_allow_html=True)
# Session state for content plan
if 'content_plan' not in st.session_state:
st.session_state.content_plan = None
# Sidebar configuration
with st.sidebar:
st.header("Configuration âī¸")
YOUTUBE_API_KEY = st.text_input("YouTube API Key", type="password")
GEMINI_API_KEY = st.text_input("Gemini API Key", type="password")
MAX_VIDEOS = st.slider("Max Videos to Analyze", 1, 20, 10)
COMMENTS_PER_VIDEO = st.slider("Comments per Video", 10, 100, 50)
# Main content
st.markdown('
', unsafe_allow_html=True)
st.write("Generate data-driven content plans using YouTube audience insights.")
# Helper functions
def get_actual_channel_id(youtube, channel_url):
"""Extract real channel ID from a handle (@username) or custom URL."""
if "@" in channel_url:
username = channel_url.split("@")[-1]
request = youtube.channels().list(part="id", forHandle=username)
elif "channel/" in channel_url:
return channel_url.split("channel/")[-1]
else:
return None
response = request.execute()
if "items" in response and response["items"]:
return response["items"][0]["id"]
return None
def get_channel_videos(youtube, channel_id):
"""Fetch recent video IDs from the channel."""
request = youtube.search().list(
part="id",
channelId=channel_id,
maxResults=min(MAX_VIDEOS, 50), # Ensure within API limit
order="date",
type="video"
)
response = request.execute()
return [item['id']['videoId'] for item in response.get("items", [])]
def get_video_comments(youtube, video_id):
"""Fetch comments from a video."""
request = youtube.commentThreads().list(
part="snippet",
videoId=video_id,
maxResults=min(COMMENTS_PER_VIDEO, 100), # Ensure within API limit
textFormat="plainText"
)
response = request.execute()
return [item['snippet']['topLevelComment']['snippet']['textDisplay'] for item in response.get("items", [])]
def analyze_comments(comments):
"""Analyze comments using Gemini API and generate a content plan."""
genai.configure(api_key=GEMINI_API_KEY)
model = genai.GenerativeModel('gemini-1.5-pro')
prompt = f"""
Analyze the following YouTube comments and generate a 10-day content plan.
Each day should include:
1. Content Topic
2. Objective
3. Format
4. Engagement Strategy
5. Success Metrics
Comments:
{comments}
"""
response = model.generate_content(prompt)
return response.text
# Get channel URL
channel_url = st.text_input("Enter YouTube Channel URL:", placeholder="https://www.youtube.com/@ChannelName")
if st.button("Generate Content Plan đ"):
if not all([YOUTUBE_API_KEY, GEMINI_API_KEY, channel_url]):
st.error("Please fill all required fields!")
else:
try:
youtube = googleapiclient.discovery.build("youtube", "v3", developerKey=YOUTUBE_API_KEY)
genai.configure(api_key=GEMINI_API_KEY)
with st.spinner("đ Analyzing channel..."):
channel_id = get_actual_channel_id(youtube, channel_url)
if not channel_id:
st.error("Invalid channel URL!")
st.stop()
video_ids = get_channel_videos(youtube, channel_id)
all_comments = []
progress_bar = st.progress(0)
for idx, video_id in enumerate(video_ids):
progress = (idx + 1) / len(video_ids)
progress_bar.progress(progress, text=f"đĨ Collecting comments from video {idx+1}/{len(video_ids)}...")
all_comments.extend(get_video_comments(youtube, video_id))
with st.spinner("đ§ Analyzing comments and generating plan..."):
content_plan = analyze_comments(all_comments)
st.session_state.content_plan = content_plan
progress_bar.empty()
except Exception as e:
st.error(f"Error: {str(e)}")
# Display results
if st.session_state.content_plan:
st.markdown("## đ
10-Day Content Plan")
st.success("Here's your personalized content strategy based on audience insights!")
start_date = datetime.now()
for day in range(10):
current_date = start_date + timedelta(days=day)
with st.expander(f"Day {day+1} - {current_date.strftime('%b %d')}", expanded=True if day == 0 else False):
plan_lines = st.session_state.content_plan.split("\n")
start_index = day * 5
if start_index + 4 < len(plan_lines):
st.markdown(f"""
{plan_lines[start_index] if start_index < len(plan_lines) else 'No Topic'}
đ¯ Objective: {plan_lines[start_index+1] if start_index+1 < len(plan_lines) else 'N/A'}
đš Format: {plan_lines[start_index+2] if start_index+2 < len(plan_lines) else 'N/A'}
đĄ Engagement Strategy: {plan_lines[start_index+3] if start_index+3 < len(plan_lines) else 'N/A'}
đ Success Metrics: {plan_lines[start_index+4] if start_index+4 < len(plan_lines) else 'N/A'}
""", unsafe_allow_html=True)
st.download_button(
label="đĨ Download Full Plan",
data=st.session_state.content_plan,
file_name=f"content_plan_{datetime.now().strftime('%Y%m%d')}.txt",
mime="text/plain"
)
with st.expander("âšī¸ How to use this tool"):
st.markdown("""
1. **Get API Keys**:
- YouTube Data API: [Get it here](https://console.cloud.google.com/)
- Gemini API: [Get it here](https://makersuite.google.com/)
2. **Enter Channel URL**:
3. **Adjust Settings**:
4. **Generate Plan**:
5. **Download & Track Results**.
""")