const axios = require('axios'); class AnimeConverter { constructor() { this.baseURL = 'https://api.anifun.ai/aitools'; this.tempURL = 'https://temp.anifun.ai'; this.headers = { 'Accept': 'application/json, text/plain, */*', 'Content-Type': 'application/json', 'fp': '3bb76e9ae8e3349d2b18784710f9fcf2', 'fp1': '5J0h1+bPFg4F6qVNO46PpRwyoEoxaViPWymZNXDJBp8Na7vNifH6jre49yHOnzRP', 'x-guide': 'rYJ2cO93MBTiPlC0ipi8WySUJwAa30Kvjigyvz41a6kCR7hopnzY512gBRd8nGkFB7dNAKkf01jW/3LvfyC9e8U5HZtWnDPoql58VJXOm2VSGyEXPmTzWIkG2PhDFhZnbn/nM3hrjh2YI84k2dpT7q8Hq3tLZ1qV2Yegucrs0hI=', 'theme-version': '83EmcUoQTUv50LhNx0VrdcK8rcGexcP35FcZDcpgWsAXEyO4xqL5shCY6sFIWB2Q', 'X-code': Date.now().toString() }; this.models = { 'meina': 'MeinaHentai_v4.safetensors', 'anime': 'animeModel_v1.safetensors', 'manga': 'mangaStyle_v2.safetensors' }; } async uploadImage(imageUrl) { const imageResponse = await axios.get(imageUrl, { responseType: 'arraybuffer', timeout: 45000 }); const FormData = require('form-data'); const formData = new FormData(); formData.append('file', Buffer.from(imageResponse.data), { filename: 'image.jpg', contentType: 'image/jpeg' }); const response = await axios.post(`${this.baseURL}/upload-img`, formData, { headers: { ...this.headers, ...formData.getHeaders() }, timeout: 60000 }); if (response.data.code !== 200) { throw new Error(`Upload failed: ${response.data.message}`); } return response.data.data.path; } async createTask(imagePath, model) { const modelName = this.models[model] || this.models['meina']; const response = await axios.post(`${this.baseURL}/of/create`, { fn_name: 'demo-photo2anime', call_type: 3, input: { source_image: imagePath, model: modelName, request_from: 16 }, data: '', request_from: 16, origin_from: '68d425c58e76bc6c' }, { headers: { ...this.headers, 'X-code': Date.now().toString() }, timeout: 30000 }); if (response.data.code !== 200) { throw new Error(`Task creation failed: ${response.data.message}`); } return response.data.data.task_id; } async checkStatus(taskId, maxRetries = 60) { for (let i = 0; i < maxRetries; i++) { const response = await axios.post(`${this.baseURL}/of/check-status`, { task_id: taskId, fn_name: 'demo-photo2anime', call_type: 3, request_from: 16, origin_from: '68d425c58e76bc6c' }, { headers: { ...this.headers, 'X-code': Date.now().toString() }, timeout: 25000 }); if (response.data.code !== 200) { throw new Error(`Status check failed: ${response.data.message}`); } const status = response.data.data.status; if (status === 2) { return `${this.tempURL}/${response.data.data.result_image}`; } await new Promise(resolve => setTimeout(resolve, 3000)); } throw new Error('Processing timeout'); } async convert(imageUrl, model = 'meina') { const imagePath = await this.uploadImage(imageUrl); const taskId = await this.createTask(imagePath, model); const resultUrl = await this.checkStatus(taskId); return resultUrl; } } const handler = async (req, res) => { try { const { image, key, model } = req.query; if (!image || !key) { return res.status(400).json({ success: false, error: 'Missing required parameters: image and key' }); } const modelType = model || 'meina'; const validModels = ['meina', 'anime', 'manga']; if (!validModels.includes(modelType)) { return res.status(400).json({ success: false, error: 'Invalid model parameter', availableModels: validModels }); } const converter = new AnimeConverter(); const resultUrl = await converter.convert(image, modelType); res.json({ author: 'Herza', success: true, data: { model: modelType, url: resultUrl } }); } catch (error) { res.status(500).json({ success: false, error: error.message }); } }; module.exports = { name: 'Image to Anime Converter', description: 'Convert photos to anime style using AI', type: 'GET', routes: ['api/AI/img2anime'], tags: ['ai', 'image', 'anime', 'converter'], main: ['AI'], parameters: ['image', 'key'], enabled: true, limit: 3, handler };