|
import streamlit as st |
|
import googleapiclient.discovery |
|
import google.generativeai as genai |
|
from datetime import datetime, timedelta |
|
|
|
|
|
st.set_page_config( |
|
page_title="YouTube Content Strategist", |
|
page_icon="π", |
|
layout="wide", |
|
initial_sidebar_state="expanded" |
|
) |
|
|
|
|
|
st.markdown(r""" |
|
<style> |
|
.header { |
|
font-size: 2.5em !important; |
|
color: #FF4B4B !important; |
|
margin-bottom: 30px !important; |
|
} |
|
.sidebar .sidebar-content { |
|
background-color: #F0F2F6; |
|
} |
|
.stProgress > div > div > div > div { |
|
background-color: #FF4B4B; |
|
} |
|
.day-card { |
|
padding: 20px; |
|
border-radius: 10px; |
|
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); |
|
margin-bottom: 20px; |
|
background-color: white; |
|
} |
|
body { |
|
background-image: url('https://images.unsplash.com/photo-7NT4EDSI5Ok'); |
|
background-size: cover; |
|
background-position: center; |
|
background-repeat: no-repeat; |
|
background-attachment: fixed; |
|
} |
|
.main > div { |
|
background-color: rgba(255, 255, 255, 0.9); |
|
padding: 20px; |
|
border-radius: 10px; |
|
} |
|
</style> |
|
""", unsafe_allow_html=True) |
|
|
|
|
|
if 'content_plan' not in st.session_state: |
|
st.session_state.content_plan = None |
|
|
|
|
|
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) |
|
|
|
|
|
st.markdown('<div class="header">π₯ YouTube Content Strategist</div>', unsafe_allow_html=True) |
|
st.write("Generate data-driven content plans using YouTube audience insights") |
|
|
|
|
|
def get_channel_id(channel_url): |
|
"""Extract channel ID from URL.""" |
|
if "@" in channel_url: |
|
return channel_url.split("@")[-1] |
|
elif "channel/" in channel_url: |
|
return channel_url.split("channel/")[-1] |
|
return None |
|
|
|
def get_channel_videos(channel_id): |
|
"""Fetch recent video IDs from the channel.""" |
|
youtube = googleapiclient.discovery.build("youtube", "v3", developerKey=YOUTUBE_API_KEY) |
|
request = youtube.search().list( |
|
part="id", |
|
channelId=channel_id, |
|
maxResults=MAX_VIDEOS, |
|
order="date", |
|
type="video" |
|
) |
|
response = request.execute() |
|
return [item['id']['videoId'] for item in response['items']] |
|
|
|
def get_video_comments(video_id): |
|
"""Fetch comments from a video.""" |
|
youtube = googleapiclient.discovery.build("youtube", "v3", developerKey=YOUTUBE_API_KEY) |
|
request = youtube.commentThreads().list( |
|
part="snippet", |
|
videoId=video_id, |
|
maxResults=COMMENTS_PER_VIDEO, |
|
textFormat="plainText" |
|
) |
|
response = request.execute() |
|
return [item['snippet']['topLevelComment']['snippet']['textDisplay'] for item in response['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 |
|
|
|
|
|
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) |
|
model = genai.GenerativeModel('gemini-1.5-pro') |
|
|
|
|
|
with st.spinner("π Analyzing channel..."): |
|
channel_id = get_channel_id(channel_url) |
|
if not channel_id: |
|
st.error("Invalid channel URL") |
|
st.stop() |
|
|
|
video_ids = get_channel_videos(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(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)}") |
|
|
|
|
|
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""" |
|
|
|
<div class="day-card"> |
|
<h3>{plan_lines[start_index] if start_index < len(plan_lines) else 'No Topic'}</h3> |
|
<p>π― Objective: {plan_lines[start_index+1] if start_index+1 < len(plan_lines) else 'N/A'}</p> |
|
<p>πΉ Format: {plan_lines[start_index+2] if start_index+2 < len(plan_lines) else 'N/A'}</p> |
|
<p>π‘ Engagement Strategy: {plan_lines[start_index+3] if start_index+3 < len(plan_lines) else 'N/A'}</p> |
|
<p>π Success Metrics: {plan_lines[start_index+4] if start_index+4 < len(plan_lines) else 'N/A'}</p> |
|
</div> |
|
""", 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**: |
|
- Supports both channel IDs (@ChannelName) and custom URLs |
|
|
|
3. **Adjust Settings**: |
|
- Control number of videos/comments analyzed in sidebar |
|
|
|
4. **Generate Plan**: |
|
- Click the rocket button to create your strategy |
|
|
|
5. **Implement & Track**: |
|
- Download the plan and track performance in YouTube Analytics |
|
""") |