File size: 4,367 Bytes
789e9a5
38b9967
 
 
 
bb4997c
38b9967
1e9c6e8
38b9967
 
 
 
 
 
a69ad33
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38b9967
 
 
bb4997c
38b9967
00ed860
bb4997c
5d97250
 
00ed860
 
 
 
38b9967
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5d97250
38b9967
 
 
 
 
 
 
 
5d97250
00ed860
38b9967
5d97250
38b9967
a08f6a9
 
5d97250
 
a08f6a9
 
38b9967
a08f6a9
00ed860
38b9967
00ed860
bb4997c
38b9967
 
5d97250
 
 
 
 
a08f6a9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38b9967
 
 
bb4997c
5d97250
 
 
 
38b9967
 
a08f6a9
 
 
 
38b9967
 
 
 
bb4997c
 
a08f6a9
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// 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 characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
function generateRandomCharacter(length) {
  let result = '';
  const charactersLength = characters.length;
  for (let i = 0; i < length; i++) {
    const randomIndex = Math.floor(Math.random() * charactersLength);
    result += characters.charAt(randomIndex);
  }
  return result;
}




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 {
		let { characterId, text, sessionId, uid } = req.query // Inisialisasi variabel uid
		if (!sessionId) return res.json({ success: false, message: 'Input parameter sessionId' })
		if (!characterId) return res.json({ success: false, message: 'Input parameter characterId' })
		if (!text) return res.json({ success: false, message: 'Input parameter text' })
	    
		if (sessions.has(sessionId)) {
			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 }
			})
		} else {
			const id = sessionId;
			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
		})
	}
})
app.get('/ping', (req, res) => {
  const start = Date.now();
  res.send(`Pong! Respons time: ${Date.now() - start}ms`);
});

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://nultx-character-ai.hf.space/ping`, { method: 'head' }).catch(console.log), 1 * 60 * 1000)