gemmy.mjs
javascript•Created 20 Jan 2026, 08:30•95 views
AI Chat & Image Generator Wrapper Gemmy apk.
#ai#chatbot#smart
javascript
0 lines
/***
@ Base: https://play.google.com/store/apps/details?id=com.jetkite.gemmy
@ Author: Shannz
@ Note: AI Chat & Image Generator Wrapper Gemmy apk.
***/
import axios from 'axios';
import fs from 'fs';
import crypto from 'crypto';
import { fileTypeFromBuffer } from 'file-type';
const CONFIG = {
GEMINI: {
URL: "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-lite:generateContent",
API_KEY: "AIzaSyAKbxdxfyNoQMx9ft9xAVoQWrwpN9JnphY",
HEADERS: {
'User-Agent': 'okhttp/5.3.2',
'Accept-Encoding': 'gzip',
'x-goog-api-key': 'AIzaSyAKbxdxfyNoQMx9ft9xAVoQWrwpN9JnphY',
'x-android-package': 'com.jetkite.gemmy',
'x-android-cert': '037CD2976D308B4EFD63EC63C48DC6E7AB7E5AF2',
'content-type': 'application/json; charset=UTF-8'
}
},
IMAGEN: {
URL: "https://firebasevertexai.googleapis.com/v1beta/projects/gemmy-ai-bdc03/models/imagen-4.0-fast-generate-001:predict",
HEADERS: {
'User-Agent': 'ktor-client',
'Accept': 'application/json',
'Accept-Encoding': 'gzip',
'Content-Type': 'application/json',
'x-goog-api-key': 'AIzaSyAxof8_SbpDcww38NEQRhNh0Pzvbphh-IQ',
'x-goog-api-client': 'gl-kotlin/2.2.21-ai fire/17.7.0',
'x-firebase-appid': '1:652803432695:android:c4341db6033e62814f33f2',
'x-firebase-appversion': '91',
'x-firebase-appcheck': 'eyJlcnJvciI6IlVOS05PV05fRVJST1IifQ==',
'accept-charset': 'UTF-8'
}
}
};
// bisa di costume prompt kalo mau
const SYSTEM_INSTRUCTION = {
role: "user",
parts: [{
text: "You are a helpful assistant. Keep your answers concise. Provide no more than 3–4 paragraphs unless the user explicitly asks for a longer explanation."
}]
};
const uploadToCloud = async (buffer) => {
try {
const filename = `gemmy-${crypto.randomUUID()}.png`;
const { data } = await axios.post('https://api.cloudsky.biz.id/get-upload-url', {
fileKey: filename,
contentType: 'image/png',
fileSize: buffer.length
});
await axios.put(data.uploadUrl, buffer, {
headers: {
'Content-Type': 'image/png',
'Content-Length': buffer.length,
'x-amz-server-side-encryption': 'AES256'
}
});
return `https://api.cloudsky.biz.id/file?key=${encodeURIComponent(filename)}`;
} catch (error) {
console.error(`[Cloud Upload Error]: ${error.message}`);
return null;
}
};
const toBase64 = async (input) => {
try {
let buffer;
if (Buffer.isBuffer(input)) {
buffer = input;
} else if (input.startsWith('http')) {
const res = await axios.get(input, { responseType: 'arraybuffer' });
buffer = Buffer.from(res.data);
} else if (fs.existsSync(input)) {
buffer = fs.readFileSync(input);
} else {
return null;
}
return buffer.toString('base64');
} catch (e) { return null; }
};
const getMimeType = (pathOrUrl) => {
const ext = pathOrUrl.split('.').pop().toLowerCase();
const mimes = { 'jpg': 'image/jpeg', 'jpeg': 'image/jpeg', 'png': 'image/png', 'webp': 'image/webp' };
return mimes[ext] || 'application/octet-stream';
};
export const gemmy = {
chat: async (prompt, history = [], media = null) => {
try {
let parts = [];
if (media) {
const base64Data = await toBase64(media);
if (base64Data) {
const isImage = typeof media === 'string' && /\.(jpg|jpeg|png|webp)$/i.test(media);
if (isImage) {
parts.push({
inlineData: {
mimeType: getMimeType(media),
data: base64Data
}
});
parts.push({ text: prompt });
} else {
const decodedText = Buffer.from(base64Data, 'base64').toString('utf-8');
parts.push({
text: `${prompt}\n\n--- DOCUMENT CONTENT ---\n\n${decodedText}`
});
}
} else {
parts.push({ text: prompt });
}
} else {
parts.push({ text: prompt });
}
const newHistory = [
...history,
{
role: "user",
parts: parts
}
];
const payload = {
contents: newHistory,
generationConfig: {
maxOutputTokens: 800,
temperature: 0.9
},
systemInstruction: SYSTEM_INSTRUCTION
};
const response = await axios.post(CONFIG.GEMINI.URL, payload, {
headers: CONFIG.GEMINI.HEADERS
});
const result = response.data;
if (result.candidates && result.candidates.length > 0) {
const reply = result.candidates[0].content;
newHistory.push(reply);
return {
success: true,
reply: reply.parts[0].text,
history: newHistory,
usage: result.usageMetadata
};
}
return { success: false, msg: 'No response candidates found' };
} catch (error) {
console.error(`[Gemini Chat Error]: ${error.message}`);
return { success: false, msg: error.message };
}
},
generateImage: async (prompt, options = {}) => {
try {
const payload = {
instances: [
{ prompt: prompt }
],
parameters: {
sampleCount: 1,
includeRaiReason: true,
includeSafetyAttributes: true,
aspectRatio: options.aspectRatio || "1:1",
safetySetting: "block_low_and_above",
personGeneration: "allow_adult",
imageOutputOptions: {
mimeType: "image/jpeg",
compressionQuality: 100
}
}
};
const response = await axios.post(CONFIG.IMAGEN.URL, payload, {
headers: CONFIG.IMAGEN.HEADERS
});
const predictions = response.data.predictions;
if (predictions && predictions.length > 0 && predictions[0].bytesBase64Encoded) {
const imgBuffer = Buffer.from(predictions[0].bytesBase64Encoded, 'base64');
const url = await uploadToCloud(imgBuffer);
if (url) {
return {
success: true,
url: url,
safetyAttributes: predictions[0].safetyAttributes
};
} else {
return { success: false, msg: 'Failed to upload image to cloud' };
}
}
return { success: false, msg: 'No image generated' };
} catch (error) {
console.error(`[Imagen Error]: ${error.message}`);
return { success: false, msg: error.message };
}
}
};
/*
(async () => {
// 1. Contoh Chat Biasa
console.log("--- Tes Chat ---");
let chatRes = await gemmy.chat("Siapa itu Jokowi?");
console.log("Bot:", chatRes.reply);
// Simpan history untuk konteks selanjutnya
let myHistory = chatRes.history;
// 2. Contoh Chat dengan Gambar
console.log("\n--- Tes Vision ---");
let visionRes = await gemmy.chat(
"Gambar apa ini? dan apakah ada hubungannya dengan pertanyaan saya sebelumnya?",
myHistory, //history sebelumnya
"./u.jpg" //bisa path bisa url
);
console.log("Bot Vision:", visionRes.reply);
// 3. Contoh Chat dengan file
console.log("\n--- Tes Dengan File ---");
let fileRes = await gemmy.chat(
"Tolong jelaskan apa fungsi file ini dan dependency apa saja yang dipakai?",
[], // tanpa history
"./s.py" // file nya wajib path
);
console.log("Bot File:", fileRes.reply);
// 4. Contoh Generate Image (Imagen)
console.log("\n--- Tes Generate Image ---");
let imgRes = await gemmy.generateImage(
"cyberpunk cat neon lights",
{ aspectRatio: "16:9" } //opsional bisa di sesuaikan ukurannya
);
console.log("Image URL:", imgRes.url);
})();
*/