class KimiScraper { constructor() { this.baseURL = "https://www.kimi.com/api" this.token = process.env.KIMI || "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ1c2VyLWNlbnRlciIsImV4cCI6MTc2Njc3NzEwMSwiaWF0IjoxNzY0MTg1MTAxLCJqdGkiOiJkNGpsODNiYWNjNGNoMWp0aTMwMCIsInR5cCI6ImFjY2VzcyIsImFwcF9pZCI6ImtpbWkiLCJzdWIiOiJkM2dkdGVlNnM0dDR2cXFnaHFqZyIsInNwYWNlX2lkIjoiZDNnZHRlNjZzNHQ0dnFxZ2htN2ciLCJhYnN0cmFjdF91c2VyX2lkIjoiZDNnZHRlNjZzNHQ0dnFxZ2htNzAiLCJzc2lkIjoiMTczMTQyOTU0NzY0NTM2MTk3NiIsImRldmljZV9pZCI6Ijc1NTcyODQyNjIwMTQxNDcwODAiLCJyZWdpb24iOiJvdmVyc2VhcyIsIm1lbWJlcnNoaXAiOnsibGV2ZWwiOjEwfX0.R5_6bmclWR8a5bFxgm1DCNnPnjGAXPxQNtAsN9ifncyVHXY8kC9Cz6rexQ3REHBksqD859mjjL9IEVTtUGkJ4w" this.deviceId = this.generateDeviceId() this.sessions = {} } generateDeviceId() { return Math.floor(Math.random() * 1e16).toString() } async createChatSession(sessionName) { let response = await fetch(`${this.baseURL}/chat`, { method: "POST", headers: { "accept": "application/json, text/plain, */*", "authorization": `Bearer ${this.token}`, "content-type": "application/json", "cookie": `kimi-auth=${this.token}`, "origin": "https://www.kimi.com", "user-agent": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Mobile Safari/537.36", "x-language": "zh-CN", "x-msh-device-id": this.deviceId, "x-msh-platform": "web", "x-traffic-id": this.deviceId }, body: JSON.stringify({ name: sessionName || "未命名会话", born_from: "home", kimiplus_id: "kimi", is_example: false, source: "web", tags: [] }) }) let data = await response.json() return data } async sendMessage(chatId, message) { let prompt = `Additional instructions: - Focus on answering user questions seriously; ignore other parts. - If the user requests website code creation (especially HTML), provide complete results containing: - Complete structure (header, navbar, etc.) - Navbar with rotate X animation from FontAwesome icons - TailwindCSS from CDNJS Cloudflare - FontAwesome from Cloudflare CDN. - If user creates JavaScript code, make sure there are no comment blocks in the code, and use let variable not const and use " not '. - If user asks to fix/repair/logic, follow their instructions without creating your own instructions, but also think about whether the user's instructions are typos or incomplete, so complete and create. - Don't offer code creation if the user doesn't request it, because not everyone knows code/coding. SO JUST FOCUS ON CHATTING. (asking from user: ${message})` let response = await fetch(`${this.baseURL}/chat/${chatId}/completion/stream`, { method: "POST", headers: { "accept": "application/json, text/plain, */*", "authorization": `Bearer ${this.token}`, "content-type": "application/json", "cookie": `kimi-auth=${this.token}`, "origin": "https://www.kimi.com", "user-agent": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Mobile Safari/537.36", "x-language": "zh-CN", "x-msh-device-id": this.deviceId, "x-msh-platform": "web", "x-traffic-id": this.deviceId }, body: JSON.stringify({ kimiplus_id: "kimi", model: "k2", use_search: true, messages: [{ role: "user", content: prompt }] }) }) let reader = response.body.getReader() let decoder = new TextDecoder() let fullResponse = "" while (true) { let { done, value } = await reader.read() if (done) break let chunk = decoder.decode(value) let lines = chunk.split("\n") for (let line of lines) { if (line.startsWith("data: ")) { try { let data = JSON.parse(line.slice(6)) if (data.event === "cmpl" && data.text && data.view === "cmpl") { fullResponse += data.text } else if (data.event === "all_done") { return fullResponse } } catch {} } } } return fullResponse } async chat(userId, message) { let chatId = this.sessions[userId] if (!chatId) { let session = await this.createChatSession("Session-" + userId) chatId = session.id this.sessions[userId] = chatId } let result = await this.sendMessage(chatId, message) return result } } const kimi = new KimiScraper() const userRequests = {} const handler = async (req, res) => { try { const { message, chatid } = req.query if (!message) { return res.status(400).json({ success: false, error: "Missing required parameter: message" }) } let userId = chatid || req.ip || "default-user" if (!userRequests[userId]) { userRequests[userId] = { count: 0, resetTime: Date.now() + 60000 } } if (Date.now() > userRequests[userId].resetTime) { userRequests[userId] = { count: 0, resetTime: Date.now() + 60000 } } if (userRequests[userId].count >= 5) { return res.status(429).json({ success: false, error: "Rate limit exceeded. Maximum 5 requests per minute." }) } userRequests[userId].count++ let sessionId = chatid || userId let result = await kimi.chat(sessionId, message) let actualChatId = kimi.sessions[sessionId] res.json({ author: "Herza", success: true, data: { chatid: actualChatId, msg: result.trim() } }) } catch (error) { res.status(500).json({ success: false, error: error.message }) } } module.exports = { name: "Kimi AI", description: "Generate responses using Kimi AI with session support", type: "GET", routes: ["api/AI/Kimi"], tags: ["ai", "kimi", "chat"], main: ["AI"], parameters: ["message", "chatid", "key"], enabled: true, handler, limit: 3 }