Disclaimer This project is provided for educational and research purposes only. It demonstrates how time based Discord quest progress is reported from the client. Using this code on live services may violate platform Terms of Service and may result in penalties.
This project is a lightweight proof of concept that simulates progress for Discord quests by sending gradual, time respecting progress updates.
The implementation is intentionally minimal and focuses on:
- Realistic timing
- Incremental progress
- Avoiding instant or abnormal completion patterns
- Finds an active, enrolled, incomplete quest
- Reads the quest’s required watch duration
- Gradually advances progress using small randomized steps
- Ensures progress never exceeds reasonable time bounds
- Stops automatically once the target is reached
No UI manipulation, no auto-accept, no auto-claim logic.
- Enable Developer Tools inside discord. I recommend the PTB version of Discord when doing this
- Press Ctrl + Shift + I (or the equivalent shortcut on your system).
- Navigate to the Console tab.
- Paste the script into the console and press Enter.
Progress is simulated using the following constraints:
-
Enrollment time aware
- Progress is capped relative to how much real time has passed since enrollment
-
Randomized increments
- Each update advances by a small, non-uniform amount
-
Human like pacing
- Randomized delays are applied between updates
This produces a progress curve that closely resembles legitimate playback behavior.
Updated Feb 1, 2026
(() => {
delete window.$;
var wpReq = webpackChunkdiscord_app.push([[Symbol()], {}, r => r]);
webpackChunkdiscord_app.pop();
var StreamStore = Object.values(wpReq.c).find(m => m?.exports?.Z?.__proto__?.getStreamerActiveStreamMetadata)?.exports?.Z;
var GameStore, QuestStore, ThreadStore, GuildThreadStore, Dispatcher, HTTP;
if (!StreamStore) {
StreamStore = Object.values(wpReq.c).find(m => m?.exports?.A?.__proto__?.getStreamerActiveStreamMetadata).exports.A;
GameStore = Object.values(wpReq.c).find(m => m?.exports?.Ay?.getRunningGames).exports.Ay;
QuestStore = Object.values(wpReq.c).find(m => m?.exports?.A?.__proto__?.getQuest).exports.A;
ThreadStore = Object.values(wpReq.c).find(m => m?.exports?.A?.__proto__?.getAllThreadsForParent).exports.A;
GuildThreadStore = Object.values(wpReq.c).find(m => m?.exports?.Ay?.getSFWDefaultChannel).exports.Ay;
Dispatcher = Object.values(wpReq.c).find(m => m?.exports?.h?.__proto__?.flushWaitQueue).exports.h;
HTTP = Object.values(wpReq.c).find(m => m?.exports?.Bo?.get).exports.Bo;
} else {
GameStore = Object.values(wpReq.c).find(m => m?.exports?.ZP?.getRunningGames).exports.ZP;
QuestStore = Object.values(wpReq.c).find(m => m?.exports?.Z?.__proto__?.getQuest).exports.Z;
ThreadStore = Object.values(wpReq.c).find(m => m?.exports?.Z?.__proto__?.getAllThreadsForParent).exports.Z;
GuildThreadStore = Object.values(wpReq.c).find(m => m?.exports?.ZP?.getSFWDefaultChannel).exports.ZP;
Dispatcher = Object.values(wpReq.c).find(m => m?.exports?.Z?.__proto__?.flushWaitQueue).exports.Z;
HTTP = Object.values(wpReq.c).find(m => m?.exports?.tn?.get).exports.tn;
}
var TASKS = ["WATCH_VIDEO", "PLAY_ON_DESKTOP", "STREAM_ON_DESKTOP", "PLAY_ACTIVITY", "WATCH_VIDEO_ON_MOBILE"];
var activeQuests = [...QuestStore.quests.values()].filter(q =>
q.userStatus?.enrolledAt &&
!q.userStatus?.completedAt &&
new Date(q.config.expiresAt).getTime() > Date.now() &&
TASKS.some(t => Object.keys((q.config.taskConfig ?? q.config.taskConfigV2).tasks).includes(t))
);
var isDesktop = typeof DiscordNative !== "undefined";
if (!activeQuests.length) {
console.log("No pending quests.");
return;
}
var runNext = async () => {
var q = activeQuests.pop();
if (!q) return;
var pid = Math.floor(Math.random() * 30000) + 1000;
var appId = q.config.application.id;
var appName = q.config.application.name;
var title = q.config.messages.questName;
var cfg = q.config.taskConfig ?? q.config.taskConfigV2;
var type = TASKS.find(t => cfg.tasks[t]);
var target = cfg.tasks[type].target;
var progress = q.userStatus?.progress?.[type]?.value ?? 0;
if (type === "WATCH_VIDEO" || type === "WATCH_VIDEO_ON_MOBILE") {
var enrolled = new Date(q.userStatus.enrolledAt).getTime();
var done = false;
(async () => {
while (true) {
var max = Math.floor((Date.now() - enrolled) / 1000) + 10;
if (max - progress >= 7) {
var next = Math.min(target, progress + 7 + Math.random());
var r = await HTTP.post({ url: `/quests/${q.id}/video-progress`, body: { timestamp: next } });
done = r.body.completed_at != null;
progress = Math.min(target, progress + 7);
}
if (progress >= target) break;
await new Promise(r => setTimeout(r, 1000));
}
if (!done) {
await HTTP.post({ url: `/quests/${q.id}/video-progress`, body: { timestamp: target } });
}
console.log("Quest completed:", title);
runNext();
})();
} else if (type === "PLAY_ON_DESKTOP") {
if (!isDesktop) {
console.log("Desktop app required:", title);
return;
}
HTTP.get({ url: `/applications/public?application_ids=${appId}` }).then(res => {
var app = res.body[0];
var exe = app.executables.find(e => e.os === "win32").name.replace(">", "");
var fake = {
cmdLine: `C:\\Program Files\\${app.name}\\${exe}`,
exeName: exe,
exePath: `c:/program files/${app.name.toLowerCase()}/${exe}`,
hidden: false,
isLauncher: false,
id: appId,
name: app.name,
pid,
pidPath: [pid],
processName: app.name,
start: Date.now()
};
var realGames = GameStore.getRunningGames();
var oldA = GameStore.getRunningGames;
var oldB = GameStore.getGameForPID;
GameStore.getRunningGames = () => [fake];
GameStore.getGameForPID = p => p === pid ? fake : null;
Dispatcher.dispatch({ type: "RUNNING_GAMES_CHANGE", removed: realGames, added: [fake], games: [fake] });
var fn = d => {
var p = q.config.configVersion === 1 ? d.userStatus.streamProgressSeconds : Math.floor(d.userStatus.progress.PLAY_ON_DESKTOP.value);
if (p >= target) {
GameStore.getRunningGames = oldA;
GameStore.getGameForPID = oldB;
Dispatcher.dispatch({ type: "RUNNING_GAMES_CHANGE", removed: [fake], added: [], games: [] });
Dispatcher.unsubscribe("QUESTS_SEND_HEARTBEAT_SUCCESS", fn);
console.log("Quest completed:", title);
runNext();
}
};
Dispatcher.subscribe("QUESTS_SEND_HEARTBEAT_SUCCESS", fn);
});
} else if (type === "STREAM_ON_DESKTOP") {
if (!isDesktop) {
console.log("Desktop app required:", title);
return;
}
var real = StreamStore.getStreamerActiveStreamMetadata;
StreamStore.getStreamerActiveStreamMetadata = () => ({ id: appId, pid, sourceName: null });
var fn = d => {
var p = q.config.configVersion === 1 ? d.userStatus.streamProgressSeconds : Math.floor(d.userStatus.progress.STREAM_ON_DESKTOP.value);
if (p >= target) {
StreamStore.getStreamerActiveStreamMetadata = real;
Dispatcher.unsubscribe("QUESTS_SEND_HEARTBEAT_SUCCESS", fn);
console.log("Quest completed:", title);
runNext();
}
};
Dispatcher.subscribe("QUESTS_SEND_HEARTBEAT_SUCCESS", fn);
} else if (type === "PLAY_ACTIVITY") {
var channelId = ThreadStore.getSortedPrivateChannels()[0]?.id ??
Object.values(GuildThreadStore.getAllGuilds()).find(g => g && g.VOCAL.length).VOCAL[0].channel.id;
var key = `call:${channelId}:1`;
(async () => {
while (true) {
var r = await HTTP.post({ url: `/quests/${q.id}/heartbeat`, body: { stream_key: key, terminal: false } });
if (r.body.progress.PLAY_ACTIVITY.value >= target) {
await HTTP.post({ url: `/quests/${q.id}/heartbeat`, body: { stream_key: key, terminal: true } });
break;
}
await new Promise(r => setTimeout(r, 20000));
}
console.log("Quest completed:", title);
runNext();
})();
}
};
runNext();
})();
thanks
works perfectly