🎮 Script Complete Discord Quest

English | Español
Ver en GitHub

Cargando...

Estrellas

Cargando...

Forks

Cargando...

Issues Abiertos

Cargando...

Observadores

Licencia: MIT Funciona desde Enero 2026

¡Completa automáticamente las quests de Discord con facilidad! 🚀 Hecho por CiszukoAntony.

📋 Tabla de Contenidos

✨ Características

📋 Prerrequisitos

🚀 Instalación y Uso

Guía Paso a Paso

  1. Abre la Aplicación de Escritorio de Discord 🖥️
    Asegúrate de estar usando el cliente oficial de Discord (no web o móvil).
  2. Habilita el Modo Desarrollador ⚙️
    Ve a Configuración de Usuario > Avanzado > Modo Desarrollador y actívalo.
    Si eso no funciona, edita tu archivo de configuración:
    - Windows: %AppData%\discord\settings.json
    - Linux: ~/.config/discord/settings.json
    - macOS: ~/Library/Application Support/discord/settings.json
    Agrega esta línea: "DANGEROUS_ENABLE_DEVTOOLS_ONLY_ENABLE_IF_YOU_KNOW_WHAT_YOURE_DOING": true
    Guarda y reinicia Discord.
  3. Abre las Herramientas de Desarrollador 🛠️
    Únete a cualquier servidor y presiona Ctrl + Shift + I (o Cmd + Option + I en Mac) para abrir DevTools.
    Si el atajo no funciona, haz clic derecho en cualquier lugar y selecciona "Inspeccionar Elemento".
  4. Habilita Pegar en la Consola ⚠️
    Ve a la pestaña "Consola".
    Escribe "allow pasting" y presiona Enter. Esto permite pegar scripts largos.
  5. Copia y Pega el Script 📋
    Copia todo el script de la sección Script a continuación.
    Pégalo en la consola y presiona Enter.
  6. Monitorea el Progreso 👀
    Observa la consola para actualizaciones de progreso.
    El script completará automáticamente tus quests.
  7. Disfruta tus Recompensas 🎉
    Una vez completado, reclama tus recompensas de quest manualmente.

Notas Importantes

📜 Script

El script actualizado ahora soporta quests que no tienen ejecutable (ejemplo: Toxic Commando). Simulará el juego usando solo el nombre y el ID de la app si es necesario.

Haz clic para ver el script completo
// Script Complete Discord Quest en Español.
// Funciona desde enero de 2026.
// Hecho por CiszukoAntony.

// Instrucciones:
// 1. Abre Discord en aplicacion de escritorio.
// 2. Ve a Configuración de Usuario > Avanzado > Modo Desarrollador y actívalo.
// 3. Abre cualquier servidor y presiona Ctrl + Shift + I para abrir las herramientas de desarrollo.
// 4. ADVERTENCIA: Ve a la pestaña "Consola" escribe en el cuadro de texto "allow pasting", y presiona Enter. Esto es para permitir pegar scripts largos.
// 5. Copia y pega este script de abajo completo en la consola y presiona Enter.
// 6. Espera a que el script complete tus quests automáticamente.
// 7. Si deseas detener el script en cualquier momento, escribe "window.stopQuestScript = true" en la consola y presiona Enter.
// 8. Si deseas "windown.stopQuestScript = false" y presiona Enter para reanudar el script si lo detuviste antes de que terminara todas las quests.
// 9. ¡Disfruta de tus recompensas de Quest!

// Nota: Algunas quests requieren que estés en un canal de voz con al menos otra persona para contar el tiempo. Asegúrate de cumplir con esos requisitos para completar esas quests.

delete window.$;
window.stopQuestScript = false; // Variable global para detener el script
let wpRequire = webpackChunkdiscord_app.push([[Symbol()], {}, r => r]);
webpackChunkdiscord_app.pop();

function getStore(findFn, fallback = null) {
	try {
		return Object.values(wpRequire.c).find(findFn);
	} catch (e) {
		console.warn('Store no encontrado:', e);
		return fallback;
	}
}

let ApplicationStreamingStore = getStore(x => x?.exports?.Z?.__proto__?.getStreamerActiveStreamMetadata)?.exports?.Z ||
	getStore(x => x?.exports?.A?.__proto__?.getStreamerActiveStreamMetadata)?.exports?.A;
let RunningGameStore = getStore(x => x?.exports?.Ay?.getRunningGames)?.exports?.Ay ||
	getStore(x => x?.exports?.ZP?.getRunningGames)?.exports?.ZP;
let QuestsStore = getStore(x => x?.exports?.A?.__proto__?.getQuest)?.exports?.A ||
	getStore(x => x?.exports?.Z?.__proto__?.getQuest)?.exports?.Z;
let ChannelStore = getStore(x => x?.exports?.A?.__proto__?.getAllThreadsForParent)?.exports?.A ||
	getStore(x => x?.exports?.Z?.__proto__?.getAllThreadsForParent)?.exports?.Z;
let GuildChannelStore = getStore(x => x?.exports?.Ay?.getSFWDefaultChannel)?.exports?.Ay ||
	getStore(x => x?.exports?.ZP?.getSFWDefaultChannel)?.exports?.ZP;
let FluxDispatcher = getStore(x => x?.exports?.h?.__proto__?.flushWaitQueue)?.exports?.h ||
	getStore(x => x?.exports?.Z?.__proto__?.flushWaitQueue)?.exports?.Z;
let api = getStore(x => x?.exports?.Bo?.get)?.exports?.Bo ||
	getStore(x => x?.exports?.tn?.get)?.exports?.tn;

if (!QuestsStore || !ChannelStore || !GuildChannelStore || !FluxDispatcher || !api) {
	console.error('No se pudieron obtener los stores necesarios. El script no puede continuar.');
	return;
}

const supportedTasks = ["WATCH_VIDEO", "PLAY_ON_DESKTOP", "STREAM_ON_DESKTOP", "PLAY_ACTIVITY", "WATCH_VIDEO_ON_MOBILE"]
let quests = [];
try {
	quests = [...QuestsStore.quests.values()].filter(x => x.userStatus?.enrolledAt && !x.userStatus?.completedAt && new Date(x.config.expiresAt).getTime() > Date.now() && supportedTasks.find(y => Object.keys((x.config.taskConfig ?? x.config.taskConfigV2).tasks).includes(y)));
} catch (e) {
	console.error('Error obteniendo quests:', e);
}
let isApp = typeof DiscordNative !== "undefined"
if(quests.length === 0) {
	console.log("¡No tienes quests incompletas!")
} else {
	let doJob = function() {
		if(window.stopQuestScript) {
			console.log("Script detenido por el usuario.");
			return;
		}
		const quest = quests.pop()
		if(!quest) return

		const pid = Math.floor(Math.random() * 30000) + 1000
		
		const applicationId = quest.config.application.id
		const applicationName = quest.config.application.name
		const questName = quest.config.messages.questName
		const taskConfig = quest.config.taskConfig ?? quest.config.taskConfigV2
		const taskName = supportedTasks.find(x => taskConfig.tasks && taskConfig.tasks[x] != null)
		const secondsNeeded = taskConfig.tasks[taskName].target
		let secondsDone = quest.userStatus?.progress?.[taskName]?.value ?? 0

		if(taskName === "WATCH_VIDEO" || taskName === "WATCH_VIDEO_ON_MOBILE") {
			const maxFuture = 10, speed = 7, interval = 1
			const enrolledAt = new Date(quest.userStatus.enrolledAt).getTime()
			let completed = false
			let fn = async () => {			
				while(true) {
					if(window.stopQuestScript) {
						console.log("Script detenido durante la quest de video.");
						return;
					}
					const maxAllowed = Math.floor((Date.now() - enrolledAt)/1000) + maxFuture
					const diff = maxAllowed - secondsDone
					const timestamp = secondsDone + speed
					if(diff >= speed) {
						const res = await api.post({url: `/quests/${quest.id}/video-progress`, body: {timestamp: Math.min(secondsNeeded, timestamp + Math.random())}})
						completed = res.body.completed_at != null
						secondsDone = Math.min(secondsNeeded, timestamp)
					}
					
					if(timestamp >= secondsNeeded) {
						break
					}
					await new Promise(resolve => setTimeout(resolve, interval * 1000))
				}
				if(!completed) {
					await api.post({url: `/quests/${quest.id}/video-progress`, body: {timestamp: secondsNeeded}})
				}
				console.log("¡Quest completada!")
				doJob()
			}
			fn()
			console.log(`Falsificando video para ${questName}.`)
		} else if(taskName === "PLAY_ON_DESKTOP") {
			if(!isApp) {
				console.log("Esto ya no funciona en el navegador para quests no de video. Usa la aplicación de escritorio de Discord para completar la quest", questName, "quest!")
			} else {
				api.get({url: `/applications/public?application_ids=${applicationId}`}).then(res => {
					const appData = res.body[0]
					let exeName = appData.name;
					let fakeGame;
					if (appData.executables && Array.isArray(appData.executables)) {
						const exeWin = appData.executables.find(x => x.os === "win32");
						if (exeWin) {
							exeName = exeWin.name.replace(/>/g, "");
						}
					}
					// Spoof aunque no haya executables, usando solo el nombre y el ID
					fakeGame = {
						cmdLine: `C:\\Program Files\\${appData.name}\\${exeName}`,
						exeName,
						exePath: `c:/program files/${appData.name.toLowerCase()}/${exeName}`,
						hidden: false,
						isLauncher: false,
						id: applicationId,
						name: appData.name,
						pid: pid,
						pidPath: [pid],
						processName: appData.name,
						start: Date.now(),
					}
					const realGames = RunningGameStore.getRunningGames()
					const fakeGames = [fakeGame]
					const realGetRunningGames = RunningGameStore.getRunningGames
					const realGetGameForPID = RunningGameStore.getGameForPID
					RunningGameStore.getRunningGames = () => fakeGames
					RunningGameStore.getGameForPID = (pid) => fakeGames.find(x => x.pid === pid)
					FluxDispatcher.dispatch({type: "RUNNING_GAMES_CHANGE", removed: realGames, added: [fakeGame], games: fakeGames})
					
					let fn = data => {
						let progress = quest.config.configVersion === 1 ? data.userStatus.streamProgressSeconds : Math.floor(data.userStatus.progress.PLAY_ON_DESKTOP.value)
						console.log(`Progreso de la quest: ${progress}/${secondsNeeded}`)
						
						if(progress >= secondsNeeded) {
							console.log("¡Quest completada!")
							
							RunningGameStore.getRunningGames = realGetRunningGames
							RunningGameStore.getGameForPID = realGetGameForPID
							FluxDispatcher.dispatch({type: "RUNNING_GAMES_CHANGE", removed: [fakeGame], added: [], games: []})
							FluxDispatcher.unsubscribe("QUESTS_SEND_HEARTBEAT_SUCCESS", fn)
							
							doJob()
						}
					}
					FluxDispatcher.subscribe("QUESTS_SEND_HEARTBEAT_SUCCESS", fn)
					
					console.log(`Falsificado tu juego a ${applicationName}. Espera ${Math.ceil((secondsNeeded - secondsDone) / 60)} minutos más.`)
				})
			}
		} else if(taskName === "STREAM_ON_DESKTOP") {
			if(!isApp) {
				console.log("Esto ya no funciona en el navegador para quests no de video. Usa la aplicación de escritorio de Discord para completar la quest", questName, "quest!")
			} else {
				let realFunc = ApplicationStreamingStore.getStreamerActiveStreamMetadata
				ApplicationStreamingStore.getStreamerActiveStreamMetadata = () => ({
					id: applicationId,
					pid,
					sourceName: null
				})
				
				let fn = data => {
					let progress = quest.config.configVersion === 1 ? data.userStatus.streamProgressSeconds : Math.floor(data.userStatus.progress.STREAM_ON_DESKTOP.value)
					console.log(`Progreso de la quest: ${progress}/${secondsNeeded}`)
					
					if(progress >= secondsNeeded) {
						console.log("¡Quest completada!")
						
						ApplicationStreamingStore.getStreamerActiveStreamMetadata = realFunc
						FluxDispatcher.unsubscribe("QUESTS_SEND_HEARTBEAT_SUCCESS", fn)
						
						doJob()
					}
				}
				FluxDispatcher.subscribe("QUESTS_SEND_HEARTBEAT_SUCCESS", fn)
				
				console.log(`Falsificado tu stream a ${applicationName}. Stream cualquier ventana en vc por ${Math.ceil((secondsNeeded - secondsDone) / 60)} minutos más.`)
				console.log("¡Recuerda que necesitas al menos 1 persona más en el vc!")
			}
		} else if(taskName === "PLAY_ACTIVITY") {
			let channelId = null;
			try {
				const privChannels = ChannelStore.getSortedPrivateChannels();
				if (privChannels && privChannels.length > 0) {
					channelId = privChannels[0].id;
				} else {
					const guilds = Object.values(GuildChannelStore.getAllGuilds());
					const vocalGuild = guilds.find(x => x != null && x.VOCAL && x.VOCAL.length > 0);
					if (vocalGuild) {
						channelId = vocalGuild.VOCAL[0].channel.id;
					}
				}
			} catch (e) {
				console.error('Error obteniendo channelId:', e);
			}
			if (!channelId) {
				console.error('No se pudo obtener channelId para PLAY_ACTIVITY.');
				return;
			}
			const streamKey = `call:${channelId}:1`;
			
			let fn = async () => {
				console.log("Completando quest", questName, "-", quest.config.messages.questName)
				
				while(true) {
					if(window.stopQuestScript) {
						console.log("Script detenido durante la quest de actividad.");
						return;
					}
					const res = await api.post({url: `/quests/${quest.id}/heartbeat`, body: {stream_key: streamKey, terminal: false}})
					const progress = res.body.progress.PLAY_ACTIVITY.value
					console.log(`Progreso de la quest: ${progress}/${secondsNeeded}`)
					
					await new Promise(resolve => setTimeout(resolve, 20 * 1000))
					
					if(progress >= secondsNeeded) {
						await api.post({url: `/quests/${quest.id}/heartbeat`, body: {stream_key: streamKey, terminal: true}})
						break
					}
				}
				
				console.log("¡Quest completada! - Gracias por usar mi script - CiszukoAntony")
				doJob()
			}
			fn()
		}
	}
	doJob()
    

🎮 Comandos

📊 Seguimiento de Progreso

Monitorea el progreso de tu quest revisando los logs de la consola:

Para quests de video, también puedes revisar la barra de progreso en la pestaña Quests de Discord.

❓ Preguntas Frecuentes

¿Puedo ser baneado por usar esto?

A: Siempre hay un riesgo, aunque hasta ahora nadie ha sido baneado por esto o cosas similares como mods de cliente.

Ctrl + Shift + I no funciona

A: Descarga el cliente PTB, o usa esto para habilitar DevTools en stable.

Ctrl + Shift + I toma una captura de pantalla

A: Deshabilita el atajo de teclado en tu aplicación AMD Radeon.

Obtengo un error de sintaxis/token inesperado

A: Asegúrate de que tu navegador no esté traduciendo automáticamente este sitio web antes de copiar el script. Deshabilita cualquier extensión de traductor e intenta de nuevo.

Estoy en Vesktop pero dice que estoy usando un navegador

A: Vesktop no es un cliente de escritorio real, es un envoltorio elegante de navegador. Descarga la aplicación de escritorio real en su lugar.

Obtengo un error diferente

A: Asegúrate de copiar/pegar el script correctamente y que hayas hecho todos los pasos.

¿Puedo completar quests expiradas con esto?

A: No, no hay forma de hacerlo.

¿Puedes hacer que el script acepte automáticamente la quest/recompensa?

A: No. Ambas acciones pueden mostrar un captcha, por lo que automatizarlas no es una buena idea. Solo haz los dos clics tú mismo.

¿Puedes hacer esto un plugin de Vencord?

A: No. El script a veces requiere actualizaciones inmediatas para cambios de Discord, y el ciclo de actualización y revisión de código de Vencord sería demasiado lento para eso. Hay algunos forks de Vencord que han implementado este script o sus propios completadores de quest si realmente quieres uno.

¿Puedes subir el script independiente a un repo y hacer que el código de este gist sea una línea fetch()?

A: No. Hacer eso te pondría en riesgo porque yo (o alguien en mi cuenta) podría cambiar el código subyacente a malicioso en cualquier momento, luego forcepush y borrarlo después, y nunca lo sabrías.

📄 Licencia

Este proyecto está licenciado bajo la Licencia MIT. A continuación el texto completo de la licencia:

Licencia MIT

Copyright (c) 2024 CiszukoAntony

Se concede permiso, libre de cargos, a cualquier persona que obtenga una copia
de este software y de los archivos de documentación asociados (el "Software"), a utilizar
el Software sin restricción, incluyendo sin limitación los derechos
a usar, copiar, modificar, fusionar, publicar, distribuir, sublicenciar, y/o vender
copias del Software, y a permitir a las personas a las que se les proporcione el Software
a hacer lo mismo, sujeto a las siguientes condiciones:

El aviso de copyright anterior y este aviso de permiso se incluirán en todas
las copias o partes sustanciales del Software.

EL SOFTWARE SE PROPORCIONA "COMO ESTÁ", SIN GARANTÍA DE NINGÚN TIPO, EXPRESA O
IMPLÍCITA, INCLUYENDO PERO NO LIMITADO A GARANTÍAS DE COMERCIALIZACIÓN,
IDONEIDAD PARA UN PROPÓSITO PARTICULAR E INCUMPLIMIENTO. EN NINGÚN CASO LOS
AUTORES O PROPIETARIOS DE LOS DERECHOS DE AUTOR SERÁN RESPONSABLES DE NINGUNA
RECLAMACIÓN, DAÑOS U OTRAS RESPONSABILIDADES, YA SEA EN UNA ACCIÓN DE CONTRATO,
DELITO O DE OTRA MANERA, DERIVADAS DE, FUERA DE O EN CONEXIÓN CON EL SOFTWARE
O EL USO U OTRO TIPO DE ACCIONES EN EL SOFTWARE.

Descargo de responsabilidad: Úsalo bajo tu propio riesgo. Este script es solo para fines educativos.