Instagram Embed Link Copier for Discord (with Reels Support)

Adds four buttons to copy Instagram post/reel links. Order from left to right: ez, dd, original, fxig. Includes improved spacing and modern look, now supports /reel/ links.

// ==UserScript==
// @name         Instagram Embed Link Copier for Discord (with Reels Support)
// @namespace    http://tampermonkey.net/
// @version      1.8
// @description  Adds four buttons to copy Instagram post/reel links. Order from left to right: ez, dd, original, fxig. Includes improved spacing and modern look, now supports /reel/ links.
// @match        https://www.instagram.com/*
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // Helper function to create a styled button
    function createStyledButton(text, bgColor) {
        const btn = document.createElement('button');
        btn.innerText = text;
        btn.style.cssText = `
            padding: 5px 10px;
            background-color: ${bgColor};
            color: #fff;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 12px;
            font-weight: 500;
            box-shadow: 0 1px 2px rgba(0,0,0,0.1);
            transition: background-color 0.2s ease;
        `;
        // Simple hover effect
        btn.addEventListener('mouseenter', () => {
            btn.style.filter = 'brightness(90%)';
        });
        btn.addEventListener('mouseleave', () => {
            btn.style.filter = 'none';
        });
        return btn;
    }

    // Function to show a small toast message
    function createToast(message) {
        const toast = document.createElement('div');
        toast.textContent = message;
        toast.style.cssText = `
            position: fixed;
            bottom: 20px;
            right: 20px;
            background-color: rgba(0, 0, 0, 0.8);
            color: white;
            padding: 10px 20px;
            border-radius: 5px;
            font-size: 14px;
            z-index: 10000;
            opacity: 1;
            transition: opacity 0.5s ease;
        `;
        document.body.appendChild(toast);

        // Remove the toast after 1 second
        setTimeout(() => {
            toast.style.opacity = '0';
            setTimeout(() => {
                toast.remove();
            }, 500);
        }, 1000);
    }

    // Copy text to clipboard
    function copyToClipboard(text) {
        const textarea = document.createElement('textarea');
        textarea.value = text;
        document.body.appendChild(textarea);
        textarea.select();
        document.execCommand('copy');
        document.body.removeChild(textarea);
    }

    // Retrieve the post or reel link (current page if /p/ or /reel/, otherwise from the closest article)
    function getPostLink(section) {
        const href = window.location.href;
        // If current URL has /p/ or /reel/ use that
        if (href.includes('/p/') || href.includes('/reel/')) {
            return href;
        }
        // Otherwise, look for an <a> with /p/ or /reel/
        const postLinkElement =
            section.closest('article') &&
            section.closest('article').querySelector('a[href*="/p/"], a[href*="/reel/"]');
        return postLinkElement ? postLinkElement.href : null;
    }

    // Create the four copy buttons
    function createCopyButtons() {
        // Target sections in both the timeline and single-post/reel view
        const buttonSections = document.querySelectorAll(
            'section.x6s0dn4.xrvj5dj.x1o61qjw.x12nagc.x1gslohp, section.x6s0dn4.xrvj5dj.x1o61qjw, section.x78zum5.x1q0g3np'
        );

        buttonSections.forEach((section) => {
            // Skip if we've already inserted our buttons
            if (section.querySelector('.copy-ez-link-btn')) {
                return;
            }

            // 1. ez Button (left-most, red)
            const ezButton = createStyledButton('Copy ez Link', '#f02a2a');
            ezButton.className = 'copy-ez-link-btn';
            ezButton.addEventListener('click', function() {
                const originalLink = getPostLink(section);
                if (originalLink) {
                    const modifiedLink = originalLink.replace('instagram.com', 'instagramez.com');
                    copyToClipboard(modifiedLink);
                    createToast('Modified "ez" link copied!');
                } else {
                    createToast('Failed to find post link.');
                }
            });

            // 2. dd Button (blue)
            const ddButton = createStyledButton('Copy dd Link', '#3897f0');
            ddButton.className = 'copy-dd-link-btn';
            ddButton.addEventListener('click', function() {
                const originalLink = getPostLink(section);
                if (originalLink) {
                    const modifiedLink = originalLink.replace('www.instagram.com', 'www.ddinstagram.com');
                    copyToClipboard(modifiedLink);
                    createToast('Modified "dd" link copied!');
                } else {
                    createToast('Failed to find post link.');
                }
            });

            // 3. Original Button (gray)
            const origButton = createStyledButton('Copy Original Link', '#555');
            origButton.className = 'copy-original-link-btn';
            origButton.addEventListener('click', function() {
                const originalLink = getPostLink(section);
                if (originalLink) {
                    copyToClipboard(originalLink);
                    createToast('Original link copied!');
                } else {
                    createToast('Failed to find post link.');
                }
            });

            // 4. Fxig button (right-most, green)
            const fxigButton = createStyledButton('Copy fxig Link', '#28a745');
            fxigButton.className = 'copy-fxig-link-btn';
            fxigButton.addEventListener('click', function() {
                const originalLink = getPostLink(section);
                if (originalLink) {
                    const modifiedLink = originalLink.replace('instagram.com', 'fxig.seria.moe');
                    copyToClipboard(modifiedLink);
                    createToast('Modified "fxig" link copied!');
                } else {
                    createToast('Failed to find post link.');
                }
            });

            // Container for the buttons
            const buttonContainer = document.createElement('div');
            // Use gap to space them evenly
            buttonContainer.style.cssText = `
                display: inline-flex;
                align-items: center;
                gap: 8px;
                margin-top: 8px;
            `;

            // Append buttons in the chosen order: ez, dd, original, fxig
            buttonContainer.appendChild(ezButton);
            buttonContainer.appendChild(ddButton);
            buttonContainer.appendChild(origButton);
            buttonContainer.appendChild(fxigButton);

            // Insert into the section
            section.appendChild(buttonContainer);
        });
    }

    // Observe changes for dynamically loaded posts
    window.addEventListener('load', () => {
        const observer = new MutationObserver(() => {
            createCopyButtons();
        });
        observer.observe(document.body, { childList: true, subtree: true });
    });
})();