feat: 재생 403 우회용 poToken 자동 생성·주입 (youtube-plugin 런타임 엔드포인트)
googlevideo 재생 403(스트림 거절)은 Lavalink youtube-plugin에 유효한 poToken/visitorData가 없어서 발생. 봇이 노드 ready 시점과 2시간 주기로 poToken을 생성해 Lavalink의 POST /youtube 엔드포인트에 주입한다. - scripts/potoken-refresh.mjs: youtubei.js+bgutils-js+jsdom로 생성 후 주입 (독립 ESM 프로세스) - LavalinkManager: ready 이벤트 + 2h 인터벌로 자식 프로세스 실행 - deps: bgutils-js 3.2.0, jsdom, youtubei.js 추가 / Docker base node:22-alpine Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
import { Connectors, LoadType, Shoukaku, Track } from "shoukaku";
|
||||
import { Client } from "discord.js";
|
||||
import { spawn } from "node:child_process";
|
||||
import { join } from "node:path";
|
||||
import { GuildPlayer } from "./GuildPlayer";
|
||||
import { Config } from "../utils/Config";
|
||||
import { Logger } from "../utils/Logger";
|
||||
@@ -25,10 +27,43 @@ export class LavalinkManager {
|
||||
|
||||
this.shoukaku.on("ready", (name) => {
|
||||
Logger.ready(`[LavalinkManager] 노드 [${name}] 연결 완료!`);
|
||||
// 노드가 (재)연결될 때마다 poToken 주입 — Lavalink 재시작 후에도 자동 복구
|
||||
this.refreshPoToken();
|
||||
});
|
||||
this.shoukaku.on("error", (name, err) => {
|
||||
Logger.error(`[LavalinkManager] 노드 [${name}] 에러: ${String(err)}`);
|
||||
});
|
||||
|
||||
// poToken은 수 시간 뒤 만료되므로 주기적으로 재생성/재주입 (2시간)
|
||||
setInterval(() => this.refreshPoToken(), 2 * 60 * 60 * 1000).unref();
|
||||
}
|
||||
|
||||
/**
|
||||
* googlevideo 재생 403 우회용 poToken/visitorData를 생성해 Lavalink youtube-plugin에 주입한다.
|
||||
* BotGuard 생성의 메모리 스파이크를 봇 본체와 격리하기 위해 독립 ESM 스크립트를 자식 프로세스로 실행한다.
|
||||
*/
|
||||
private refreshPoToken(): void {
|
||||
const script = join(__dirname, "..", "..", "scripts", "potoken-refresh.mjs");
|
||||
const child = spawn(process.execPath, [script], {
|
||||
env: {
|
||||
...process.env,
|
||||
LAVALINK_HOST: Config.lavalink.host,
|
||||
LAVALINK_PORT: String(Config.lavalink.port),
|
||||
LAVALINK_PW: Config.lavalink.pw,
|
||||
},
|
||||
stdio: ["ignore", "pipe", "pipe"],
|
||||
});
|
||||
let out = "";
|
||||
child.stdout?.on("data", (d) => { out += String(d); });
|
||||
child.stderr?.on("data", (d) => { out += String(d); });
|
||||
child.on("error", (err) => {
|
||||
Logger.error(`[LavalinkManager] poToken 갱신 실행 실패: ${String(err)}`);
|
||||
});
|
||||
child.on("close", (code) => {
|
||||
const msg = out.trim().split("\n").pop() ?? "";
|
||||
if (code === 0) Logger.ready(`[LavalinkManager] ${msg || "poToken 주입 완료"}`);
|
||||
else Logger.error(`[LavalinkManager] poToken 갱신 실패(code ${code}): ${msg}`);
|
||||
});
|
||||
}
|
||||
|
||||
/** 연결 가능한(CONNECTED 상태) Lavalink 노드가 하나라도 있는지 확인 */
|
||||
|
||||
Reference in New Issue
Block a user