// for (let sign of ['unhandledRejection', 'uncaughtException']) process.on(sign, console.error) const os = require('os') const util = require('util') const uuid = require('uuid') const logger = require('morgan') const express = require('express') const puppeteer = require('puppeteer') const rateLimit = require('express-rate-limit') const CharacterAI = require('node_characterai') const { execSync } = require('child_process') const sessions = new Map() const app = express() app.set('trust proxy', 1) app.set('json spaces', 4) app.use(logger('dev')) app.use(express.urlencoded({ extended: true })) app.use(async (req, res, next) => { for (let [sessionId, characterAI] of sessions) { const timeReset = 10 * 60 * 1000 // 10 min if (Date.now() - characterAI.lastFetch > timeReset) { await characterAI.unauthenticate() sessions.delete(sessionId) } } next() }) app.all('/', (req, res) => { const obj = {} const used = process.memoryUsage() for (let key in used) obj[key] = `${Math.round(used[key] / 1000 / 1000 * 100) / 100} MB` const disk = execSync('du -sh').toString().split('M')[0] obj.diskUsage = `${disk} MB` const totalmem = os.totalmem() const freemem = os.freemem() obj.memoryUsage = `${((totalmem - freemem) / Math.pow(1024, 3)).toFixed(1)} GB / ${(totalmem / Math.pow(1024, 3)).toFixed(1)} GB` res.json({ success: true, message: 'Hello World', uptime: new Date(process.uptime() * 1000).toUTCString().split(' ')[4], status: obj }) }) app.get('/ip', (req, res) => res.send(req.ip)) app.get('/sessions', (_, res) => res.send(eval(Array.from(sessions)))) app.all('/api', rateLimit(), async (req, res) => { if (!['GET', 'POST'].includes(req.method)) return res.json({ success: false, message: 'Method not allowed' }) try { const { characterId, text, sessionId } = req.query if (!characterId) return res.json({ success: false, message: 'Input parameter characterId' }) if (!text) return res.json({ success: false, message: 'Input parameter text' }) if (sessionId) { if (!sessions.has(sessionId)) return res.json({ success: false, message: 'sessionId not found' }) const characterAI = sessions.get(sessionId) sessions.set(sessionId, Object.assign(characterAI, { lastFetch: Date.now() })) const chat = await characterAI.createOrContinueChat(characterId) const response = await chat.sendAndAwaitResponse(text, true) const urlAvatar = `https://characterai.io/i/80/static/avatars/${response.srcAvatarFileName}` delete response.chat res.json({ success: true, message: 'sessionId will be deleted in 10 minutes if not used', result: { ...response, urlAvatar, sessionId } }) return } const id = uuid.v4() const characterAI = new CharacterAI() characterAI.requester.puppeteerPath = puppeteer.executablePath() await characterAI.authenticateAsGuest() sessions.set(id, Object.assign(characterAI, { lastFetch: Date.now() })) const chat = await characterAI.createOrContinueChat(characterId) const response = await chat.sendAndAwaitResponse(text, true) const urlAvatar = `https://characterai.io/i/80/static/avatars/${response.srcAvatarFileName}` delete response.chat res.json({ success: true, message: 'sessionId will be deleted in 10 minutes if not used', result: { ...response, urlAvatar, sessionId: id } }) } catch (e) { console.log(e) e = String(e) res.json({ error: true, message: e === '[object Object]' ? 'Internal Server Error' : e }) } }) const PORT = process.env.PORT || 7860 app.listen(PORT, () => console.log('App running on port', PORT)) // const { REPL_SLUG, REPL_OWNER } = process.env // if (REPL_SLUG && REPL_OWNER) setInterval(() => fetch(`https://c-ai.team-skizo.repl.co`, { method: 'head' }).catch(console.log), 20 * 1000)