-
Notifications
You must be signed in to change notification settings - Fork 1.7k
/
index.js
202 lines (172 loc) · 6.74 KB
/
index.js
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
import express from 'express';
import fs from 'fs';
import ws from 'ws';
import expressWs from 'express-ws';
import {job} from './keep_alive.js';
import {OpenAIOperations} from './openai_operations.js';
import {TwitchBot} from './twitch_bot.js';
// Start keep alive cron job
job.start();
console.log(process.env);
// Setup express app
const app = express();
const expressWsInstance = expressWs(app);
// Set the view engine to ejs
app.set('view engine', 'ejs');
// Load environment variables
const GPT_MODE = process.env.GPT_MODE || 'CHAT';
const HISTORY_LENGTH = process.env.HISTORY_LENGTH || 5;
const OPENAI_API_KEY = process.env.OPENAI_API_KEY || '';
const MODEL_NAME = process.env.MODEL_NAME || 'gpt-3.5-turbo';
const TWITCH_USER = process.env.TWITCH_USER || 'oSetinhasBot';
const TWITCH_AUTH = process.env.TWITCH_AUTH || 'oauth:vgvx55j6qzz1lkt3cwggxki1lv53c2';
const COMMAND_NAME = process.env.COMMAND_NAME || '!gpt';
const CHANNELS = process.env.CHANNELS || 'oSetinhas,jones88';
const SEND_USERNAME = process.env.SEND_USERNAME || 'true';
const ENABLE_TTS = process.env.ENABLE_TTS || 'false';
const ENABLE_CHANNEL_POINTS = process.env.ENABLE_CHANNEL_POINTS || 'false';
const COOLDOWN_DURATION = parseInt(process.env.COOLDOWN_DURATION, 10) || 10; // Cooldown duration in seconds
if (!OPENAI_API_KEY) {
console.error('No OPENAI_API_KEY found. Please set it as an environment variable.');
}
const commandNames = COMMAND_NAME.split(',').map(cmd => cmd.trim().toLowerCase());
const channels = CHANNELS.split(',').map(channel => channel.trim());
const maxLength = 399;
let fileContext = 'You are a helpful Twitch Chatbot.';
let lastUserMessage = '';
let lastResponseTime = 0; // Track the last response time
// Setup Twitch bot
console.log('Channels: ', channels);
const bot = new TwitchBot(TWITCH_USER, TWITCH_AUTH, channels, OPENAI_API_KEY, ENABLE_TTS);
// Setup OpenAI operations
fileContext = fs.readFileSync('./file_context.txt', 'utf8');
const openaiOps = new OpenAIOperations(fileContext, OPENAI_API_KEY, MODEL_NAME, HISTORY_LENGTH);
// Setup Twitch bot callbacks
bot.onConnected((addr, port) => {
console.log(`* Connected to ${addr}:${port}`);
channels.forEach(channel => {
console.log(`* Joining ${channel}`);
console.log(`* Saying hello in ${channel}`);
});
});
bot.onDisconnected(reason => {
console.log(`Disconnected: ${reason}`);
});
// Connect bot
bot.connect(
() => {
console.log('Bot connected!');
},
error => {
console.error('Bot couldn\'t connect!', error);
}
);
bot.onMessage(async (channel, user, message, self) => {
if (self) return;
const currentTime = Date.now();
const elapsedTime = (currentTime - lastResponseTime) / 1000; // Time in seconds
if (ENABLE_CHANNEL_POINTS === 'true' && user['msg-id'] === 'highlighted-message') {
console.log(`Highlighted message: ${message}`);
if (elapsedTime < COOLDOWN_DURATION) {
bot.say(channel, `Cooldown active. Please wait ${COOLDOWN_DURATION - elapsedTime.toFixed(1)} seconds before sending another message.`);
return;
}
lastResponseTime = currentTime; // Update the last response time
const response = await openaiOps.make_openai_call(message);
bot.say(channel, response);
}
const command = commandNames.find(cmd => message.toLowerCase().startsWith(cmd));
if (command) {
if (elapsedTime < COOLDOWN_DURATION) {
bot.say(channel, `Cooldown active. Please wait ${COOLDOWN_DURATION - elapsedTime.toFixed(1)} seconds before sending another message.`);
return;
}
lastResponseTime = currentTime; // Update the last response time
let text = message.slice(command.length).trim();
if (SEND_USERNAME === 'true') {
text = `Message from user ${user.username}: ${text}`;
}
const response = await openaiOps.make_openai_call(text);
if (response.length > maxLength) {
const messages = response.match(new RegExp(`.{1,${maxLength}}`, 'g'));
messages.forEach((msg, index) => {
setTimeout(() => {
bot.say(channel, msg);
}, 1000 * index);
});
} else {
bot.say(channel, response);
}
if (ENABLE_TTS === 'true') {
try {
const ttsAudioUrl = await bot.sayTTS(channel, response, user['userstate']);
notifyFileChange(ttsAudioUrl);
} catch (error) {
console.error('TTS Error:', error);
}
}
}
});
app.ws('/check-for-updates', (ws, req) => {
ws.on('message', message => {
// Handle WebSocket messages (if needed)
});
});
const messages = [{role: 'system', content: 'You are a helpful Twitch Chatbot.'}];
console.log('GPT_MODE:', GPT_MODE);
console.log('History length:', HISTORY_LENGTH);
console.log('OpenAI API Key:', OPENAI_API_KEY);
console.log('Model Name:', MODEL_NAME);
app.use(express.json({extended: true, limit: '1mb'}));
app.use('/public', express.static('public'));
app.all('/', (req, res) => {
console.log('Received a request!');
res.render('pages/index');
});
if (GPT_MODE === 'CHAT') {
fs.readFile('./file_context.txt', 'utf8', (err, data) => {
if (err) throw err;
console.log('Reading context file and adding it as system-level message for the agent.');
messages[0].content = data;
});
} else {
fs.readFile('./file_context.txt', 'utf8', (err, data) => {
if (err) throw err;
console.log('Reading context file and adding it in front of user prompts:');
fileContext = data;
});
}
app.get('/gpt/:text', async (req, res) => {
const text = req.params.text;
let answer = '';
try {
if (GPT_MODE === 'CHAT') {
answer = await openaiOps.make_openai_call(text);
} else if (GPT_MODE === 'PROMPT') {
const prompt = `${fileContext}\n\nUser: ${text}\nAgent:`;
answer = await openaiOps.make_openai_call_completion(prompt);
} else {
throw new Error('GPT_MODE is not set to CHAT or PROMPT. Please set it as an environment variable.');
}
res.send(answer);
} catch (error) {
console.error('Error generating response:', error);
res.status(500).send('An error occurred while generating the response.');
}
});
const server = app.listen(3000, () => {
console.log('Server running on port 3000');
});
const wss = expressWsInstance.getWss();
wss.on('connection', ws => {
ws.on('message', message => {
// Handle client messages (if needed)
});
});
function notifyFileChange() {
wss.clients.forEach(client => {
if (client.readyState === ws.OPEN) {
client.send(JSON.stringify({updated: true}));
}
});
}