Some checks failed
Release / semantic-release (push) Successful in 26s
tests / Unit tests (Linux, Python 3.11) (push) Successful in 9m54s
Release / build-linux (push) Failing after 7m13s
Release / build-windows (push) Has been cancelled
Release / build-macos (arm64, macos-latest) (push) Has been cancelled
Release / build-macos (x64, macos-15-intel) (push) Has been cancelled
Release / release-main (push) Has been cancelled
Release / release-develop (push) Has been cancelled
get-token.ts now writes the Remote Auth URL as a 512x512 QR image (/tmp/javis_qr.png, override via QR_OUT) in addition to printing the link, so it can be sent to the user and scanned from a second screen with the Discord mobile app. Adds the qrcode dependency.
91 lines
3.5 KiB
TypeScript
91 lines
3.5 KiB
TypeScript
/**
|
|
* Selfbot token helper — get a user-account token via Discord Remote Auth,
|
|
* WITHOUT devtools, a password, or a second screen.
|
|
*
|
|
* How it works: Discord's "scan QR to log in" is just a link of the form
|
|
* https://discord.com/ra/<code>. This script asks Discord for that link and
|
|
* prints it. Open the link on a phone that has the Discord app installed and
|
|
* approve the "New login" prompt — the token is sent back here and written to
|
|
* the repo-root .env as DISCORD_SELFBOT_TOKEN.
|
|
*
|
|
* bun run token # from bot/
|
|
*
|
|
* ⚠️ The token belongs to whatever account is logged into the Discord app that
|
|
* APPROVES the request. Switch the app to a BURNER account first — never
|
|
* approve with your main account (selfbot use can get that account banned).
|
|
*
|
|
* ⚠️ The link expires in ~2 minutes. Approve promptly.
|
|
*/
|
|
import { readFileSync, writeFileSync, existsSync } from "node:fs";
|
|
import { fileURLToPath } from "node:url";
|
|
import QRCode from "qrcode";
|
|
// Optional native peer dep; only needed for this helper.
|
|
// @ts-ignore - provided by discord.js-selfbot-v13 (optionalDependency)
|
|
import { DiscordAuthWebsocket } from "discord.js-selfbot-v13";
|
|
|
|
const ENV_PATH = fileURLToPath(new URL("../../.env", import.meta.url));
|
|
// Where to write the scannable QR image (so it can be sent to the user).
|
|
const QR_OUT = process.env.QR_OUT || "/tmp/javis_qr.png";
|
|
|
|
function upsertEnv(key: string, value: string) {
|
|
let lines: string[] = [];
|
|
if (existsSync(ENV_PATH)) {
|
|
lines = readFileSync(ENV_PATH, "utf8").split("\n");
|
|
}
|
|
const idx = lines.findIndex((l) => l.startsWith(`${key}=`));
|
|
if (idx >= 0) lines[idx] = `${key}=${value}`;
|
|
else {
|
|
if (lines.length && lines[lines.length - 1] !== "") lines.push("");
|
|
lines.push(`${key}=${value}`);
|
|
}
|
|
writeFileSync(ENV_PATH, lines.join("\n"));
|
|
}
|
|
|
|
async function main() {
|
|
const ws: any = new DiscordAuthWebsocket();
|
|
|
|
ws.on("ready", async () => {
|
|
// Render the auth URL as a scannable QR PNG. Show it on a SECOND screen
|
|
// (PC monitor) and scan it with the Discord mobile app's QR scanner.
|
|
try {
|
|
await QRCode.toFile(QR_OUT, ws.AuthURL, { width: 512, margin: 2 });
|
|
} catch (e) {
|
|
console.error("QR 생성 실패:", e);
|
|
}
|
|
console.log("\n================ DISCORD REMOTE LOGIN ================");
|
|
console.log("QR_IMAGE: " + QR_OUT);
|
|
console.log("AUTH_URL: " + ws.AuthURL);
|
|
console.log("\nPC/두 번째 화면에 위 QR을 띄우고, 디스코드 모바일 앱의 QR 스캐너로 스캔하세요");
|
|
console.log("(버너 계정으로 로그인된 상태!). 승인하면 토큰이 자동 저장됩니다.");
|
|
console.log("링크는 약 2분 후 만료됩니다.");
|
|
console.log("=====================================================\n");
|
|
});
|
|
|
|
ws.on("pending", (user: any) => {
|
|
console.log(`[remote-auth] 스캔됨: ${user?.username ?? "?"} — 폰에서 '승인'을 눌러주세요.`);
|
|
});
|
|
|
|
ws.on("finish", (token: string) => {
|
|
upsertEnv("DISCORD_SELFBOT_TOKEN", token);
|
|
console.log(`[remote-auth] ✅ 토큰 수신 — ${ENV_PATH} 의 DISCORD_SELFBOT_TOKEN 에 저장했습니다.`);
|
|
ws.destroy?.();
|
|
process.exit(0);
|
|
});
|
|
|
|
ws.on("cancel", () => {
|
|
console.log("[remote-auth] ❌ 사용자가 취소했습니다.");
|
|
process.exit(1);
|
|
});
|
|
ws.on("closed", () => {
|
|
console.log("[remote-auth] 연결 종료(만료 또는 닫힘). 다시 실행하세요.");
|
|
process.exit(1);
|
|
});
|
|
|
|
await ws.connect();
|
|
}
|
|
|
|
main().catch((e) => {
|
|
console.error("remote-auth 실패:", e);
|
|
process.exit(1);
|
|
});
|