testing / Dockerfile
nirkyy's picture
Update Dockerfile
112b97b verified
FROM node:20-slim
WORKDIR /app
RUN cat <<'EOF' > /app/package.json
{
"name": "gemini-api-server",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"start": "node index.js"
},
"dependencies": {
"axios": "^1.6.8",
"cors": "^2.8.5",
"express": "^4.19.2"
}
}
EOF
RUN npm install --only=production
RUN cat <<'EOF' > /app/index.js
const express = require('express');
const cors = require('cors');
const axios = require('axios');
const crypto = require('crypto');
const app = express();
const PORT = 7860;
const chatApiUrl = 'https://www.blackbox.ai/api/chat';
const userAgents = [
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36',
'Mozilla/5.0 (Linux; Android 13; SM-S908B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36',
'Mozilla/5.0 (iPhone; CPU iPhone OS 17_5_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Mobile/15E148 Safari/604.1',
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:126.0) Gecko/20100101 Firefox/126.0'
];
const firstNames = ['Adi', 'Budi', 'Citra', 'Dewi', 'Eka', 'Fajar', 'Gita', 'Hadi', 'Indah', 'Joko'];
const lastNames = ['Santoso', 'Wijaya', 'Kusuma', 'Lestari', 'Pratama', 'Nugroho', 'Wahyuni', 'Setiawan'];
const getRandomElement = (arr) => arr[Math.floor(Math.random() * arr.length)];
const generateRandomSession = () => {
const firstName = getRandomElement(firstNames);
const lastName = getRandomElement(lastNames);
const name = `${firstName} ${lastName}`;
const email = `${firstName.toLowerCase()}.${lastName.toLowerCase()}${Math.floor(Math.random() * 1000)}@gmail.com`;
const id = (BigInt(10**20) + BigInt(Math.floor(Math.random() * 9 * 10**20))).toString();
const expires = new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString();
return {
user: { name, email, image: `https://ui-avatars.com/api/?name=${encodeURIComponent(name)}`, id },
expires,
isNewUser: false
};
};
const createHeaders = () => {
const userAgent = getRandomElement(userAgents);
const isMobile = userAgent.includes('Mobile') || userAgent.includes('Android') || userAgent.includes('iPhone');
const platform = userAgent.includes('Win') ? '"Windows"' : userAgent.includes('Mac') ? '"macOS"' : '"Android"';
const chromeVersion = userAgent.match(/Chrome\/(\d+)/)?.[1] || '125';
const headers = {
'Accept': '*/*',
'Accept-Language': 'id-ID,id;q=0.9,en-US;q=0.8,en;q=0.7',
'Content-Type': 'application/json',
'Origin': 'https://www.blackbox.ai',
'Referer': 'https://www.blackbox.ai/',
'User-Agent': userAgent,
'Sec-Ch-Ua': `"Google Chrome";v="${chromeVersion}", "Not(A:Brand";v="8", "Chromium";v="${chromeVersion}"`,
'Sec-Ch-Ua-Mobile': isMobile ? '?1' : '?0',
'Sec-Ch-Ua-Platform': platform,
'Sec-Fetch-Dest': 'empty',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Site': 'same-origin',
'Cookie': `sessionId=${crypto.randomUUID()}`
};
return { headers, isMobile };
};
const generateId = (size = 7) => {
const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
return Array.from({ length: size }, () => alphabet[Math.floor(Math.random() * alphabet.length)]).join('');
};
const createPayload = (prompt, session, isMobile) => {
return {
messages: [{ role: "user", content: prompt, id: generateId() }],
id: generateId(),
previewToken: null,
userId: crypto.randomUUID(),
codeModelMode: true,
trendingAgentMode: {},
isMicMode: false,
userSystemPrompt: null,
maxTokens: 1024,
playgroundTopP: null,
playgroundTemperature: null,
isChromeExt: false,
githubToken: "",
clickedAnswer2: false,
clickedAnswer3: false,
clickedForceWebSearch: false,
visitFromDelta: false,
isMemoryEnabled: false,
mobileClient: isMobile,
userSelectedModel: null,
userSelectedAgent: "VscodeAgent",
validated: "a38f5889-8fef-46d4-8ede-bf4668b6a9bb",
imageGenerationMode: false,
imageGenMode: "autoMode",
webSearchModePrompt: false,
deepSearchMode: false,
promptSelection: "",
domains: null,
vscodeClient: false,
codeInterpreterMode: false,
customProfile: { name: "", occupation: "", traits: [], additionalInfo: "", enableNewChats: false },
webSearchModeOption: { autoMode: true, webMode: false, offlineMode: false },
session: session,
isPremium: false,
subscriptionCache: {
status: "FREE",
customerId: null,
expiryTimestamp: null,
lastChecked: Date.now(),
isTrialSubscription: false,
hasPaymentVerificationFailure: false,
verificationFailureTimestamp: null,
requiresAuthentication: false
},
beastMode: false,
reasoningMode: false,
designerMode: false,
workspaceId: "",
asyncMode: false,
integrations: {},
isTaskPersistent: false,
selectedElement: null
};
};
const parseApiResponse = (data) => {
const delimiter = '$~~~$';
if (typeof data === 'string' && data.includes(delimiter)) {
const parts = data.split(delimiter);
try {
return parts[2] ? parts[2].trim() : data;
} catch {
return data;
}
}
return data;
};
app.use(cors());
app.use(express.json({ limit: '50mb' }));
app.use(express.urlencoded({ extended: true, limit: '50mb' }));
app.post('/api/generate', async (req, res) => {
const { prompt } = req.body;
if (!prompt) {
return res.status(400).json({ error: 'Request body harus menyertakan "prompt"' });
}
try {
const session = generateRandomSession();
const { headers, isMobile } = createHeaders();
const payload = createPayload(prompt, session, isMobile);
const response = await axios.post(chatApiUrl, payload, { headers: headers });
const finalAnswer = parseApiResponse(response.data);
res.setHeader('Content-Type', 'text/plain');
res.send(finalAnswer);
} catch (error) {
console.error("Error pada /api/generate:", error.message);
res.status(500).send("Terjadi kesalahan pada server saat memproses permintaan.");
}
});
app.listen(PORT, () => {
console.log(`Server berjalan di http://localhost:${PORT}`);
console.log('Endpoint tersedia: POST /api/generate');
});
EOF
EXPOSE 7860
CMD ["npm", "start"]