Skip to content

Instantly share code, notes, and snippets.

@taiapi
Created February 1, 2026 03:36
Show Gist options
  • Select an option

  • Save taiapi/b0a11593082f4b4664bf9181553023be to your computer and use it in GitHub Desktop.

Select an option

Save taiapi/b0a11593082f4b4664bf9181553023be to your computer and use it in GitHub Desktop.
Upload code
const fs = require("fs-extra");
const path = require("path");
const axios = require("axios");
const crypto = require("crypto");
module.exports.config = {
name: "code",
version: "1.2.5",
hasPermssion: 0,
credits: "yamato",
description: "Nhập giftcode Play Together",
commandCategory: "Tiện ích",
usages: "/code set <id> | add <id> | del <id> | list | clear | <giftcode>",
cooldowns: 5
};
const URL = "https://vgrapi-sea.vnggames.com/coordinator/api/v1/code/redeem";
const SERVER_ID = "2";
const GAME_CODE = "661";
const LOGIN_URL = "https://billing.vnggames.com/fe/api/auth/quick";
const CLIENT_KEY =
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjIjoxMDY2MSwiYSI6MTA2NjEsInMiOjF9.B08-6v9oP3rNxrvImC-WBO-AN0mru77ZNLOgqosNIjA";
const DATA_DIR = path.join(__dirname, "cache");
const DB_FILE = path.join(DATA_DIR, "pt_ids_by_thread.json");
const TEMP_FILE = path.join(DATA_DIR, "pt_redeem_temp.json");
const EXPIRE_TIME = 24 * 60 * 60 * 1000;
function uuid() {
return crypto.randomUUID();
}
function sleep(ms) {
return new Promise(r => setTimeout(r, ms));
}
function norm(s) {
return String(s || "").trim();
}
async function loadDB() {
await fs.ensureDir(DATA_DIR);
if (!(await fs.pathExists(DB_FILE))) await fs.writeJson(DB_FILE, {});
return fs.readJson(DB_FILE);
}
async function saveDB(db) {
await fs.writeJson(DB_FILE, db, { spaces: 2 });
}
async function loadTemp() {
await fs.ensureDir(DATA_DIR);
if (!(await fs.pathExists(TEMP_FILE))) await fs.writeJson(TEMP_FILE, {});
const data = await fs.readJson(TEMP_FILE);
const now = Date.now();
for (const k in data) {
if (now - data[k] > EXPIRE_TIME) delete data[k];
}
await fs.writeJson(TEMP_FILE, data);
return data;
}
async function saveTemp(d) {
await fs.writeJson(TEMP_FILE, d);
}
async function checkRoleValid(roleId) {
const data = new URLSearchParams({
platform: "mobile",
clientKey: CLIENT_KEY,
loginType: 9,
lang: "VI",
jtoken: "",
userID: "",
roleID: roleId,
roleName: roleId,
serverID: "",
getVgaId: 1
}).toString();
try {
const res = await axios.post(LOGIN_URL, data, {
headers: {
accept: "application/json, text/plain, */*",
"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
origin: "https://shop.vnggames.com",
referer: "https://shop.vnggames.com/",
"user-agent":
"Mozilla/5.0 (Linux; Android 10) AppleWebKit/537.36 Chrome/137.0.0.0 Mobile Safari/537.36"
},
timeout: 15000,
validateStatus: () => true
});
if (res.data?.returnCode !== 1) return null;
return {
id: roleId,
name: res.data?.data?.roleName || "Không rõ tên"
};
} catch {
return null;
}
}
async function getRoleName(roleId) {
const info = await checkRoleValid(roleId);
return info ? info.name : roleId;
}
async function redeemForRole(roleId, giftcode) {
const res = await axios.post(
URL,
{
serverId: SERVER_ID,
gameCode: GAME_CODE,
roleId,
roleName: roleId,
code: giftcode
},
{
headers: {
accept: "application/json, text/plain, */*",
"content-type": "application/json",
origin: "https://giftcode.vnggames.com",
referer: "https://giftcode.vnggames.com/",
"user-agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/143.0.0.0 Safari/537.36",
"x-client-region": "VN",
"x-request-id": uuid()
},
timeout: 20000,
validateStatus: () => true
}
);
const d = res.data || {};
return (
d.success === true ||
d.code === 1 ||
d.errorCode === 0 ||
String(d.message || "").toLowerCase().includes("success")
);
}
module.exports.run = async function ({ api, event, args }) {
const { threadID, messageID } = event;
const sub = (args[0] || "").toLowerCase();
const db = await loadDB();
const temp = await loadTemp();
db[threadID] = Array.isArray(db[threadID]) ? db[threadID] : [];
const saved = db[threadID];
if (sub === "list") {
if (!saved.length)
return api.sendMessage("ℹ️ Nhóm chưa có ID nào.", threadID, messageID);
return api.sendMessage(
`📌 ID đã lưu (${saved.length}):\n` +
saved.map((x, i) => `${i + 1}. ${x}`).join("\n"),
threadID,
messageID
);
}
if (sub === "clear") {
db[threadID] = [];
await saveDB(db);
return api.sendMessage("✅ Đã xoá toàn bộ ID.", threadID, messageID);
}
if (sub === "set" || sub === "add") {
const ids = args.slice(1).map(norm).filter(Boolean);
if (!ids.length)
return api.sendMessage("❎ Dùng: /code add <id1> <id2> ...", threadID, messageID);
let added = [];
let existed = [];
let invalid = [];
for (const id of ids) {
if (saved.includes(id)) {
existed.push(id);
continue;
}
const info = await checkRoleValid(id);
if (!info) {
invalid.push(id);
continue;
}
saved.push(id);
added.push(`${id} (${info.name})`);
}
db[threadID] = saved;
await saveDB(db);
let msg = "";
if (added.length)
msg += `✅ Đã thêm (${added.length}):\n${added.join("\n")}\n`;
if (existed.length)
msg += `⚠️ Đã tồn tại (${existed.length}):\n${existed.join("\n")}\n`;
if (invalid.length)
msg += `❌ Không hợp lệ (${invalid.length}):\n${invalid.join("\n")}\n`;
msg += `📦 Tổng ID: ${saved.length}`;
return api.sendMessage(msg.trim(), threadID, messageID);
}
if (sub === "del") {
const id = norm(args[1]);
if (!id) return api.sendMessage("❎ Dùng: /code del <id>", threadID, messageID);
db[threadID] = saved.filter(x => x !== id);
await saveDB(db);
return api.sendMessage(
`✅ Đã xoá ID: ${id}\nCòn lại: ${db[threadID].length}`,
threadID,
messageID
);
}
const giftcode = norm(args[0]);
if (!giftcode) {
return api.sendMessage(
"/code set <id>\n/code add <id>\n/code del <id>\n/code list\n/code clear\n/code <giftcode>",
threadID,
messageID
);
}
if (!saved.length) {
return api.sendMessage("ℹ️ Chưa có ID nào. Dùng /code add trước.", threadID, messageID);
}
api.sendMessage(
`⏳ Đang nhập code "${giftcode}" cho ${saved.length} ID...\n⏱️ Delay: 2s / 20ID`,
threadID,
messageID
);
let success = 0;
let fail = 0;
let failList = [];
for (let i = 0; i < saved.length; i++) {
const rid = saved[i];
const key = rid + "|" + giftcode;
if (temp[key]) continue;
try {
const ok = await redeemForRole(rid, giftcode);
if (ok) {
success++;
temp[key] = Date.now();
await saveTemp(temp);
} else {
fail++;
const name = await getRoleName(rid);
failList.push(name);
}
} catch {
fail++;
const name = await getRoleName(rid);
failList.push(name);
}
if ((i + 1) % 20 === 0 && i + 1 < saved.length) {
await sleep(2000);
}
}
let msg =
`🎁 Giftcode: ${giftcode}\n` +
`✅ Thành công: ${success}\n` +
`❌ Thất bại: ${fail}`;
if (failList.length)
msg += `\n📄 Nhân vật lỗi:\n` + failList.join("\n");
return api.sendMessage(msg, threadID, messageID);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment