Greasy Fork

Greasy Fork is available in English.

OG Kick Advanced Tools — Chat Spammer + Rate Limit Bypass

Advanced chat spammer for Kick.com

// ==UserScript==
// @name         OG Kick Advanced Tools — Chat Spammer + Rate Limit Bypass
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Advanced chat spammer for Kick.com
// @author       Robert
// @icon         https://www.google.com/s2/favicons?sz=64&domain=kick.com
// @match        https://kick.com/*
// @grant none
// @license MIT
// ==/UserScript==

(function() {
    'use strict';

    let bearerToken = localStorage.getItem('bearerToken') || null;
    let chatroomId = null;
    let logs = [];
    let spamStatus = 'unknown';
    const randomEmotes = [
        '[emote:39286:YOUTried]', '[emote:37239:WeSmart]', '[emote:37240:WeirdChamp]', '[emote:39284:vibePlz]',
        '[emote:37237:TriKool]', '[emote:39283:ToXiC]', '[emote:37236:ThisIsFine]', '[emote:37235:SUSSY]',
        '[emote:28633:SenpaiWhoo]', '[emote:39282:saltyTrain]', '[emote:37248:ratJAM]', '[emote:37234:Prayge]',
        '[emote:39279:PPJedi]', '[emote:39277:politeCat]', '[emote:37230:POLICE]', '[emote:37233:PogU]',
        '[emote:39275:peepoShyy]', '[emote:37246:peepoRiot]', '[emote:37245:peepoDJ]', '[emote:37232:PeepoClap]',
        '[emote:37231:PatrickBoo]', '[emote:28632:OuttaPocke]', '[emote:37229:OOOO]', '[emote:28631:NugTime]',
        '[emote:37228:NODDERS]', '[emote:39273:MuteD]', '[emote:37244:modCheck]', '[emote:43404:mericKat]',
        '[emote:37227:LULW]', '[emote:39272:LetMeIn]', '[emote:39261:kkHuh]', '[emote:55886:kickSadge]',
        '[emote:37226:KEKW]', '[emote:37225:KEKLEO]', '[emote:39269:KEKByebye]', '[emote:39256:KatKiss]',
        '[emote:305040:KappA]', '[emote:39268:HYPERCLAPH]', '[emote:39267:HaHaaHaHaa]', '[emote:37224:GIGACHAD]',
        '[emote:37243:gachiGASM]', '[emote:39402:Flowie]', '[emote:37221:EZ]', '[emote:39265:EDMusiC]',
        '[emote:39262:duckPlz]', '[emote:37220:DonoWall]', '[emote:39260:DanceDance]', '[emote:39258:coffinPls]',
        '[emote:37218:Clap]', '[emote:37242:catblobDan]', '[emote:39254:CaptFail]', '[emote:37217:Bwop]',
        '[emote:39251:beeBobble]', '[emote:39250:BBooomer]', '[emote:37215:AYAYA]'
    ];

    function createUI() {
        const ui = document.createElement('div');
        ui.style.cssText = `
            position: fixed;
            top: 20px;
            right: 20px;
            background: linear-gradient(135deg, #1e1e1e, #2a2a2a);
            padding: 0;
            border-radius: 10px;
            box-shadow: 0 4px 15px rgba(0, 0, 0, 0.5);
            z-index: 9999;
            color: #ffffff;
            font-family: 'Segoe UI', Arial, sans-serif;
            width: 450px;
            height: 450px;
            display: flex;
        `;
        ui.setAttribute('id', 'kick-tools-ui');

        ui.innerHTML = `
            <div style="width: 120px; background: #181818; padding: 15px; border-radius: 10px 0 0 10px;" id="dragHandle">
                <img src="https://kick.com/img/kick-logo.svg" style="width: 80px; margin-bottom: 20px;" alt="Kick Logo">
                <div id="tab-buttons" style="display: flex; flex-direction: column; gap: 10px;">
                    <button data-tab="chat" style="padding: 10px; background: #333; color: #fff; border: none; border-radius: 5px; cursor: pointer; text-align: left; transition: background 0.3s;">Chat Spammer</button>
                    <button data-tab="settings" style="padding: 10px; background: #333; color: #fff; border: none; border-radius: 5px; cursor: pointer; text-align: left; transition: background 0.3s;">Settings</button>
                </div>
            </div>
            <div style="flex: 1; padding: 20px; overflow-y: auto; position: relative;">
                <button id="minimizeButton" style="position: absolute; top: 10px; right: 10px; padding: 5px 10px; background: #555; color: #fff; border: none; border-radius: 5px; cursor: pointer; font-size: 12px;">-</button>
                <div id="chat-tab" class="tab-content" style="display: none;">
                    <div style="font-size: 18px; font-weight: 600; margin-bottom: 15px; color: #00ff00; text-shadow: 0 0 5px rgba(0, 255, 0, 0.3);">Chat Spammer</div>
                    <div style="margin-bottom: 15px; display: flex; gap: 10px;">
                        <input type="text" id="messageInput" placeholder="Enter your message" style="flex: 1; padding: 8px 12px; background: #333; color: #fff; border: 1px solid #444; border-radius: 5px; outline: none;">
                        <input type="number" id="countInput" value="1" min="1" style="width: 60px; padding: 8px; background: #333; color: #fff; border: 1px solid #444; border-radius: 5px; outline: none;">
                    </div>
                    <div style="margin-bottom: 15px; display: flex; gap: 5px; flex-wrap: wrap;">
                        <button id="kekwButton" title="KEKW" style="padding: 8px; background: #555; color: #fff; border: none; border-radius: 5px; cursor: pointer;"><img src="https://files.kick.com/emotes/37226/fullsize" style="width: 20px; vertical-align: middle;"></button>
                        <button id="patrickBooButton" title="PatrickBoo" style="padding: 8px; background: #555; color: #fff; border: none; border-radius: 5px; cursor: pointer;"><img src="https://files.kick.com/emotes/37231/fullsize" style="width: 20px; vertical-align: middle;"></button>
                        <button id="thisIsFineButton" title="ThisIsFine" style="padding: 8px; background: #555; color: #fff; border: none; border-radius: 5px; cursor: pointer;"><img src="https://files.kick.com/emotes/37236/fullsize" style="width: 20px; vertical-align: middle;"></button>
                        <button id="modCheckButton" title="modCheck" style="padding: 8px; background: #555; color: #fff; border: none; border-radius: 5px; cursor: pointer;"><img src="https://files.kick.com/emotes/37244/fullsize" style="width: 20px; vertical-align: middle;"></button>
                        <button id="muteDButton" title="MuteD" style="padding: 8px; background: #555; color: #fff; border: none; border-radius: 5px; cursor: pointer;"><img src="https://files.kick.com/emotes/39273/fullsize" style="width: 20px; vertical-align: middle;"></button>
                        <button id="weSmartButton" title="WeSmart" style="padding: 8px; background: #555; color: #fff; border: none; border-radius: 5px; cursor: pointer;"><img src="https://files.kick.com/emotes/37239/fullsize" style="width: 20px; vertical-align: middle;"></button>
                    </div>
                    <div style="margin-bottom: 15px; display: flex; gap: 10px;">
                        <button id="spamButton" style="flex: 1; padding: 10px; background: #00ff00; color: #000; border: none; border-radius: 5px; cursor: pointer; font-weight: 600;">SPAM</button>
                        <button id="saveButton" style="flex: 1; padding: 10px; background: #555; color: #fff; border: none; border-radius: 5px; cursor: pointer; font-weight: 600;">Save</button>
                    </div>
                    <div style="margin-bottom: 15px;">
                        <select id="savedMessages" style="width: 100%; padding: 8px; background: #333; color: #fff; border: 1px solid #444; border-radius: 5px; outline: none;">
                            <option value="">Select Saved Message</option>
                        </select>
                    </div>
                    <div style="margin-bottom: 15px; display: flex; align-items: center; gap: 15px;">
                        <label style="font-size: 14px;">Delay (ms): <input type="number" id="delayInput" value="0" min="0" style="width: 60px; padding: 6px; background: #333; color: #fff; border: 1px solid #444; border-radius: 5px; outline: none;"></label>
                        <label style="font-size: 14px;">Random Emote: <input type="checkbox" id="randomEmoteCheckbox" style="width: 16px; height: 16px;"></label>
                        <span id="spamStatus" style="margin-left: auto; font-size: 12px;"></span>
                    </div>
                    <div style="margin-top: 20px; display: flex; justify-content: space-between; align-items: center;">
                        <span style="font-size: 12px;">Chatroom ID: <span id="chatIdDisplay">${chatroomId || 'N/A'}</span></span>
                        <button id="clearLogsButton" style="padding: 6px 12px; background: #555; color: #fff; border: none; border-radius: 5px; cursor: pointer; font-size: 12px;">Clear Logs</button>
                    </div>
                    <div id="logArea" style="height: 120px; overflow-y: auto; background: #222; padding: 10px; border-radius: 5px; font-size: 12px; line-height: 1.4; border: 1px solid #444; margin-top: 10px;"></div>
                </div>
                <div id="settings-tab" class="tab-content" style="display: none;">
                    <div style="font-size: 18px; font-weight: 600; margin-bottom: 15px; color: #00ff00; text-shadow: 0 0 5px rgba(0, 255, 0, 0.3);">Settings</div>
                    <div style="margin-bottom: 15px;">
                        <input type="text" id="tokenInput" placeholder="Enter Bearer Token" value="${bearerToken || ''}" style="width: 100%; padding: 8px 12px; background: #333; color: #fff; border: 1px solid #444; border-radius: 5px; outline: none;">
                    </div>
                    <button id="setTokenButton" style="width: 100%; padding: 10px; background: #555; color: #fff; border: none; border-radius: 5px; cursor: pointer; font-weight: 600;">Set Token</button>
                </div>
            </div>
        `;

        document.body.appendChild(ui);
        addDragFunctionality(ui);
        setupEventListeners();
        populateSavedMessages();
        updateSpamStatus();
        setInterval(() => {
            getChatroomId();
            updateSpamStatus();
        }, 1000);
    }

    function createMinimizedIcon() {
        const icon = document.createElement('div');
        icon.style.cssText = `
            position: fixed;
            bottom: 20px;
            left: 50%;
            transform: translateX(-50%);
            background: #555;
            padding: 10px;
            border-radius: 50%;
            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.5);
            z-index: 9999;
            cursor: pointer;
            width: 40px;
            height: 40px;
            display: flex;
            align-items: center;
            justify-content: center;
        `;
        icon.setAttribute('id', 'minimized-icon');
        icon.innerHTML = `<img src="https://kick.com/img/kick-logo.svg" style="width: 30px;" title="Click to restore Kick Tools">`;
        document.body.appendChild(icon);
        icon.addEventListener('click', () => {
            document.getElementById('kick-tools-ui').style.display = 'flex';
            icon.remove();
        });
    }

    function addDragFunctionality(element) {
        let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
        const dragHandle = element.querySelector('#dragHandle');
        dragHandle.onmousedown = dragMouseDown;

        function dragMouseDown(e) {
            if (e.target.tagName === 'BUTTON' || e.target.tagName === 'IMG') return;
            e.preventDefault();
            pos3 = e.clientX;
            pos4 = e.clientY;
            document.onmouseup = closeDragElement;
            document.onmousemove = elementDrag;
        }

        function elementDrag(e) {
            e.preventDefault();
            pos1 = pos3 - e.clientX;
            pos2 = pos4 - e.clientY;
            pos3 = e.clientX;
            pos4 = e.clientY;
            element.style.top = (element.offsetTop - pos2) + "px";
            element.style.left = (element.offsetLeft - pos1) + "px";
        }

        function closeDragElement() {
            document.onmouseup = null;
            document.onmousemove = null;
        }
    }

    function addLog(message) {
        const timestamp = new Date().toLocaleTimeString();
        logs.push(`[${timestamp}] ${message}`);
        if (logs.length > 50) logs.shift();
        const logArea = document.getElementById('logArea');
        if (logArea) {
            logArea.innerHTML = logs.join('<br>');
            logArea.scrollTop = logArea.scrollHeight;
        }
    }

    function getChatroomId() {
        const source = document.documentElement.innerHTML;
        const match = source.match(/"chatroomId\\":(\d+),/);
        const newId = match && match[1] ? match[1] : null;
        if (newId !== chatroomId) {
            chatroomId = newId;
            document.getElementById('chatIdDisplay').textContent = chatroomId || 'N/A';
            addLog(`DEBUG: Updated chatroom ID: ${chatroomId || 'N/A'}`);
        }
    }

    function updateSpamStatus() {
        const chatInput = document.querySelector('div.pointer-events-none.absolute.left-2\\.5.top-1\\/2.-translate-y-1\\/2');
        spamStatus = chatInput && chatInput.textContent.includes('Send a message') ? 'able' : 'unable';
        const statusElement = document.getElementById('spamStatus');
        if (statusElement) {
            statusElement.textContent = spamStatus === 'able' ? 'Chat Available' : 'Chat Unavailable';
            statusElement.style.color = spamStatus === 'able' ? '#00ff00' : '#ff4444';
        }
    }

    function populateSavedMessages() {
        const savedMessages = JSON.parse(localStorage.getItem('savedMessages')) || [];
        const select = document.getElementById('savedMessages');
        select.innerHTML = '<option value="">Select Saved Message</option>';
        savedMessages.forEach((msg, index) => {
            const option = document.createElement('option');
            option.value = index;
            option.text = msg.substring(0, 30) + (msg.length > 30 ? '...' : '');
            select.appendChild(option);
        });
    }

    function sendMessages(message, count, delay, randomEmote) {
        if (!bearerToken) {
            addLog('DEBUG: No bearer token set');
            return;
        }
        if (!chatroomId) {
            addLog('DEBUG: No chatroom ID');
            return;
        }
        if (spamStatus !== 'able') {
            addLog('DEBUG: Chat not available for spamming');
            return;
        }

        const url = `https://kick.com/api/v2/messages/send/${chatroomId}`;
        const headers = {
            "accept": "application/json",
            "content-type": "application/json",
            "Authorization": `Bearer ${bearerToken}`,
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
        };

        addLog(`DEBUG: Initiating ${count} message requests`);

        const requests = Array.from({ length: count }, (_, i) => {
            const msg = randomEmote ? randomEmotes[Math.floor(Math.random() * randomEmotes.length)] : message || "Hello, this is a default message";
            const data = { "content": msg, "type": "message" };

            return new Promise((resolve) => {
                if (delay > 0) {
                    setTimeout(() => {
                        resolve(fetch(url, { method: 'POST', headers, body: JSON.stringify(data), mode: 'cors', credentials: 'include' }));
                    }, delay * i);
                } else {
                    resolve(fetch(url, { method: 'POST', headers, body: JSON.stringify(data), mode: 'cors', credentials: 'include' }));
                }
            })
            .then(response => ({ index: i + 1, status: response.status }))
            .catch(error => ({ index: i + 1, error: error.message }));
        });

        Promise.all(requests)
            .then(results => {
                results.forEach(result => {
                    if (result.status) {
                        addLog(`DEBUG: Message ${result.index}/${count} sent - Status: ${result.status}`);
                    } else {
                        addLog(`DEBUG: Error sending message ${result.index}/${count}: ${result.error}`);
                    }
                });
            })
            .catch(() => addLog('DEBUG: Some message requests failed'));
    }

    function setupEventListeners() {
        const spamButton = document.getElementById('spamButton');
        const messageInput = document.getElementById('messageInput');
        const countInput = document.getElementById('countInput');
        const tokenInput = document.getElementById('tokenInput');
        const setTokenButton = document.getElementById('setTokenButton');
        const saveButton = document.getElementById('saveButton');
        const savedMessagesSelect = document.getElementById('savedMessages');
        const delayInput = document.getElementById('delayInput');
        const randomEmoteCheckbox = document.getElementById('randomEmoteCheckbox');
        const clearLogsButton = document.getElementById('clearLogsButton');
        const kekwButton = document.getElementById('kekwButton');
        const patrickBooButton = document.getElementById('patrickBooButton');
        const thisIsFineButton = document.getElementById('thisIsFineButton');
        const modCheckButton = document.getElementById('modCheckButton');
        const muteDButton = document.getElementById('muteDButton');
        const weSmartButton = document.getElementById('weSmartButton');
        const minimizeButton = document.getElementById('minimizeButton');
        const tabButtons = document.querySelectorAll('#tab-buttons button');

        tabButtons.forEach(button => {
            button.addEventListener('click', () => {
                document.querySelectorAll('.tab-content').forEach(tab => tab.style.display = 'none');
                document.getElementById(`${button.dataset.tab}-tab`).style.display = 'block';
                tabButtons.forEach(btn => btn.style.background = '#333');
                button.style.background = '#555';
            });
        });
        if (tabButtons.length > 0) {
            tabButtons[0].click();
        }


        spamButton?.addEventListener('click', () => {
            const message = messageInput.value;
            const count = parseInt(countInput.value) || 1;
            const delay = parseInt(delayInput.value) || 0;
            const randomEmote = randomEmoteCheckbox.checked;
            sendMessages(message, count, delay, randomEmote);
        });

        setTokenButton?.addEventListener('click', () => {
            const manualToken = tokenInput.value.trim();
            if (manualToken) {
                bearerToken = manualToken;
                localStorage.setItem('bearerToken', bearerToken);
                addLog(`DEBUG: Bearer token set: ${bearerToken.substring(0, 10)}...`);
            } else {
                addLog('DEBUG: No valid bearer token entered');
            }
        });

        saveButton?.addEventListener('click', () => {
            const message = messageInput.value.trim();
            const savedMessages = JSON.parse(localStorage.getItem('savedMessages')) || [];
            if (message && !savedMessages.includes(message)) {
                savedMessages.push(message);
                localStorage.setItem('savedMessages', JSON.stringify(savedMessages));
                populateSavedMessages();
                addLog(`DEBUG: Saved message: ${message.substring(0, 20)}...`);
            }
        });

        savedMessagesSelect?.addEventListener('change', () => {
            const index = savedMessagesSelect.value;
            if (index !== '') {
                const savedMessages = JSON.parse(localStorage.getItem('savedMessages')) || [];
                messageInput.value = savedMessages[index];
                addLog(`DEBUG: Loaded saved message: ${savedMessages[index].substring(0, 20)}...`);
            }
        });

        kekwButton?.addEventListener('click', () => { messageInput.value += ' [emote:37226:KEKW]'; addLog('DEBUG: Added KEKW emote'); });
        patrickBooButton?.addEventListener('click', () => { messageInput.value += ' [emote:37231:PatrickBoo]'; addLog('DEBUG: Added PatrickBoo emote'); });
        thisIsFineButton?.addEventListener('click', () => { messageInput.value += ' [emote:37236:ThisIsFine]'; addLog('DEBUG: Added ThisIsFine emote'); });
        modCheckButton?.addEventListener('click', () => { messageInput.value += ' [emote:37244:modCheck]'; addLog('DEBUG: Added modCheck emote'); });
        muteDButton?.addEventListener('click', () => { messageInput.value += ' [emote:39273:MuteD]'; addLog('DEBUG: Added MuteD emote'); });
        weSmartButton?.addEventListener('click', () => { messageInput.value += ' [emote:37239:WeSmart]'; addLog('DEBUG: Added WeSmart emote'); });

        clearLogsButton?.addEventListener('click', () => {
            logs = [];
            const logArea = document.getElementById('logArea');
            if (logArea) logArea.innerHTML = '';
            addLog('DEBUG: Logs cleared');
        });

        minimizeButton?.addEventListener('click', () => {
            document.getElementById('kick-tools-ui').style.display = 'none';
            createMinimizedIcon();
            addLog('DEBUG: UI minimized');
        });
    }

    addLog('DEBUG: Script loaded');
    if (bearerToken) addLog(`DEBUG: Loaded bearer token: ${bearerToken.substring(0, 10)}...`);
    createUI();
    getChatroomId();
})();