aiease.mjs

Ai filter style generator.

#ai#image#generator
17
26 Des 2025, 07:10
RawEdit
javascript0 lines
/***
  @ Base: https://www.aiease.ai/
  @ Author: Shannz
  @ Note: AI Filter Style Generator
***/

import axios from 'axios';
import crypto from 'crypto';
import fs from 'fs';

const CONFIG = {
    BASE_URL: "https://www.aiease.ai",
    API: {
        FILTER: "/api/api/common/ai_filter_style",
        VISIT: "/api/api/user/visit",
        UPLOAD: "/api/api/id_photo/s",
        IMG2IMG: "/api/api/gen/img2img",
        TASK: "/api/api/id_photo/task-info"
    },
    SECRET: "Q@D24=oueV%]OBS8i,%eK=5I|7WU$PeE",
    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.aiease.ai",
        "Referer": "https://www.aiease.ai/",
        "User-Agent": "ScRaPe/9.9 (KaliLinux; Nusantara Os; My/Shannz)"
    }
};

const cryptoUtils = () => {
    const keyHash = crypto.createHash("SHA256").update(CONFIG.SECRET).digest();

    return {
        encrypt: (payload) => {
            try {
                const encoded = encodeURIComponent(payload);
                const iv = crypto.randomBytes(16);
                const cipher = crypto.createCipheriv("aes-256-cfb", keyHash, iv);
                const encrypted = Buffer.concat([cipher.update(encoded, "utf-8"), cipher.final()]);
                return Buffer.concat([iv, encrypted]).toString("base64");
            } catch (e) { return null; }
        },
        decrypt: (encryptedBase64) => {
            try {
                const buffer = Buffer.from(encryptedBase64, "base64");
                const iv = buffer.subarray(0, 16);
                const data = buffer.subarray(16);
                const decipher = crypto.createDecipheriv("aes-256-cfb", keyHash, iv);
                const decrypted = Buffer.concat([decipher.update(data), decipher.final()]);
                return decodeURIComponent(decrypted.toString("utf-8"));
            } catch (e) { return null; }
        }
    };
};

const utils = cryptoUtils();

export const aiease = {
    getFilters: async () => {
        try {
            const response = await axios.get(CONFIG.BASE_URL + CONFIG.API.FILTER, {
                headers: CONFIG.HEADERS
            });
            return response.data;
        } catch (error) {
            console.error(`error getFilters: ${error.message}`);
            return null;
        }
    },

    generate: async (input, filterId) => {
        try {
            let imageBuffer;
            if (Buffer.isBuffer(input)) {
                imageBuffer = input;
            } else if (input.startsWith('http')) {
                const bufRes = await axios.get(input, { responseType: 'arraybuffer' });
                imageBuffer = Buffer.from(bufRes.data);
            } else if (fs.existsSync(input)) {
                imageBuffer = fs.readFileSync(input);
            } else {
                return 'Gambar tidak ditemukan.';
            }

            const visitRes = await axios.post(CONFIG.BASE_URL + CONFIG.API.VISIT, {}, { headers: CONFIG.HEADERS });
            const token = visitRes.data?.result?.user?.token;
            if (!token) return 'Gagal mendapatkan token sesi.';

            const authHeaders = { ...CONFIG.HEADERS, "Authorization": `JWT ${token}` };

            const uploadPayload = {
                length: imageBuffer.length,
                filetype: "image/jpeg",
                filename: `${crypto.randomBytes(5).toString("hex")}_syn.jpeg`
            };
            
            const sig = utils.encrypt(JSON.stringify(uploadPayload));
            const uploadSlotRes = await axios.post(
                CONFIG.BASE_URL + CONFIG.API.UPLOAD, 
                JSON.stringify({ t: sig }), 
                { 
                    headers: authHeaders,
                    params: { time: crypto.randomUUID().toString() }
                }
            );

            const decryptedUrl = utils.decrypt(uploadSlotRes.data.result);
            if (!decryptedUrl) return 'Gagal dekripsi URL upload.';

            await axios.put(decryptedUrl, imageBuffer, {
                headers: { ...CONFIG.HEADERS, "Content-Type": "image/jpeg" }
            });

            const urlObj = new URL(decryptedUrl);
            const cleanUrl = urlObj.origin + urlObj.pathname;
            
            const genPayload = {
                gen_type: "ai_filter",
                ai_filter_extra_data: {
                    img_url: cleanUrl,
                    style_id: filterId
                }
            };
            
            const genRes = await axios.post(CONFIG.BASE_URL + CONFIG.API.IMG2IMG, genPayload, { headers: authHeaders });
            const taskId = genRes.data?.result?.task_id;
            if (!taskId) return 'Gagal memulai task AI.';

            let resultUrl = null;
            let attempts = 0;
            const maxAttempts = 30;
            let currentStatus = "processing"; 

            while (attempts < maxAttempts) {
                const dots = ".".repeat((attempts % 4) + 1);
                process.stdout.write(`\r[Polling] Status: ${currentStatus}${dots}   `);

                await new Promise(r => setTimeout(r, 4000));
                
                const taskRes = await axios.get(CONFIG.BASE_URL + CONFIG.API.TASK, {
                    headers: authHeaders,
                    params: { task_id: taskId }
                });

                const data = taskRes.data;
                currentStatus = data.result?.data?.queue_info?.status || 'unknown';

                if (currentStatus === 'success') {
                    process.stdout.write('\n');
                    resultUrl = data; 
                    break;
                }
                attempts++;
            }
            
            if (!resultUrl) process.stdout.write('\n');

            return resultUrl || 'Timeout generating image.';

        } catch (error) {
            process.stdout.write('\n');
            console.error(`error generate: ${error.message}`);
            if (error.response) console.error(error.response.data);
            return null;
        }
    }
};