2024-02-05 16:42:50 -05:00
require ( 'dotenv' ) . config ( ) ;
const { Client } = require ( 'discord.js-selfbot-v13' ) ;
const client = new Client ( ) ;
2024-02-07 17:24:14 -05:00
const fs = require ( 'fs' ) ;
const path = require ( 'path' ) ;
2024-02-05 16:42:50 -05:00
2024-02-05 16:53:57 -05:00
const BATCH _INTERVAL = 5000 ;
let messageQueue = [ ] ;
2024-02-05 16:42:50 -05:00
2024-02-05 17:22:14 -05:00
const channelMappings = {
[ process . env . SOURCE _CHANNEL _ID _1 ] : process . env . TARGET _CHANNEL _ID _1 ,
[ process . env . SOURCE _CHANNEL _ID _2 ] : process . env . TARGET _CHANNEL _ID _2 ,
2024-02-08 17:14:36 -05:00
[ process . env . SOURCE _CHANNEL _ID _3 ] : process . env . TARGET _CHANNEL _ID _3 ,
2024-02-08 18:59:07 -05:00
[ process . env . SOURCE _CHANNEL _ID _4 ] : process . env . TARGET _CHANNEL _ID _4 ,
[ process . env . SOURCE _CHANNEL _ID _5 ] : process . env . TARGET _CHANNEL _ID _5 ,
[ process . env . SOURCE _CHANNEL _ID _6 ] : process . env . TARGET _CHANNEL _ID _6 ,
2024-02-05 17:22:14 -05:00
} ;
2024-02-06 15:56:37 -05:00
let includeImages = process . env . IMAGES === '1' ;
const COMMAND _CHANNEL _ID = process . env . COMMAND _CHANNEL _ID ;
2024-02-08 20:10:29 -05:00
const confPath = path . join ( _ _dirname , 'conf' ) ;
const settingsFilePath = path . join ( confPath , 'channelSettings.json' ) ;
if ( ! fs . existsSync ( confPath ) ) {
fs . mkdirSync ( confPath , { recursive : true } ) ;
}
let channelSettings = { } ;
if ( fs . existsSync ( settingsFilePath ) ) {
channelSettings = JSON . parse ( fs . readFileSync ( settingsFilePath , 'utf8' ) ) ;
} else {
channelSettings = { includeImages : { } } ;
fs . writeFileSync ( settingsFilePath , JSON . stringify ( channelSettings , null , 2 ) ) ;
}
2024-02-06 15:13:02 -05:00
2024-02-05 16:42:50 -05:00
client . on ( 'ready' , ( ) => {
console . log ( ` ${ client . user . tag } is ready! ` ) ;
2024-02-07 17:39:09 -05:00
client . user . setPresence ( {
status : 'invisible'
} )
2024-02-05 16:53:57 -05:00
setInterval ( processMessageQueue , BATCH _INTERVAL ) ;
2024-02-08 20:33:21 -05:00
console . log ( "Channel Mappings:" , channelMappings ) ;
2024-02-05 16:42:50 -05:00
} ) ;
2024-02-07 17:24:14 -05:00
const outputsDir = path . join ( _ _dirname , 'outputs' ) ;
if ( ! fs . existsSync ( outputsDir ) ) {
fs . mkdirSync ( outputsDir , { recursive : true } ) ;
}
function logMessageToFile ( channelId , message ) {
const channelDir = path . join ( outputsDir , channelId ) ;
if ( ! fs . existsSync ( channelDir ) ) {
fs . mkdirSync ( channelDir , { recursive : true } ) ;
}
const logFilePath = path . join ( channelDir , 'messages_logged.txt' ) ;
fs . appendFile ( logFilePath , message + '\n' , err => {
if ( err ) {
console . error ( 'Failed to log message to file:' , err ) ;
}
} ) ;
}
2024-02-05 16:42:50 -05:00
client . on ( 'messageCreate' , async message => {
2024-02-08 20:55:20 -05:00
if ( message . channel . id === COMMAND _CHANNEL _ID && message . content . startsWith ( '.toggleimages' ) ) {
2024-02-08 20:10:29 -05:00
const args = message . content . split ( ' ' ) ;
2024-02-08 20:17:56 -05:00
if ( args . length === 1 ) {
2024-02-08 20:55:20 -05:00
let response = "Image forwarding status for channels:\n" ;
for ( const sourceChannelId of Object . keys ( channelMappings ) ) {
if ( ! sourceChannelId || sourceChannelId === 'undefined' ) continue ;
const targetChannelId = channelMappings [ sourceChannelId ] ;
const status = channelSettings . includeImages [ sourceChannelId ] !== undefined ? ( channelSettings . includeImages [ sourceChannelId ] ? "Enabled" : "Disabled" ) : "Not Set" ;
response += ` - <# ${ sourceChannelId } > to <# ${ targetChannelId } > ( ${ sourceChannelId } ) : ${ status } \n ` ;
}
return message . channel . send ( response ) . then ( msg => setTimeout ( ( ) => msg . delete ( ) , 10000 ) ) ;
}
else if ( args . length === 2 ) {
const channelId = args [ 1 ] ;
if ( ! Object . keys ( channelMappings ) . includes ( channelId ) ) {
return message . reply ( ` Channel ID ${ channelId } is not a recognized source channel. ` ) . then ( msg => setTimeout ( ( ) => msg . delete ( ) , 5000 ) ) ;
}
channelSettings . includeImages [ channelId ] = ! channelSettings . includeImages [ channelId ] ;
fs . writeFileSync ( settingsFilePath , JSON . stringify ( channelSettings , null , 2 ) ) ;
return message . reply ( ` Image and link forwarding for channel <# ${ channelId } > is now ${ channelSettings . includeImages [ channelId ] ? "enabled" : "disabled" } . ` ) . then ( msg => setTimeout ( ( ) => msg . delete ( ) , 5000 ) ) ;
2024-02-08 20:17:56 -05:00
} else {
2024-02-08 20:55:20 -05:00
return message . reply ( "Usage: .toggleimages <channelId>" ) . then ( msg => setTimeout ( ( ) => msg . delete ( ) , 5000 ) ) ;
2024-02-08 20:10:29 -05:00
}
2024-02-06 15:56:37 -05:00
}
2024-02-05 17:22:14 -05:00
if ( channelMappings [ message . channel . id ] ) {
2024-02-05 16:42:50 -05:00
if ( message . author . id === client . user . id ) return ;
2024-02-08 20:10:29 -05:00
const includeImages = channelSettings . includeImages [ message . channel . id ] || false ;
2024-02-05 16:42:50 -05:00
2024-02-06 15:13:02 -05:00
let content = message . content ;
if ( ! includeImages ) {
content = content . replace ( /https?:\/\/\S+/g , '[Link removed]' ) ;
}
2024-02-05 17:09:55 -05:00
const timestamp = new Date ( message . createdTimestamp ) . toISOString ( ) ;
2024-02-06 15:13:02 -05:00
let attachmentUrls = '' ;
if ( includeImages ) {
attachmentUrls = message . attachments . map ( a => a . url ) . join ( ' ' ) ;
if ( attachmentUrls ) {
attachmentUrls = ' ' + attachmentUrls ;
}
2024-02-05 17:32:33 -05:00
}
2024-02-05 17:22:14 -05:00
const formattedMessage = {
2024-02-07 17:24:14 -05:00
content : ` \` ${ timestamp } \` <@ ${ message . author . id } > / ** ${ message . author . tag } **: ${ content } ${ attachmentUrls } \` [Message ID: ${ message . id } ] \` ` ,
2024-02-05 17:22:14 -05:00
target : channelMappings [ message . channel . id ]
} ;
2024-02-05 17:09:55 -05:00
2024-02-07 17:24:14 -05:00
const formattedMessageForLog = ` ${ timestamp } <@ ${ message . author . id } > / ${ message . author . username } : ${ content } ${ attachmentUrls } [Message ID: ${ message . id } ] ` ;
logMessageToFile ( message . channel . id . toString ( ) , formattedMessageForLog ) ;
2024-02-05 17:09:55 -05:00
messageQueue . push ( formattedMessage ) ;
2024-02-05 16:53:57 -05:00
}
} ) ;
async function processMessageQueue ( ) {
2024-02-05 17:22:14 -05:00
if ( messageQueue . length === 0 ) return ;
2024-02-06 15:13:02 -05:00
2024-02-05 17:22:14 -05:00
while ( messageQueue . length > 0 ) {
let batchMessage = '' ;
let targetChannelId = messageQueue [ 0 ] . target ;
while ( messageQueue . length > 0 && messageQueue [ 0 ] . target === targetChannelId && ( batchMessage . length + messageQueue [ 0 ] . content . length ) <= 2000 ) {
const nextMessage = messageQueue . shift ( ) . content ;
if ( batchMessage . length + nextMessage . length + 1 <= 2000 ) {
batchMessage += nextMessage + '\n' ;
} else {
const targetChannel = await client . channels . fetch ( targetChannelId ) ;
await targetChannel . send ( batchMessage ) ;
batchMessage = nextMessage + '\n' ; // Start a new batch
}
}
2024-02-05 16:53:57 -05:00
2024-02-05 17:22:14 -05:00
if ( batchMessage . length > 0 ) {
const targetChannel = await client . channels . fetch ( targetChannelId ) ;
2024-02-05 16:53:57 -05:00
await targetChannel . send ( batchMessage ) ;
2024-02-05 16:42:50 -05:00
}
2024-02-05 16:53:57 -05:00
}
}
2024-02-05 16:42:50 -05:00
client . login ( process . env . DISCORD _TOKEN ) ;
2024-02-05 16:53:57 -05:00