refactor(global): token in env

This commit is contained in:
kyuuseiryuu 2026-01-29 17:37:33 +09:00
parent bedd6ccb1b
commit 979e0abf59
7 changed files with 73 additions and 61 deletions

1
.env.example Normal file
View File

@ -0,0 +1 @@
KAIQIUCC_TOKEN=''

View File

@ -1,5 +1,7 @@
services:
kaiqiu-game-info:
build: .
env_file:
- .env
ports:
- 3005:3000

View File

@ -4,7 +4,7 @@
"private": true,
"type": "module",
"scripts": {
"dev": "bun --hot src/index.tsx",
"dev": "bun --hot src/index.ts",
"build": "bun build ./src/index.html --outdir=dist --sourcemap --target=browser --minify --define:process.env.NODE_ENV='\"production\"' --env='BUN_PUBLIC_*'",
"start": "NODE_ENV=production bun src/index.tsx"
},

View File

@ -1,5 +0,0 @@
import type { Config } from "./types";
export const config: Config = {
KAIQIUCC_TOKEN: '',
};

View File

@ -1,13 +1,15 @@
import { serve } from "bun";
import { getMatchInfo, listEvent } from "./utils";
import index from "./index.html";
import { getAdvProfile, getMatchInfo, getMemberDetail, getPlayerTags, listEvent } from "./utils";
import { config } from "./config";
import { XCXAPI } from "./services/xcxApi";
if (!config.KAIQIUCC_TOKEN) {
if (!process.env.KAIQIUCC_TOKEN) {
console.error('env KAIQIUCC_TOKEN not found');
process.exit(1);
}
const xcxApi = new XCXAPI(process.env.KAIQIUCC_TOKEN ?? '');
const server = serve({
port: process.env.PORT || 3000,
routes: {
@ -28,21 +30,21 @@ const server = serve({
"/api/match/:matchId/:itemId": {
async GET(req) {
const { matchId, itemId } = req.params;
const data = await getMemberDetail(matchId, itemId);
const data = await xcxApi.getMemberDetail(matchId, itemId);
return Response.json(data);
}
},
"/api/user/:uid": {
async GET(req) {
const uid = req.params.uid;
const profile = await getAdvProfile(uid);
const profile = await xcxApi.getAdvProfile(uid);
return Response.json(profile);
},
},
"/api/user/:uid/tags": {
async GET(req) {
const uid = req.params.uid;
const profile = await getPlayerTags(uid);
const profile = await xcxApi.getPlayerTags(uid);
return Response.json(profile);
},
}

60
src/services/xcxApi.ts Normal file
View File

@ -0,0 +1,60 @@
import type { XCXMember, XCXProfile, XCXTag } from "../types";
import { BASE_URL } from "../utils";
const XCX_BASE_URL = `${BASE_URL}/xcx/public/index.php`;
export function createXCXHeader(token: string) {
const xcxDefaultHeaders = {
'token': token,
'XX-Device-Type': 'wxapp',
'content-type': 'application/json',
'Accept-Encoding': 'gzip,compress,br,deflate',
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.68(0x1800442a) NetType/WIFI Language/zh_CN',
'Referer': 'https://servicewechat.com/wxff09fb0e92aa456a/464/page-frame.html',
};
return xcxDefaultHeaders;
}
export class XCXAPI {
#defaultHeader: any;
constructor(token: string) {
this.#defaultHeader = createXCXHeader(token);
}
async getAdvProfile(uid: string) {
// return JSON.parse(fs.readFileSync(
// path.resolve(__dirname, '..', '__test__', 'data', 'profile.json'),
// ).toString()).data;
if (!/^\d+$/.test(uid)) return null;
if (!uid) return null;
const resp = await fetch(`${XCX_BASE_URL}/api/User/adv_profile?uid=${uid}`, {
headers: this.#defaultHeader,
});
const data = await resp.json();
if (data.code !== 1) return null;
return data.data as XCXProfile;
}
async getPlayerTags(uid: string) {
// return JSON.parse(fs.readFileSync(
// path.resolve(__dirname, '..', '__test__', 'data', 'profile.json'),
// ).toString()).data;
if (!/^\d+$/.test(uid)) return null;
if (!uid) return null;
const resp = await fetch(`${XCX_BASE_URL}/api/User/get_tags?uid=${uid}&limitByCount=50&getNegative=true`, {
headers: this.#defaultHeader,
});
const data = await resp.json();
if (data.code !== 1) return null;
return (data.data as XCXTag[]).filter(e => Number(e.count) > 0);
}
async getMemberDetail(matchId: string, itemId: string) {
const resp = await fetch(`${XCX_BASE_URL}/api/enter/get_member_detail?id=${itemId}&match_id=${matchId}`, {
headers: this.#defaultHeader,
});
const data = await resp.json();
if (data.code !== 1) return null;
return (data.data.list as XCXMember[]);
}
}

View File

@ -5,10 +5,8 @@ import path from 'path';
import { chunk } from 'lodash';
import type { XCXProfile } from "./types/profile";
import type { XCXTag } from "./types/tag";
import { config } from './config';
const BASE_URL = `https://kaiqiuwang.cc`;
const XCX_BASE_URL = `${BASE_URL}/xcx/public/index.php`;
export const BASE_URL = `https://kaiqiuwang.cc`;
/**
*
@ -19,15 +17,6 @@ Accept-Encoding: gzip,compress,br,deflate
User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 18_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.68(0x1800442a) NetType/WIFI Language/zh_CN
Referer: https://servicewechat.com/wxff09fb0e92aa456a/464/page-frame.html
*/
const xcxDefaultHeaders = {
'token': config.KAIQIUCC_TOKEN,
'XX-Device-Type': 'wxapp',
'content-type': 'application/json',
'Accept-Encoding': 'gzip,compress,br,deflate',
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.68(0x1800442a) NetType/WIFI Language/zh_CN',
'Referer': 'https://servicewechat.com/wxff09fb0e92aa456a/464/page-frame.html',
};
/**
* @param tagid ID
*/
@ -134,40 +123,3 @@ export function sneckGroup(size: number, groupLen: number) {
}
return newGroups;
}
export async function getAdvProfile(uid: string) {
// return JSON.parse(fs.readFileSync(
// path.resolve(__dirname, '..', '__test__', 'data', 'profile.json'),
// ).toString()).data;
if (!/^\d+$/.test(uid)) return null;
if (!uid) return null;
const resp = await fetch(`${XCX_BASE_URL}/api/User/adv_profile?uid=${uid}`, {
headers: xcxDefaultHeaders,
});
const data = await resp.json();
if (data.code !== 1) return null;
return data.data as XCXProfile;
}
export async function getPlayerTags(uid: string) {
// return JSON.parse(fs.readFileSync(
// path.resolve(__dirname, '..', '__test__', 'data', 'profile.json'),
// ).toString()).data;
if (!/^\d+$/.test(uid)) return null;
if (!uid) return null;
const resp = await fetch(`${XCX_BASE_URL}/api/User/get_tags?uid=${uid}&limitByCount=50&getNegative=true`, {
headers: xcxDefaultHeaders,
});
const data = await resp.json();
if (data.code !== 1) return null;
return (data.data as XCXTag[]).filter(e => Number(e.count) > 0);
}
export async function getMemberDetail(matchId: string, itemId: string) {
const resp = await fetch(`${XCX_BASE_URL}/api/enter/get_member_detail?id=${itemId}&match_id=${matchId}`, {
headers: xcxDefaultHeaders,
});
const data = await resp.json();
if (data.code !== 1) return null;
return (data.data.list as XCXMember[]);
}