2023-04-09 16:07:32 +00:00
const Discord = require ( 'discord.js' ) ;
const fetch = require ( 'node-fetch' ) ;
2023-04-09 23:45:06 +00:00
const emptyResponses = require ( './assets/emptyMessages.js' ) ;
const resetResponses = require ( './assets/resetMessages.js' ) ;
const errorMessages = require ( './assets/errorMessages.js' ) ;
2023-04-09 16:07:32 +00:00
require ( 'dotenv' ) . config ( )
2023-04-09 16:31:48 +00:00
// hi
2023-04-09 16:07:32 +00:00
const { Client , GatewayIntentBits , ActivityType , Partials } = require ( 'discord.js' ) ;
const client = new Client ( {
intents : [
GatewayIntentBits . DirectMessages ,
GatewayIntentBits . Guilds ,
GatewayIntentBits . GuildBans ,
GatewayIntentBits . GuildMessages ,
GatewayIntentBits . MessageContent ,
] ,
partials : [ Partials . Channel ] ,
} ) ;
const channelID = '1094494101631680653' ; // Replace with your channel ID
const channelID2 = '1094628334727614605' ; // Replace with your channel ID
const conversations = new Map ( ) ;
client . once ( 'ready' , ( ) => {
console . log ( 'Bot is ready.' ) ;
client . user . setPresence ( {
activities : [ { name : ` AI ` , type : ActivityType . Playing } ] ,
status : 'dnd' ,
} ) ;
} ) ;
client . on ( 'messageCreate' , async ( message ) => {
// Only respond in the specified channels
if ( message . channel . id !== channelID && message . channel . id !== channelID2 ) {
return ;
}
2023-04-09 23:45:06 +00:00
if ( message . author . bot ) return ; // Ignore messages from bots
2023-04-09 16:07:32 +00:00
if ( conversations . get ( message . author . id ) ? . busy ) {
message . delete ( )
await message . author . send ( "I'm currently busy with another process. Please try again later." ) ;
return ;
}
const userID = message . author . id ;
let conversation = conversations . get ( userID ) || { messages : [ ] , busy : false } ;
if ( conversation . messages . length === 0 ) {
2023-04-09 23:10:48 +00:00
conversation . messages . push ( { role : 'user' , content : ` You are the smartest AI and help with anything I ask. You are great at coding! When giving a list always use one line per item. My name is ${ message . author . username } . ` } ) ;
2023-04-09 16:31:48 +00:00
conversation . messages . push ( { role : 'user' , content : ` My name is ${ message . author . username } . ` } ) ;
2023-04-09 23:10:48 +00:00
conversation . messages . push ( { role : 'assistant' , content : ` Hello, ${ message . author . username } , how may I help you? ` } ) ;
2023-04-09 16:31:48 +00:00
conversation . messages . push ( { role : 'user' , content : message . cleanContent } ) ;
2023-04-09 16:07:32 +00:00
2023-04-09 16:31:48 +00:00
} else {
2023-04-09 23:45:06 +00:00
// Append user message to conversation history
conversation . messages . push ( { role : 'user' , content : message . cleanContent } ) ;
2023-04-09 16:31:48 +00:00
}
2023-04-09 23:10:48 +00:00
if ( message . content === '!reset' || message . content === '!r' ) {
2023-04-09 16:07:32 +00:00
conversations . delete ( userID ) ; // Delete user's conversation map if they request reset
await message . channel . send ( 'Conversation reset.' ) ;
return ;
}
// Append user message to conversation history
conversation . messages . push ( { role : 'user' , content : message . cleanContent } ) ;
try {
conversation . busy = true ;
const response = await generateResponse ( conversation ) ;
// Append bot message to conversation history
conversation . messages . push ( { role : 'assistant' , content : response } ) ;
2023-04-09 23:10:48 +00:00
if ( response && response . trim ( ) ) {
// Send response to user if it's not empty
await message . channel . send ( response ) ;
2023-04-09 23:45:06 +00:00
conversation . busy = false ;
2023-04-09 23:10:48 +00:00
} else {
// Handle empty response here
2023-04-09 23:45:06 +00:00
const randomResponse = emptyResponses [ Math . floor ( Math . random ( ) * emptyResponses . length ) ] ;
// We had an empty response, create a new memory map for sanity.
await message . channel . send ( randomResponse ) ; // give the user a human like reponse about the error
2023-04-09 23:10:48 +00:00
conversations . delete ( userID ) ; // Delete user's conversation map if they request reset
2023-04-09 23:45:06 +00:00
const resetMessage = resetResponses [ Math . floor ( Math . random ( ) * resetResponses . length ) ] ;
await message . channel . send ( resetMessage ) ; // give a notification of reset using a human like response.
conversation . busy = false ;
2023-04-09 23:10:48 +00:00
}
2023-04-09 16:07:32 +00:00
conversations . set ( userID , conversation ) ; // Update user's conversation map in memory
} catch ( err ) {
console . error ( err ) ;
2023-04-09 23:45:06 +00:00
const errorMessage = errorMessages [ Math . floor ( Math . random ( ) * errorMessages . length ) ] ;
await message . channel . send ( errorMessage ) ; // give a notification of reset using a human like response. } finally {
2023-04-09 16:07:32 +00:00
conversation . busy = false ;
}
} ) ;
async function generateResponse ( conversation ) {
const controller = new AbortController ( ) ;
const timeout = setTimeout ( ( ) => {
controller . abort ( ) ;
} , 900000 ) ;
try {
const response = await fetch ( 'http://192.168.0.15/v1/chat/completions' , {
method : 'POST' ,
headers : {
'accept' : 'application/json' ,
'Content-Type' : 'application/json'
} ,
2023-04-09 23:45:06 +00:00
body : JSON . stringify ( { messages : conversation . messages } ) ,
2023-04-09 16:07:32 +00:00
signal : controller . signal
} ) ;
const responseData = await response . json ( ) ;
const choice = responseData . choices [ 0 ] ;
2023-04-09 16:31:48 +00:00
// Remove "user None:" and any text after it from the response
const responseText = choice . message . content . trim ( ) ;
const startIndex = responseText . indexOf ( 'user None:' ) ;
const sanitizedResponse = startIndex === - 1 ? responseText : responseText . substring ( 0 , startIndex ) ;
return sanitizedResponse ;
2023-04-09 16:07:32 +00:00
} catch ( err ) {
console . error ( err ) ;
return 'Oops, something went wrong!' ;
} finally {
clearTimeout ( timeout ) ;
}
}
client . login ( process . env . THE _TOKEN ) ; // Replace with your bot token