// ==UserScript==
// @name OG Kick Advanced Tools — Chat Spammer + Rate Limit Bypass
// @namespace http://tampermonkey.net/
// @version 1.3
// @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
// @run-at document-start
// @license MIT
// @downloadURL none
// ==/UserScript==
(function() {
'use strict';
const originalFetch = window.fetch;
let initialTokenLogged = false;
async function attemptToSniffTokenViaActivationMessage() {
if (localStorage.getItem('bearerToken')) {
addLog('DEBUG: Token already exists in storage. Skipping active sniff via activation message.');
return;
}
addLog('DEBUG: Page fully loaded. Attempting to actively sniff token via activation message...');
const targetChatroomId = "56778838";
const url = `https://kick.com/api/v2/messages/send/${targetChatroomId}`;
const payload = { "content": "activation_ping_v1.5", "type": "message" };
try {
await originalFetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
},
body: JSON.stringify(payload),
credentials: 'include'
});
addLog('DEBUG: Activation message sent (for token sniffing post-load). Our fetch wrapper will inspect it.');
} catch (error) {
addLog(`ERROR: Failed to send activation message for token sniffing: ${error.message}`);
}
}
window.fetch = async function(...args) {
let [resource, config] = args;
let url = '';
let requestHeaders = {};
if (typeof resource === 'string') {
url = resource;
} else if (resource instanceof Request) {
url = resource.url;
}
if (config && config.headers) {
if (config.headers instanceof Headers) {
config.headers.forEach((value, key) => { requestHeaders[key.toLowerCase()] = value; });
} else {
for (const key in config.headers) { requestHeaders[key.toLowerCase()] = config.headers[key]; }
}
} else if (resource instanceof Request && resource.headers) {
resource.headers.forEach((value, key) => { requestHeaders[key.toLowerCase()] = value; });
}
const authHeaderValue = requestHeaders['authorization'];
if (authHeaderValue && typeof authHeaderValue === 'string' && authHeaderValue.startsWith('Bearer ')) {
const token = authHeaderValue.substring(7);
if (token) {
const currentStoredToken = localStorage.getItem('bearerToken');
if (token !== currentStoredToken) {
localStorage.setItem('bearerToken', token);
if (typeof window.bearerTokenGlobal !== 'undefined') window.bearerTokenGlobal = token;
if (!initialTokenLogged) {
console.log('[Kick Tools] Bearer token detected/updated from network request and stored.');
addLog(`INFO: Bearer token updated from network: ${token.substring(0,10)}...`);
initialTokenLogged = true;
}
}
}
}
return originalFetch.apply(this, args);
};
window.bearerTokenGlobal = 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() {
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', buildActualUI);
} else {
buildActualUI();
}
}
function buildActualUI() {
if (document.getElementById('kick-tools-ui')) return;
window.bearerTokenGlobal = localStorage.getItem('bearerToken') || null;
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');
const currentTokenForUI = window.bearerTokenGlobal || '';
ui.innerHTML = `
Settings
Token should be auto-detected. Use 'Set Token' to manually override or if detection fails.
`;
document.body.appendChild(ui);
addDragFunctionality(ui);
setupEventListeners();
populateSavedMessages();
updateSpamStatus();
getChatroomId();
setInterval(getChatroomId, 3000);
setInterval(updateSpamStatus, 1500);
}
function createMinimizedIcon() {
if (document.getElementById('minimized-icon')) return;
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 = `
`;
document.body.appendChild(icon);
icon.addEventListener('click', () => {
const ui = document.getElementById('kick-tools-ui');
if (ui) ui.style.display = 'flex';
icon.remove();
});
}
function addDragFunctionality(element) {
let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
const dragHandle = element.querySelector('#dragHandle');
if (!dragHandle) return;
dragHandle.onmousedown = dragMouseDown;
function dragMouseDown(e) {
if (e.target.tagName === 'BUTTON' || e.target.tagName === 'A' || e.target.closest('a')) return;
if (e.target.tagName === 'IMG' && e.target.closest('#dragHandle')) { }
else if (e.target.closest('#tab-buttons')) 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 > 100) logs.shift();
const logArea = document.getElementById('logArea');
if (logArea) {
logArea.innerHTML = logs.join('
');
logArea.scrollTop = logArea.scrollHeight;
}
}
function getChatroomId() {
try {
const scripts = Array.from(document.getElementsByTagName('script'));
const initialStateScript = scripts.find(s => s.textContent.includes('window.__INITIAL_STATE__'));
if (initialStateScript) {
const match = initialStateScript.textContent.match(/"chatroom_id":(\d+)/);
if (match && match[1]) {
const newId = match[1];
if (newId !== chatroomId) {
chatroomId = newId;
const chatIdDisplay = document.getElementById('chatIdDisplay');
if (chatIdDisplay) chatIdDisplay.textContent = chatroomId;
addLog(`DEBUG: Updated chatroom ID: ${chatroomId} (from __INITIAL_STATE__)`);
}
return;
}
}
} catch (error) {
addLog(`ERROR: Could not get chatroom ID: ${error.message}`);
}
}
function updateSpamStatus() {
const chatInputDiv = document.querySelector('div.chat-input');
let chatInputField = null;
if (chatInputDiv) {
chatInputField = chatInputDiv.querySelector('div[contenteditable="true"], textarea');
}
if (!chatInputField) {
const pointerEventsDiv = document.querySelector('div.pointer-events-none.absolute.left-2\\.5.top-1\\/2.-translate-y-1\\/2');
spamStatus = pointerEventsDiv && pointerEventsDiv.textContent.includes('Send a message') ? 'able' : 'unable';
} else {
spamStatus = chatInputField && !chatInputField.hasAttribute('disabled') ? '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('savedMessagesKickTools')) || [];
const select = document.getElementById('savedMessages');
if (!select) return;
select.innerHTML = '';
savedMessages.forEach((msg, index) => {
const option = document.createElement('option');
option.value = index;
option.text = msg.substring(0, 30) + (msg.length > 30 ? '...' : '');
select.appendChild(option);
});
}
async function sendMessages(message, count, delay, randomEmote) {
window.bearerTokenGlobal = localStorage.getItem('bearerToken') || null;
if (!window.bearerTokenGlobal) {
addLog('ERROR: No bearer token for sendMessages. Attempting active sniff now...');
await attemptToSniffTokenViaActivationMessage();
window.bearerTokenGlobal = localStorage.getItem('bearerToken') || null;
if (!window.bearerTokenGlobal) {
alert('Bearer Token is missing! Please ensure you are logged into Kick and the page is fully loaded, or set it manually.');
return;
}
}
if (!chatroomId) {
addLog('ERROR: No chatroom ID. Cannot send messages.');
alert('Chatroom ID is missing! Ensure you are on a Kick stream page with an active chat.');
return;
}
const url = `https://kick.com/api/v2/messages/send/${chatroomId}`;
const headers = {
"accept": "application/json",
"content-type": "application/json",
"Authorization": `Bearer ${window.bearerTokenGlobal}`,
"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(`INFO: Initiating ${count} message(s)`);
let successCount = 0;
let failCount = 0;
for (let i = 0; i < count; i++) {
const currentMessage = randomEmote ? randomEmotes[Math.floor(Math.random() * randomEmotes.length)] : message || "Hello from Kick Tools!";
const data = { "content": currentMessage, "type": "message" };
try {
if (delay > 0 && i > 0) {
await new Promise(resolve => setTimeout(resolve, delay));
}
const response = await originalFetch(url, {
method: 'POST',
headers: headers,
body: JSON.stringify(data),
});
if (response.ok) {
addLog(`SUCCESS: Message ${i + 1}/${count} sent. Status: ${response.status}`);
successCount++;
} else {
const errorText = await response.text();
addLog(`ERROR: Message ${i + 1}/${count} failed. Status: ${response.status}. Response: ${errorText.substring(0, 100)}`);
failCount++;
if (response.status === 401 || response.status === 403) {
addLog("ERROR: Authorization failed (401/403). Clearing stored token.");
localStorage.removeItem('bearerToken');
window.bearerTokenGlobal = null;
} else if (response.status === 429) {
addLog("ERROR: Rate limited (429). Try increasing delay or sending fewer messages.");
break;
}
}
} catch (error) {
addLog(`ERROR: Network error sending message ${i + 1}/${count}: ${error.message}`);
failCount++;
}
}
addLog(`INFO: Finished sending. Success: ${successCount}, Failed: ${failCount}.`);
}
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');
const tabContent = document.getElementById(`${button.dataset.tab}-tab`);
if (tabContent) tabContent.style.display = 'block';
tabButtons.forEach(btn => btn.style.background = '#333');
button.style.background = '#555';
if (button.dataset.tab === 'settings') {
const tokenInputField = document.getElementById('tokenInput');
if (tokenInputField) {
tokenInputField.value = localStorage.getItem('bearerToken') || '';
}
}
});
});
if (tabButtons.length > 0 && tabButtons[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) {
window.bearerTokenGlobal = manualToken;
localStorage.setItem('bearerToken', manualToken);
addLog(`INFO: Manual bearer token set: ${manualToken.substring(0, 10)}...`);
} else {
localStorage.removeItem('bearerToken');
window.bearerTokenGlobal = null;
addLog('INFO: Manual bearer token cleared.');
}
});
saveButton?.addEventListener('click', () => {
const message = messageInput.value.trim();
if (!message) return;
const savedMessages = JSON.parse(localStorage.getItem('savedMessagesKickTools')) || [];
if (!savedMessages.includes(message)) {
savedMessages.push(message);
localStorage.setItem('savedMessagesKickTools', JSON.stringify(savedMessages));
populateSavedMessages();
addLog(`INFO: Saved message: ${message.substring(0, 20)}...`);
} else {
addLog(`INFO: Message already saved: ${message.substring(0, 20)}...`);
}
});
savedMessagesSelect?.addEventListener('change', () => {
const index = savedMessagesSelect.value;
if (index !== '') {
const savedMessages = JSON.parse(localStorage.getItem('savedMessagesKickTools')) || [];
messageInput.value = savedMessages[index];
addLog(`INFO: Loaded saved message: ${savedMessages[index].substring(0, 20)}...`);
}
});
const addEmoteToInput = (emoteCode) => {
messageInput.value += ` ${emoteCode}`;
messageInput.focus();
addLog(`DEBUG: Added emote: ${emoteCode}`);
};
kekwButton?.addEventListener('click', () => addEmoteToInput('[emote:37226:KEKW]'));
patrickBooButton?.addEventListener('click', () => addEmoteToInput('[emote:37231:PatrickBoo]'));
thisIsFineButton?.addEventListener('click', () => addEmoteToInput('[emote:37236:ThisIsFine]'));
modCheckButton?.addEventListener('click', () => addEmoteToInput('[emote:37244:modCheck]'));
muteDButton?.addEventListener('click', () => addEmoteToInput('[emote:39273:MuteD]'));
weSmartButton?.addEventListener('click', () => addEmoteToInput('[emote:37239:WeSmart]'));
clearLogsButton?.addEventListener('click', () => {
logs = [];
const logArea = document.getElementById('logArea');
if (logArea) logArea.innerHTML = '';
addLog('INFO: Logs cleared');
});
minimizeButton?.addEventListener('click', () => {
const ui = document.getElementById('kick-tools-ui');
if (ui) ui.style.display = 'none';
createMinimizedIcon();
addLog('INFO: UI minimized');
});
}
if (window.bearerTokenGlobal) {
addLog(`INFO: Loaded bearer token from storage: ${(window.bearerTokenGlobal).substring(0, 10)}...`);
} else {
addLog('INFO: No bearer token in storage. Will attempt active sniff after page full load.');
if (document.readyState === 'complete') {
attemptToSniffTokenViaActivationMessage();
} else {
window.addEventListener('load', attemptToSniffTokenViaActivationMessage);
}
}
createUI();
})();