File size: 4,595 Bytes
789e9a5
38b9967
 
 
 
bb4997c
38b9967
1e9c6e8
38b9967
 
 
 
 
 
 
 
 
bb4997c
38b9967
00ed860
bb4997c
5d97250
 
00ed860
 
 
 
38b9967
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5d97250
38b9967
 
 
 
 
 
 
 
5d97250
00ed860
38b9967
5d97250
38b9967
 
5d97250
 
38b9967
 
5d97250
38b9967
00ed860
 
38b9967
00ed860
bb4997c
38b9967
 
5d97250
 
 
 
 
38b9967
 
 
 
 
c97caab
485a9c4
00ed860
38b9967
 
 
bb4997c
38b9967
 
5d97250
 
 
 
 
38b9967
 
bb4997c
5d97250
 
 
 
38b9967
 
 
 
 
 
bb4997c
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// 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.authenticateWithToken("eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IkVqYmxXUlVCWERJX0dDOTJCa2N1YyJ9.eyJpc3MiOiJodHRwczovL2NoYXJhY3Rlci1haS51cy5hdXRoMC5jb20vIiwic3ViIjoiZ29vZ2xlLW9hdXRoMnwxMDg2NTM4ODk3NzExMTkwMDMxMzYiLCJhdWQiOlsiaHR0cHM6Ly9hdXRoMC5jaGFyYWN0ZXIuYWkvIiwiaHR0cHM6Ly9jaGFyYWN0ZXItYWkudXMuYXV0aDAuY29tL3VzZXJpbmZvIl0sImlhdCI6MTY5NTAzNjI0MywiZXhwIjoxNjk3NjI4MjQzLCJhenAiOiJkeUQzZ0UyODFNcWdJU0c3RnVJWFloTDJXRWtucVp6diIsInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwifQ.u-xoQMpUFjTL2kfsoDj0-rPWtdW4lZ6N512YY8DZ8dX7S7noGRRVz_kTvmmhJ7hkn6PSAjUNwmxWssDEdtJW1JuNuNzyTAosCzdFxd7BTeFr-xTyr4XbQEphIt4rLGDWbrVpjo462EouYSQGIp-UA5PpZur39I3Ng0s5e2IPWtZk0fsri2d4pQv4ut7nEv9_Dmg3YXMm72YJcxFwlddwKzMr58hV_S2RNtekQl6ZrMZkEcyigRTI5rOrOU5xh3SHCEUo_EhkoupJlRHxHVzmN2jrXmSHhFCf08Lfwvhswbl7dduH1lch5EiijqX_RI5AC1BUYDTlfuBckrqUokfLgw")
		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)