convertified
This commit is contained in:
7
pyapi/start.sh
Executable file
7
pyapi/start.sh
Executable file
@@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# FastAPI Proxy Server Startup Script
|
||||||
|
# This script starts the FastAPI proxy server that bypasses Cloudflare
|
||||||
|
|
||||||
|
echo "Starting FastAPI Proxy Server on port 3070..."
|
||||||
|
uv run python -m fastapi dev --port=3070 main.py
|
||||||
47
src/lib/server/external/api.scraping.helpers.ts
vendored
47
src/lib/server/external/api.scraping.helpers.ts
vendored
@@ -1,4 +1,4 @@
|
|||||||
import { getRandomUserAgent, getULID, sleep } from "$lib/utils";
|
import { getULID, sleep } from "$lib/utils";
|
||||||
import { constants } from "$lib/utils/constants";
|
import { constants } from "$lib/utils/constants";
|
||||||
import type { BookingEntry, Draw, LooseApiUser } from "$lib/utils/data.types";
|
import type { BookingEntry, Draw, LooseApiUser } from "$lib/utils/data.types";
|
||||||
import { rng } from "$lib/utils/rng";
|
import { rng } from "$lib/utils/rng";
|
||||||
@@ -15,12 +15,10 @@ import { rng } from "$lib/utils/rng";
|
|||||||
export const testIfSessionIsValid = async (jwt: string) => {
|
export const testIfSessionIsValid = async (jwt: string) => {
|
||||||
try {
|
try {
|
||||||
const res = await fetch(
|
const res = await fetch(
|
||||||
`${constants.SCRAP_API_URL}/v1/user/get-balance?userId=6339`,
|
`${constants.PROXY_API_URL}/v1/user/get-balance?userId=6339&authorization=${encodeURIComponent(jwt)}`,
|
||||||
{
|
{
|
||||||
headers: {
|
headers: {
|
||||||
...constants.SCRAP_API_BASE_HEADERS,
|
"Content-Type": "application/json",
|
||||||
Authorization: jwt,
|
|
||||||
"User-Agent": getRandomUserAgent(),
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@@ -49,11 +47,9 @@ export const getSessionToken = async (payload: {
|
|||||||
userType: number;
|
userType: number;
|
||||||
}): Promise<{ ok: boolean; message: string }> => {
|
}): Promise<{ ok: boolean; message: string }> => {
|
||||||
console.log("Requesting...");
|
console.log("Requesting...");
|
||||||
const res = await fetch(`${constants.SCRAP_API_URL}/v1/auth/login`, {
|
const res = await fetch(`${constants.PROXY_API_URL}/v1/auth/login`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
...constants.SCRAP_API_BASE_HEADERS,
|
|
||||||
"User-Agent": getRandomUserAgent(),
|
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
},
|
},
|
||||||
body: JSON.stringify(payload),
|
body: JSON.stringify(payload),
|
||||||
@@ -68,12 +64,10 @@ export const getSessionToken = async (payload: {
|
|||||||
export async function getUsersBalance(userId: number, jwt: string) {
|
export async function getUsersBalance(userId: number, jwt: string) {
|
||||||
try {
|
try {
|
||||||
const res = await fetch(
|
const res = await fetch(
|
||||||
`${constants.SCRAP_API_URL}/v1/user/get-balance?userId=${userId}`,
|
`${constants.PROXY_API_URL}/v1/user/get-balance?userId=${userId}&authorization=${encodeURIComponent(jwt)}`,
|
||||||
{
|
{
|
||||||
headers: {
|
headers: {
|
||||||
...constants.SCRAP_API_BASE_HEADERS,
|
"Content-Type": "application/json",
|
||||||
Authorization: jwt,
|
|
||||||
"User-Agent": getRandomUserAgent(),
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@@ -85,9 +79,7 @@ export async function getUsersBalance(userId: number, jwt: string) {
|
|||||||
time: string;
|
time: string;
|
||||||
};
|
};
|
||||||
if (res.status !== 200 || rj.code !== 200 || !rj.success) {
|
if (res.status !== 200 || rj.code !== 200 || !rj.success) {
|
||||||
console.log(
|
console.log(`[!] Error getting balance for ${userId} :: ${JSON.stringify(rj)}`);
|
||||||
`[!] Error getting balance for ${userId} :: ${JSON.stringify(rj)}`,
|
|
||||||
);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return rj.data.balance;
|
return rj.data.balance;
|
||||||
@@ -103,14 +95,11 @@ export const getDealers = async (jwt: string, distributor_ids: string[]) => {
|
|||||||
const requests = distributor_ids.map(async (did) => {
|
const requests = distributor_ids.map(async (did) => {
|
||||||
await sleep(rng(100, 10000));
|
await sleep(rng(100, 10000));
|
||||||
const res = await fetch(
|
const res = await fetch(
|
||||||
`${constants.SCRAP_API_URL}/v1/user/dealer-list`,
|
`${constants.PROXY_API_URL}/v1/user/dealer-list?authorization=${encodeURIComponent(jwt)}`,
|
||||||
{
|
{
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
...constants.SCRAP_API_BASE_HEADERS,
|
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
"User-Agent": getRandomUserAgent(),
|
|
||||||
Authorization: jwt,
|
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
page: 1,
|
page: 1,
|
||||||
@@ -175,14 +164,11 @@ export const getDealers = async (jwt: string, distributor_ids: string[]) => {
|
|||||||
|
|
||||||
export const getDistributors = async (jwt: string) => {
|
export const getDistributors = async (jwt: string) => {
|
||||||
const res = await fetch(
|
const res = await fetch(
|
||||||
`${constants.SCRAP_API_URL}/v1/user/distributor-list`,
|
`${constants.PROXY_API_URL}/v1/user/distributor-list?authorization=${encodeURIComponent(jwt)}`,
|
||||||
{
|
{
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
...constants.SCRAP_API_BASE_HEADERS,
|
|
||||||
Authorization: jwt,
|
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
"User-Agent": getRandomUserAgent(),
|
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
page: 1,
|
page: 1,
|
||||||
@@ -218,14 +204,11 @@ export const getDistributors = async (jwt: string) => {
|
|||||||
|
|
||||||
export const getDraws = async (jwt: string) => {
|
export const getDraws = async (jwt: string) => {
|
||||||
const res = await fetch(
|
const res = await fetch(
|
||||||
`${constants.SCRAP_API_URL}/v1/draw/list-my?userId=15`,
|
`${constants.PROXY_API_URL}/v1/draw/list-my?userId=15&authorization=${encodeURIComponent(jwt)}`,
|
||||||
{
|
{
|
||||||
method: "GET",
|
method: "GET",
|
||||||
headers: {
|
headers: {
|
||||||
...constants.SCRAP_API_BASE_HEADERS,
|
|
||||||
Authorization: jwt,
|
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
"User-Agent": getRandomUserAgent(),
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@@ -253,13 +236,12 @@ export const getData = async (
|
|||||||
drawId: number,
|
drawId: number,
|
||||||
chosenDate: string,
|
chosenDate: string,
|
||||||
) => {
|
) => {
|
||||||
const res = await fetch(`${constants.SCRAP_API_URL}/v1/book/list2`, {
|
const res = await fetch(
|
||||||
|
`${constants.PROXY_API_URL}/v1/book/list2?authorization=${encodeURIComponent(jwt)}`,
|
||||||
|
{
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
...constants.SCRAP_API_BASE_HEADERS,
|
|
||||||
Authorization: jwt,
|
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
"User-Agent": getRandomUserAgent(),
|
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
userType: 3,
|
userType: 3,
|
||||||
@@ -271,7 +253,8 @@ export const getData = async (
|
|||||||
containImported: false,
|
containImported: false,
|
||||||
keyword: "",
|
keyword: "",
|
||||||
}),
|
}),
|
||||||
});
|
},
|
||||||
|
);
|
||||||
type J = {
|
type J = {
|
||||||
code: number;
|
code: number;
|
||||||
success: boolean;
|
success: boolean;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { getRandomUserAgent, getULID, sleep } from "$lib/utils";
|
import { getULID, sleep } from "$lib/utils";
|
||||||
import { constants } from "$lib/utils/constants";
|
import { constants } from "$lib/utils/constants";
|
||||||
import type {
|
import type {
|
||||||
ApiPostUserWithParent,
|
ApiPostUserWithParent,
|
||||||
@@ -7,8 +7,6 @@ import type {
|
|||||||
PostDataEntry,
|
PostDataEntry,
|
||||||
ServerError,
|
ServerError,
|
||||||
} from "$lib/utils/data.types";
|
} from "$lib/utils/data.types";
|
||||||
import Fetch from "node-fetch";
|
|
||||||
import { HttpsProxyAgent } from "https-proxy-agent";
|
|
||||||
|
|
||||||
export type APIResponse<T> = {
|
export type APIResponse<T> = {
|
||||||
code: number;
|
code: number;
|
||||||
@@ -72,9 +70,7 @@ export async function postDataToApi(payload: {
|
|||||||
return {
|
return {
|
||||||
ok: false,
|
ok: false,
|
||||||
detail: "User not found to post data with",
|
detail: "User not found to post data with",
|
||||||
errors: [
|
errors: [{ message: "User not found for request" }] as ServerError,
|
||||||
{ message: "User not found for request" },
|
|
||||||
] as ServerError,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (!dataByUser[userId]) {
|
if (!dataByUser[userId]) {
|
||||||
@@ -84,14 +80,11 @@ export async function postDataToApi(payload: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const userPromises = Object.entries(dataByUser).map(
|
const userPromises = Object.entries(dataByUser).map(async ([userId, userData]) => {
|
||||||
async ([userId, userData]) => {
|
|
||||||
const session = payload.sessions[userId];
|
const session = payload.sessions[userId];
|
||||||
const usr = payload.users.find((u) => u.userId === userId);
|
const usr = payload.users.find((u) => u.userId === userId);
|
||||||
if (!usr) {
|
if (!usr) {
|
||||||
throw new Error(
|
throw new Error(`User ${userId} not found for posting to api`);
|
||||||
`User ${userId} not found for posting to api`,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const distId = usr.parentDistributor ?? 0;
|
const distId = usr.parentDistributor ?? 0;
|
||||||
@@ -116,13 +109,7 @@ export async function postDataToApi(payload: {
|
|||||||
drawId,
|
drawId,
|
||||||
date,
|
date,
|
||||||
);
|
);
|
||||||
const res = await sendBatchRequest(
|
const res = await sendBatchRequest(session, dealerId, payload.draw, total, message);
|
||||||
session,
|
|
||||||
dealerId,
|
|
||||||
payload.draw,
|
|
||||||
total,
|
|
||||||
message,
|
|
||||||
);
|
|
||||||
let rj:
|
let rj:
|
||||||
| APIResponse<{
|
| APIResponse<{
|
||||||
bookDtos: {
|
bookDtos: {
|
||||||
@@ -134,9 +121,7 @@ export async function postDataToApi(payload: {
|
|||||||
try {
|
try {
|
||||||
rj = (await res.json()) as any;
|
rj = (await res.json()) as any;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(
|
console.log("Encountered error while parsing post response");
|
||||||
"Encountered error while parsing post response",
|
|
||||||
);
|
|
||||||
console.log(res.status, err);
|
console.log(res.status, err);
|
||||||
}
|
}
|
||||||
if (rj && rj.code === 200 && res.status === 200) {
|
if (rj && rj.code === 200 && res.status === 200) {
|
||||||
@@ -167,14 +152,11 @@ export async function postDataToApi(payload: {
|
|||||||
});
|
});
|
||||||
console.log(await out.text());
|
console.log(await out.text());
|
||||||
}
|
}
|
||||||
throw new Error(
|
throw new Error(`Failed to send data to api for user ${userId}`);
|
||||||
`Failed to send data to api for user ${userId}`,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return userResponseIds;
|
return userResponseIds;
|
||||||
},
|
});
|
||||||
);
|
|
||||||
|
|
||||||
// Wait for all user processes to complete
|
// Wait for all user processes to complete
|
||||||
const results = await Promise.allSettled(userPromises);
|
const results = await Promise.allSettled(userPromises);
|
||||||
@@ -195,9 +177,7 @@ export async function postDataToApi(payload: {
|
|||||||
return {
|
return {
|
||||||
ok: false,
|
ok: false,
|
||||||
detail: "Failed to post data to API for some users",
|
detail: "Failed to post data to API for some users",
|
||||||
errors: [
|
errors: [{ message: "Failed to post data to API for some users" }] as ServerError,
|
||||||
{ message: "Failed to post data to API for some users" },
|
|
||||||
] as ServerError,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,14 +205,12 @@ async function sendBatchRequest(
|
|||||||
changedBalance: number,
|
changedBalance: number,
|
||||||
body: string,
|
body: string,
|
||||||
) {
|
) {
|
||||||
return Fetch(`${constants.SCRAP_API_URL}/v1/book/add-multiple`, {
|
return fetch(
|
||||||
agent: new HttpsProxyAgent(`http://${session.ip}`),
|
`${constants.PROXY_API_URL}/v1/book/add-multiple?authorization=${encodeURIComponent(session.sessionToken)}`,
|
||||||
|
{
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
...constants.SCRAP_API_BASE_HEADERS,
|
"Content-Type": "application/json",
|
||||||
"Content-Type": "application/json;charset=UTF-8",
|
|
||||||
Authorization: session.sessionToken,
|
|
||||||
"User-Agent": getRandomUserAgent(),
|
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
dealerId,
|
dealerId,
|
||||||
@@ -242,7 +220,8 @@ async function sendBatchRequest(
|
|||||||
changedBalance,
|
changedBalance,
|
||||||
insertData: body,
|
insertData: body,
|
||||||
}),
|
}),
|
||||||
});
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function mockSendBatchRequest(
|
async function mockSendBatchRequest(
|
||||||
@@ -313,14 +292,12 @@ async function deleteAllBookedEntries({
|
|||||||
drawId: number;
|
drawId: number;
|
||||||
closeTime: string;
|
closeTime: string;
|
||||||
}) {
|
}) {
|
||||||
return Fetch(`${constants.SCRAP_API_URL}/v1/book/delete-multiple`, {
|
return fetch(
|
||||||
agent: new HttpsProxyAgent(`http://${session.ip}`),
|
`${constants.PROXY_API_URL}/v1/book/delete-multiple?authorization=${encodeURIComponent(session.sessionToken)}`,
|
||||||
|
{
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
...constants.SCRAP_API_BASE_HEADERS,
|
"Content-Type": "application/json",
|
||||||
"Content-Type": "application/json;charset=UTF-8",
|
|
||||||
Authorization: session.sessionToken,
|
|
||||||
"User-Agent": getRandomUserAgent(),
|
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
bookIds: data.map((e) => e.bookId),
|
bookIds: data.map((e) => e.bookId),
|
||||||
@@ -328,7 +305,8 @@ async function deleteAllBookedEntries({
|
|||||||
dealerId,
|
dealerId,
|
||||||
drawId,
|
drawId,
|
||||||
}),
|
}),
|
||||||
});
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// export async function postDataToApi(payload: {
|
// export async function postDataToApi(payload: {
|
||||||
|
|||||||
@@ -1,30 +1,26 @@
|
|||||||
import { getSessionToken } from "$lib/server/external/api.scraping.helpers";
|
|
||||||
import { TRPCError } from "@trpc/server";
|
|
||||||
import { createTRPCRouter, protectedProcedure } from "../t";
|
|
||||||
import { constants } from "$lib/utils/constants";
|
|
||||||
import { getUUID } from "$lib/utils";
|
|
||||||
import { z } from "zod";
|
|
||||||
import { dbApiUser } from "$lib/server/db/apiuser.db";
|
import { dbApiUser } from "$lib/server/db/apiuser.db";
|
||||||
import type { ServerError } from "$lib/utils/data.types";
|
import { getSessionToken } from "$lib/server/external/api.scraping.helpers";
|
||||||
import {
|
import {
|
||||||
isSessionValidInStore,
|
isSessionValidInStore,
|
||||||
removeSessionFromStore,
|
removeSessionFromStore,
|
||||||
setSessionToRedis,
|
setSessionToRedis,
|
||||||
} from "$lib/server/utils/session.service";
|
} from "$lib/server/utils/session.service";
|
||||||
|
import { getUUID } from "$lib/utils";
|
||||||
|
import { constants } from "$lib/utils/constants";
|
||||||
|
import type { ServerError } from "$lib/utils/data.types";
|
||||||
|
import { TRPCError } from "@trpc/server";
|
||||||
|
import { z } from "zod";
|
||||||
|
import { createTRPCRouter, protectedProcedure } from "../t";
|
||||||
|
|
||||||
export const apiAuthRouter = createTRPCRouter({
|
export const apiAuthRouter = createTRPCRouter({
|
||||||
getCaptcha: protectedProcedure.mutation(async () => {
|
getCaptcha: protectedProcedure.mutation(async () => {
|
||||||
try {
|
try {
|
||||||
const uuid = getUUID();
|
const uuid = getUUID();
|
||||||
const res = await fetch(
|
const res = await fetch(`${constants.PROXY_API_URL}/verify/image?uuid=${uuid}`, {
|
||||||
`${constants.SCRAP_API_URL}/verify/image?uuid=${uuid}`,
|
|
||||||
{
|
|
||||||
headers: {
|
headers: {
|
||||||
...constants.SCRAP_API_BASE_HEADERS,
|
"Content-Type": "application/json",
|
||||||
Accept: "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8",
|
|
||||||
},
|
},
|
||||||
},
|
});
|
||||||
);
|
|
||||||
const bloob = await res.blob();
|
const bloob = await res.blob();
|
||||||
const imageBuffer = Buffer.from(await bloob.arrayBuffer());
|
const imageBuffer = Buffer.from(await bloob.arrayBuffer());
|
||||||
const base64String = imageBuffer.toString("base64");
|
const base64String = imageBuffer.toString("base64");
|
||||||
@@ -50,8 +46,7 @@ export const apiAuthRouter = createTRPCRouter({
|
|||||||
console.log("[=] Getting new session... ", input);
|
console.log("[=] Getting new session... ", input);
|
||||||
try {
|
try {
|
||||||
const { captchaId, captchaAnswer } = input;
|
const { captchaId, captchaAnswer } = input;
|
||||||
let { userId, userType, password } =
|
let { userId, userType, password } = await dbApiUser.getRandomDistributor();
|
||||||
await dbApiUser.getRandomDistributor();
|
|
||||||
|
|
||||||
if (input.userId) {
|
if (input.userId) {
|
||||||
let _user = await dbApiUser.getUserById(input.userId);
|
let _user = await dbApiUser.getUserById(input.userId);
|
||||||
@@ -74,10 +69,7 @@ export const apiAuthRouter = createTRPCRouter({
|
|||||||
userType: userType,
|
userType: userType,
|
||||||
password: password,
|
password: password,
|
||||||
});
|
});
|
||||||
console.log(
|
console.log("[=] Token Response :: ", JSON.stringify(token, null, 2));
|
||||||
"[=] Token Response :: ",
|
|
||||||
JSON.stringify(token, null, 2),
|
|
||||||
);
|
|
||||||
if (!token.ok) {
|
if (!token.ok) {
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ export const constants = {
|
|||||||
POST_SESSION_KEY: "postsession",
|
POST_SESSION_KEY: "postsession",
|
||||||
LAST_FETCHED_KEY: "LAST_FETCHED",
|
LAST_FETCHED_KEY: "LAST_FETCHED",
|
||||||
SCRAP_API_URL: "https://gamebooking24.com/lottery-api",
|
SCRAP_API_URL: "https://gamebooking24.com/lottery-api",
|
||||||
|
PROXY_API_URL: "http://localhost:3070",
|
||||||
SCRAP_API_SESSION_KEY: "SRAJWT",
|
SCRAP_API_SESSION_KEY: "SRAJWT",
|
||||||
SCRAP_API_BASE_HEADERS: {
|
SCRAP_API_BASE_HEADERS: {
|
||||||
Host: "gamebooking24.com",
|
Host: "gamebooking24.com",
|
||||||
|
|||||||
Reference in New Issue
Block a user