DatafetchPro
    May 22, 20265 min read0 views

    How to Auto Generate YouTube Comments with AI?

    Need faster YouTube engagement? Try this AI comment assistant for smart replies, web automation, and comment generation.

    If you spend time on YouTube for marketing, outreach, or audience engagement, writing comments manually can slow everything down. This Tampermonkey script helps automate that process in a cleaner way.




    The script extracts video details like the title, expanded description, and sample comments directly from the page. It then sends the data to OpenRouter AI to generate a relevant YouTube comment automatically.

    The interface is lightweight, draggable, and built for daily use. You can quickly generate, copy, regenerate, or auto-fill comments into the YouTube comment box without switching tabs.


    Quick setup:

    1. Install Tampermonkey extension
    2. Create a new userscript
    3. Paste the script and save it
    4. Open Settings inside the floating panel
    5. Add your OpenRouter API key
    6. Select your preferred AI model
    7. Open any YouTube video and generate comments instantly

    Simple browser automation without extra software.


    This is useful for creators, marketers, researchers, and anyone working with web automation or repetitive engagement tasks. It also shows how browser-based data extraction and web scraping workflows can be combined with AI tools for practical automation.

    Features

    • Extract YouTube video title and description
    • Collect sample comments from viewers
    • AI-powered comment generation with OpenRouter
    • Quick auto-write into the comment box
    • Persistent floating UI
    • Custom prompts and model selection
    • Works directly inside YouTube

    The script is a simple example of how browser automation and AI can work together to speed up repetitive online tasks while keeping comments contextual and readable.


    // ==UserScript==

    // @name YouTube AI Comment Assistant

    // @namespace http://tampermonkey.net/

    // @version 1.0.0

    // @description Extract video title, description, comments and generate AI-powered comments using OpenRouter API

    // @author Ali

    // @match https://www.youtube.com/watch?v=*

    // @match https://www.youtube.com/watch?*

    // @grant GM_xmlhttpRequest

    // @grant GM_setValue

    // @grant GM_getValue

    // @grant GM_registerMenuCommand

    // @connect openrouter.ai

    // @license MIT

    // ==/UserScript==




    (function() {

    'use strict';

    window.trustedTypes.createPolicy('default', {createHTML: (string, sink) => string})

    // ==================== CONFIGURATION ====================

    const CONFIG = {

    API_ENDPOINT: 'https://openrouter.ai/api/v1/chat/completions',

    DEFAULT_MODEL: 'google/gemini-2.0-flash-exp:free',

    DEFAULT_SYSTEM_PROMPT: `You are a helpful YouTube comment assistant. Write engaging, thoughtful, and relevant comments for YouTube videos. Keep comments under 300 characters, be respectful, and add value to the conversation. Don't use markdown or emojis in excessive amounts.`,

    STORAGE_KEYS: {

    API_KEY: 'yt_comment_api_key',

    MODEL: 'yt_comment_model',

    PROMPT: 'yt_comment_prompt'

    }

    };




    // Available models for selection

    const AVAILABLE_MODELS = [

    { value: 'google/gemini-2.0-flash-exp:free', label: 'Gemini 2.0 Flash (Free)' },

    { value: 'google/gemini-2.0-pro-exp:free', label: 'Gemini 2.0 Pro (Free)' },

    { value: 'meta-llama/llama-3.2-3b-instruct:free', label: 'Llama 3.2 3B (Free)' },

    { value: 'microsoft/phi-3-mini-128k-instruct:free', label: 'Phi-3 Mini (Free)' },

    { value: 'mistralai/mistral-7b-instruct:free', label: 'Mistral 7B (Free)' },

    { value: 'openai/gpt-3.5-turbo', label: 'GPT-3.5 Turbo (Paid)' },

    { value: 'openai/gpt-4-turbo', label: 'GPT-4 Turbo (Paid)' },

    { value: 'anthropic/claude-3-haiku', label: 'Claude 3 Haiku (Paid)' }

    ];




    // ==================== UI CREATION ====================

    function createUI() {

    // Main floating panel

    const panel = document.createElement('div');

    panel.id = 'yt-ai-comment-panel';

    panel.innerHTML = `

    <div class="yt-ai-header">

    <span class="yt-ai-title">🤖 AI Comment Assistant</span>

    <button class="yt-ai-minimize">−</button>

    </div>

    <div class="yt-ai-content">

    <div class="yt-ai-section">

    <div class="yt-ai-status">

    <span id="yt-ai-status-text">Ready</span>

    <span id="yt-ai-status-icon">●</span>

    </div>

    </div>

    <div class="yt-ai-section">

    <button id="yt-ai-extract-btn" class="yt-ai-btn yt-ai-btn-primary">

    📋 Extract Video Data

    </button>

    </div>

    <div class="yt-ai-section yt-ai-data-preview" id="yt-ai-data-preview" style="display: none;">

    <div class="yt-ai-preview-title">📊 Extracted Data</div>

    <div id="yt-ai-title-preview" class="yt-ai-preview-item"></div>

    <div id="yt-ai-desc-preview" class="yt-ai-preview-item yt-ai-desc-preview"></div>

    <div id="yt-ai-comments-count" class="yt-ai-preview-item"></div>

    </div>

    <div class="yt-ai-section">

    <button id="yt-ai-generate-btn" class="yt-ai-btn yt-ai-btn-secondary" disabled>

    ✨ Generate Comment

    </button>

    </div>

    <div class="yt-ai-section">

    <div id="yt-ai-generated-comment" class="yt-ai-generated-comment" style="display: none;">

    <div class="yt-ai-comment-header">

    <span>💬 Generated Comment</span>

    <button id="yt-ai-copy-btn" class="yt-ai-icon-btn" title="Copy">📋</button>

    <button id="yt-ai-write-btn" class="yt-ai-icon-btn" title="Write to Comment Box">✏️</button>

    <button id="yt-ai-regenerate-btn" class="yt-ai-icon-btn" title="Regenerate">🔄</button>

    </div>

    <div id="yt-ai-comment-text" class="yt-ai-comment-text"></div>

    </div>

    </div>

    <div class="yt-ai-section">

    <button id="yt-ai-settings-btn" class="yt-ai-btn yt-ai-btn-outline">

    ⚙️ Settings

    </button>

    </div>

    </div>

    `;




    // Settings Modal

    const modal = document.createElement('div');

    modal.id = 'yt-ai-settings-modal';

    modal.className = 'yt-ai-modal';

    modal.style.display = 'none';

    modal.innerHTML = `

    <div class="yt-ai-modal-content">

    <div class="yt-ai-modal-header">

    <span>⚙️ Settings</span>

    <button class="yt-ai-modal-close">&times;</button>

    </div>

    <div class="yt-ai-modal-body">

    <div class="yt-ai-form-group">

    <label for="yt-ai-api-key">OpenRouter API Key</label>

    <input type="password" id="yt-ai-api-key" placeholder="sk-or-v1-..." value="${GM_getValue(CONFIG.STORAGE_KEYS.API_KEY, '')}">

    <small>Get your key from <a href="https://openrouter.ai/keys" target="_blank">openrouter.ai/keys</a></small>

    </div>

    <div class="yt-ai-form-group">

    <label for="yt-ai-model-select">AI Model</label>

    <select id="yt-ai-model-select">

    ${AVAILABLE_MODELS.map(m => `<option value="${m.value}" ${GM_getValue(CONFIG.STORAGE_KEYS.MODEL, CONFIG.DEFAULT_MODEL) === m.value ? 'selected' : ''}>${m.label}</option>`).join('')}

    </select>

    </div>

    <div class="yt-ai-form-group">

    <label for="yt-ai-prompt">System Prompt</label>

    <textarea id="yt-ai-prompt" rows="4" placeholder="Enter custom system prompt...">${GM_getValue(CONFIG.STORAGE_KEYS.PROMPT, CONFIG.DEFAULT_SYSTEM_PROMPT)}</textarea>

    </div>

    <div class="yt-ai-form-group">

    <button id="yt-ai-save-settings" class="yt-ai-btn yt-ai-btn-primary">Save Settings</button>

    </div>

    </div>

    </div>

    `;




    document.body.appendChild(panel);

    document.body.appendChild(modal);




    // Add styles

    addStyles();




    // Bind events

    bindEvents(panel, modal);

    }




    function addStyles() {

    const style = document.createElement('style');

    style.textContent = `

    #yt-ai-comment-panel {

    position: fixed;

    bottom: 20px;

    right: 20px;

    width: 380px;

    background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);

    border-radius: 16px;

    box-shadow: 0 8px 32px rgba(0,0,0,0.3);

    z-index: 10000;

    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;

    transition: all 0.3s ease;

    border: 1px solid rgba(255,255,255,0.1);

    backdrop-filter: blur(10px);

    }

    #yt-ai-comment-panel.minimized .yt-ai-content {

    display: none;

    }

    #yt-ai-comment-panel.minimized {

    width: auto;

    min-width: 200px;

    }

    .yt-ai-header {

    display: flex;

    justify-content: space-between;

    align-items: center;

    padding: 12px 16px;

    background: rgba(0,0,0,0.3);

    border-radius: 16px 16px 0 0;

    cursor: move;

    user-select: none;

    }

    .yt-ai-title {

    font-weight: 600;

    font-size: 14px;

    color: #fff;

    }

    .yt-ai-minimize {

    background: none;

    border: none;

    color: #fff;

    font-size: 20px;

    cursor: pointer;

    padding: 0 8px;

    border-radius: 4px;

    transition: background 0.2s;

    }

    .yt-ai-minimize:hover {

    background: rgba(255,255,255,0.1);

    }

    .yt-ai-content {

    padding: 16px;

    }

    .yt-ai-section {

    margin-bottom: 12px;

    }

    .yt-ai-status {

    display: flex;

    justify-content: space-between;

    align-items: center;

    font-size: 12px;

    color: #aaa;

    padding: 8px;

    background: rgba(0,0,0,0.2);

    border-radius: 8px;

    }

    #yt-ai-status-icon {

    font-size: 8px;

    margin-right: 6px;

    }

    .yt-ai-status.idle #yt-ai-status-icon { color: #f39c12; }

    .yt-ai-status.success #yt-ai-status-icon { color: #2ecc71; }

    .yt-ai-status.error #yt-ai-status-icon { color: #e74c3c; }

    .yt-ai-status.loading #yt-ai-status-icon {

    color: #3498db;

    animation: pulse 1s infinite;

    }

    @keyframes pulse {

    0%, 100% { opacity: 1; }

    50% { opacity: 0.3; }

    }

    .yt-ai-btn {

    width: 100%;

    padding: 10px 16px;

    border: none;

    border-radius: 8px;

    font-size: 14px;

    font-weight: 500;

    cursor: pointer;

    transition: all 0.2s;

    }

    .yt-ai-btn-primary {

    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);

    color: white;

    }

    .yt-ai-btn-primary:hover:not(:disabled) {

    transform: translateY(-1px);

    box-shadow: 0 4px 12px rgba(102,126,234,0.4);

    }

    .yt-ai-btn-secondary {

    background: linear-gradient(135deg, #f39c12 0%, #e74c3c 100%);

    color: white;

    }

    .yt-ai-btn-secondary:hover:not(:disabled) {

    transform: translateY(-1px);

    box-shadow: 0 4px 12px rgba(243,156,18,0.4);

    }

    .yt-ai-btn-outline {

    background: transparent;

    border: 1px solid rgba(255,255,255,0.2);

    color: #fff;

    }

    .yt-ai-btn-outline:hover {

    background: rgba(255,255,255,0.1);

    }

    .yt-ai-btn:disabled {

    opacity: 0.5;

    cursor: not-allowed;

    }

    .yt-ai-data-preview {

    background: rgba(0,0,0,0.3);

    border-radius: 8px;

    padding: 10px;

    font-size: 12px;

    }

    .yt-ai-preview-title {

    font-weight: 600;

    margin-bottom: 8px;

    color: #ddd;

    }

    .yt-ai-preview-item {

    margin-bottom: 6px;

    color: #bbb;

    word-break: break-word;

    }

    .yt-ai-desc-preview {

    max-height: 60px;

    overflow-y: auto;

    }

    .yt-ai-generated-comment {

    background: rgba(46,204,113,0.1);

    border-radius: 8px;

    padding: 12px;

    border-left: 3px solid #2ecc71;

    }

    .yt-ai-comment-header {

    display: flex;

    gap: 8px;

    margin-bottom: 8px;

    font-size: 12px;

    color: #2ecc71;

    }

    .yt-ai-icon-btn {

    background: none;

    border: none;

    cursor: pointer;

    font-size: 14px;

    padding: 2px 6px;

    border-radius: 4px;

    transition: background 0.2s;

    }

    .yt-ai-icon-btn:hover {

    background: rgba(255,255,255,0.1);

    }

    .yt-ai-comment-text {

    font-size: 13px;

    line-height: 1.5;

    color: #ddd;

    max-height: 150px;

    overflow-y: auto;

    padding-right: 8px;

    }

    /* Modal Styles */

    .yt-ai-modal {

    position: fixed;

    top: 0;

    left: 0;

    width: 100%;

    height: 100%;

    background: rgba(0,0,0,0.7);

    backdrop-filter: blur(4px);

    z-index: 10001;

    display: flex;

    align-items: center;

    justify-content: center;

    }

    .yt-ai-modal-content {

    background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);

    border-radius: 16px;

    width: 450px;

    max-width: 90%;

    border: 1px solid rgba(255,255,255,0.1);

    box-shadow: 0 20px 60px rgba(0,0,0,0.5);

    }

    .yt-ai-modal-header {

    display: flex;

    justify-content: space-between;

    align-items: center;

    padding: 16px;

    border-bottom: 1px solid rgba(255,255,255,0.1);

    }

    .yt-ai-modal-close {

    background: none;

    border: none;

    color: #fff;

    font-size: 24px;

    cursor: pointer;

    padding: 0 8px;

    }

    .yt-ai-modal-body {

    padding: 20px;

    }

    .yt-ai-form-group {

    margin-bottom: 16px;

    }

    .yt-ai-form-group label {

    display: block;

    margin-bottom: 6px;

    font-size: 13px;

    color: #ddd;

    }

    .yt-ai-form-group input, .yt-ai-form-group select, .yt-ai-form-group textarea {

    width: 100%;

    padding: 10px;

    background: rgba(0,0,0,0.3);

    border: 1px solid rgba(255,255,255,0.2);

    border-radius: 8px;

    color: #fff;

    font-size: 13px;

    }

    .yt-ai-form-group textarea {

    resize: vertical;

    }

    .yt-ai-form-group small {

    display: block;

    margin-top: 4px;

    font-size: 11px;

    color: #888;

    }

    .yt-ai-form-group small a {

    color: #667eea;

    }

    `;

    document.head.appendChild(style);

    }




    // ==================== STATE MANAGEMENT ====================

    let extractedData = {

    title: '',

    description: '',

    comments: []

    };




    function updateStatus(message, status = 'idle') {

    const statusText = document.getElementById('yt-ai-status-text');

    const panel = document.getElementById('yt-ai-comment-panel');

    if (statusText) {

    statusText.textContent = message;

    }

    if (panel) {

    panel.querySelector('.yt-ai-status').className = `yt-ai-status ${status}`;

    }

    }




    async function extractVideoData() {

    updateStatus('Extracting data...', 'loading');




    // Extract title

    const titleElement = document.querySelector('h1.title yt-formatted-string, h1.ytd-watch-metadata yt-formatted-string, #title h1 yt-formatted-string');

    const title = titleElement ? titleElement.textContent.trim() : document.title.replace(' - YouTube', '');




    // Extract description - click "more" button if exists

    const descriptionArea = document.querySelector('#description-inline-expander, #description');

    let description = '';




    // Try to expand description if there's a "more" button

    const moreButton = document.querySelector('#expand, #more, .ytd-text-inline-expander #expand, tp-yt-paper-button#expand');

    if (moreButton && moreButton.offsetParent !== null) {

    updateStatus('Expanding description...', 'loading');

    moreButton.click();

    await new Promise(resolve => setTimeout(resolve, 500));

    }




    const descElement = document.querySelector('div#expanded');

    if (descElement) {

    description = descElement.textContent.trim();

    } else {

    const metaDesc = document.querySelector('div#expanded');

    if (metaDesc) description = metaDesc.getAttribute('content');

    }




    // Extract sample comments (first 5)

    updateStatus('Extracting comments...', 'loading');

    const commentElements = document.querySelectorAll('#comments ytd-comment-thread-renderer, #comments ytd-comment-view-model');

    const comments = [];




    for (let i = 0; i < Math.min(commentElements.length, 5); i++) {

    const commentEl = commentElements[i];

    let commentText = '';




    // Try different selectors for comment text

    const textElement = commentEl.querySelector('#content-text, yt-attributed-string, #comment-content');

    if (textElement) {

    commentText = textElement.textContent.trim();

    }




    if (commentText) {

    comments.push(commentText.substring(0, 200));

    }

    }




    extractedData = { title, description, comments };




    // Update preview

    const previewDiv = document.getElementById('yt-ai-data-preview');

    const titlePreview = document.getElementById('yt-ai-title-preview');

    const descPreview = document.getElementById('yt-ai-desc-preview');

    const commentsCount = document.getElementById('yt-ai-comments-count');

    const generateBtn = document.getElementById('yt-ai-generate-btn');




    if (titlePreview) titlePreview.innerHTML = `<strong>Title:</strong> ${title.substring(0, 80)}${title.length > 80 ? '...' : ''}`;

    if (descPreview) descPreview.innerHTML = `<strong>Description:</strong> ${description.substring(0, 120)}${description.length > 120 ? '...' : ''}`;

    if (commentsCount) commentsCount.innerHTML = `<strong>Comments:</strong> ${comments.length} extracted`;




    if (previewDiv) previewDiv.style.display = 'block';

    if (generateBtn) generateBtn.disabled = false;




    updateStatus(`Extracted: "${title.substring(0, 40)}..."`, 'success');

    setTimeout(() => updateStatus('Ready', 'idle'), 2000);




    return extractedData;

    }




    async function generateComment() {

    const apiKey = GM_getValue(CONFIG.STORAGE_KEYS.API_KEY, '');

    if (!apiKey) {

    updateStatus('Please add API key in settings', 'error');

    document.getElementById('yt-ai-settings-btn').click();

    return;

    }




    if (!extractedData.title) {

    await extractVideoData();

    }




    updateStatus('Generating comment...', 'loading');




    const model = GM_getValue(CONFIG.STORAGE_KEYS.MODEL, CONFIG.DEFAULT_MODEL);

    const systemPrompt = GM_getValue(CONFIG.STORAGE_KEYS.PROMPT, CONFIG.DEFAULT_SYSTEM_PROMPT);




    // Build user prompt with video data

    let userPrompt = `Write an engaging YouTube comment for this video:\n\nTitle: "${extractedData.title}"\n\nDescription: "${extractedData.description.substring(0, 500)}"`;




    if (extractedData.comments.length > 0) {

    userPrompt += `\n\nSample comments from viewers:\n${extractedData.comments.map((c, i) => `${i+1}. "${c}"`).join('\n')}`;

    }




    userPrompt += `\n\nWrite a thoughtful, relevant comment (max 280 characters). Be genuine and add value to the discussion.`;




    GM_xmlhttpRequest({

    method: 'POST',

    url: CONFIG.API_ENDPOINT,

    headers: {

    'Content-Type': 'application/json',

    'Authorization': `Bearer ${apiKey}`,

    'HTTP-Referer': window.location.origin,

    'X-Title': 'YouTube AI Comment Assistant'

    },

    data: JSON.stringify({

    model: model,

    messages: [

    { role: 'system', content: systemPrompt },

    { role: 'user', content: userPrompt }

    ],

    max_tokens: 200,

    temperature: 0.8

    }),

    onload: function(response) {

    if (response.status === 200) {

    try {

    const data = JSON.parse(response.responseText);

    const generatedComment = data.choices[0].message.content.trim();

    displayGeneratedComment(generatedComment);

    updateStatus('Comment generated!', 'success');

    setTimeout(() => updateStatus('Ready', 'idle'), 2000);

    } catch (e) {

    updateStatus('Error parsing response', 'error');

    console.error(e);

    }

    } else {

    let errorMsg = `API Error: ${response.status}`;

    try {

    const error = JSON.parse(response.responseText);

    errorMsg = error.error?.message || errorMsg;

    } catch(e) {}

    updateStatus(errorMsg.substring(0, 50), 'error');

    console.error('API Error:', response.responseText);

    }

    },

    onerror: function(error) {

    updateStatus('Network error', 'error');

    console.error('Request failed:', error);

    }

    });

    }




    function displayGeneratedComment(comment) {

    const commentDiv = document.getElementById('yt-ai-generated-comment');

    const commentText = document.getElementById('yt-ai-comment-text');




    if (commentText) commentText.textContent = comment;

    if (commentDiv) commentDiv.style.display = 'block';

    }




    function copyToClipboard() {

    const commentText = document.getElementById('yt-ai-comment-text');

    if (commentText && commentText.textContent) {

    navigator.clipboard.writeText(commentText.textContent);

    updateStatus('Copied!', 'success');

    setTimeout(() => updateStatus('Ready', 'idle'), 1500);

    }

    }




    function writeToCommentBox() {

    const commentText = document.getElementById('yt-ai-comment-text');

    if (!commentText || !commentText.textContent) return;




    // Find comment input box

    const commentInput = document.querySelector('#simplebox-placeholder, #placeholder-area, ytd-comment-simplebox-renderer #placeholder-area, #comment-simplebox-renderer');




    if (commentInput) {

    // Click to focus and activate

    commentInput.click();




    setTimeout(() => {

    // Find the actual input/textarea

    const textarea = document.querySelector('#contenteditable-root, [contenteditable="true"], #comment-input, textarea');

    if (textarea) {

    if (textarea.isContentEditable) {

    textarea.focus();

    document.execCommand('insertText', false, commentText.textContent);

    } else if (textarea.tagName === 'TEXTAREA' || textarea.tagName === 'INPUT') {

    textarea.value = commentText.textContent;

    textarea.dispatchEvent(new Event('input', { bubbles: true }));

    textarea.focus();

    }




    // Scroll to comment area

    const commentSection = document.querySelector('#comments, ytd-comments');

    if (commentSection) {

    commentSection.scrollIntoView({ behavior: 'smooth', block: 'start' });

    }




    updateStatus('Comment written!', 'success');

    setTimeout(() => updateStatus('Ready', 'idle'), 1500);

    } else {

    updateStatus('Could not find comment input', 'error');

    }

    }, 500);

    } else {

    updateStatus('Please expand comments section first', 'error');

    }

    }




    function openSettings() {

    const modal = document.getElementById('yt-ai-settings-modal');

    if (modal) modal.style.display = 'flex';

    }




    function saveSettings() {

    const apiKey = document.getElementById('yt-ai-api-key').value;

    const model = document.getElementById('yt-ai-model-select').value;

    const prompt = document.getElementById('yt-ai-prompt').value;




    GM_setValue(CONFIG.STORAGE_KEYS.API_KEY, apiKey);

    GM_setValue(CONFIG.STORAGE_KEYS.MODEL, model);

    GM_setValue(CONFIG.STORAGE_KEYS.PROMPT, prompt);




    const modal = document.getElementById('yt-ai-settings-modal');

    if (modal) modal.style.display = 'none';




    updateStatus('Settings saved!', 'success');

    setTimeout(() => updateStatus('Ready', 'idle'), 1500);

    }




    function bindEvents(panel, modal) {

    // Minimize button

    const minimizeBtn = panel.querySelector('.yt-ai-minimize');

    minimizeBtn.addEventListener('click', () => {

    panel.classList.toggle('minimized');

    minimizeBtn.textContent = panel.classList.contains('minimized') ? '+' : '−';

    });




    // Extract button

    const extractBtn = document.getElementById('yt-ai-extract-btn');

    if (extractBtn) extractBtn.addEventListener('click', extractVideoData);




    // Generate button

    const generateBtn = document.getElementById('yt-ai-generate-btn');

    if (generateBtn) generateBtn.addEventListener('click', generateComment);




    // Settings button

    const settingsBtn = document.getElementById('yt-ai-settings-btn');

    if (settingsBtn) settingsBtn.addEventListener('click', openSettings);




    // Modal close

    const closeBtn = modal.querySelector('.yt-ai-modal-close');

    if (closeBtn) closeBtn.addEventListener('click', () => modal.style.display = 'none');




    // Save settings

    const saveBtn = document.getElementById('yt-ai-save-settings');

    if (saveBtn) saveBtn.addEventListener('click', saveSettings);




    // Copy button

    const copyBtn = document.getElementById('yt-ai-copy-btn');

    if (copyBtn) copyBtn.addEventListener('click', copyToClipboard);




    // Write button

    const writeBtn = document.getElementById('yt-ai-write-btn');

    if (writeBtn) writeBtn.addEventListener('click', writeToCommentBox);




    // Regenerate button

    const regenerateBtn = document.getElementById('yt-ai-regenerate-btn');

    if (regenerateBtn) regenerateBtn.addEventListener('click', generateComment);




    // Close modal on outside click

    window.addEventListener('click', (e) => {

    if (e.target === modal) modal.style.display = 'none';

    });




    // Make panel draggable

    let isDragging = false;

    let dragOffset = { x: 0, y: 0 };




    const header = panel.querySelector('.yt-ai-header');




    header.addEventListener('mousedown', (e) => {

    if (e.target === minimizeBtn) return;

    isDragging = true;

    const rect = panel.getBoundingClientRect();

    dragOffset.x = e.clientX - rect.left;

    dragOffset.y = e.clientY - rect.top;

    panel.style.position = 'fixed';

    panel.style.margin = '0';

    });




    window.addEventListener('mousemove', (e) => {

    if (!isDragging) return;

    let newX = e.clientX - dragOffset.x;

    let newY = e.clientY - dragOffset.y;




    newX = Math.max(0, Math.min(window.innerWidth - panel.offsetWidth, newX));

    newY = Math.max(0, Math.min(window.innerHeight - panel.offsetHeight, newY));




    panel.style.left = newX + 'px';

    panel.style.right = 'auto';

    panel.style.bottom = 'auto';

    panel.style.top = newY + 'px';

    });




    window.addEventListener('mouseup', () => {

    isDragging = false;

    });

    }




    // ==================== QUICK COMMENT BUTTON ====================

    function addQuickCommentButton() {

    // Wait for player controls or video actions area

    const checkInterval = setInterval(() => {

    const actionsArea = document.querySelector('#actions-inner, #menu-container, .ytd-watch-metadata #actions');

    if (actionsArea && !document.querySelector('#yt-ai-quick-btn')) {

    const quickBtn = document.createElement('button');

    quickBtn.id = 'yt-ai-quick-btn';

    quickBtn.className = 'yt-ai-quick-btn';

    quickBtn.innerHTML = '🤖 AI Comment';

    quickBtn.style.cssText = `

    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);

    border: none;

    border-radius: 18px;

    padding: 8px 16px;

    color: white;

    font-size: 14px;

    font-weight: 500;

    cursor: pointer;

    margin-left: 12px;

    transition: all 0.2s;

    `;

    quickBtn.onmouseenter = () => quickBtn.style.transform = 'scale(1.02)';

    quickBtn.onmouseleave = () => quickBtn.style.transform = 'scale(1)';

    quickBtn.onclick = async () => {

    await extractVideoData();

    generateComment();

    // Show the main panel if minimized

    const panel = document.getElementById('yt-ai-comment-panel');

    if (panel && panel.classList.contains('minimized')) {

    panel.classList.remove('minimized');

    const minimizeBtn = panel.querySelector('.yt-ai-minimize');

    if (minimizeBtn) minimizeBtn.textContent = '−';

    }

    };




    actionsArea.appendChild(quickBtn);

    clearInterval(checkInterval);

    }

    }, 2000);

    }




    // ==================== INITIALIZATION ====================

    function init() {

    createUI();

    addQuickCommentButton();




    // Auto-extract on page load

    setTimeout(() => {

    extractVideoData();

    }, 3000);

    }




    // Start the script

    if (document.readyState === 'loading') {

    document.addEventListener('DOMContentLoaded', init);

    } else {

    init();

    }

    })();
    0