2022-07-24 08:49:29 +03:00
// const { fetch } = require('undici');
// const express = require('express');
// const fetch = require('node-fetch');
// const btoa = require('btoa');
// const { clientId, clientSecret, port } = require('./config.json');
2022-08-12 20:01:29 -07:00
import express from 'express'
2022-07-24 08:49:29 +03:00
import fetch from 'node-fetch'
import { MongoClient , ServerApiVersion } from 'mongodb'
2022-08-12 20:01:29 -07:00
import { v4 as uuidv4 } from 'uuid'
import { validate as uuidValidate } from 'uuid' ;
2022-09-29 11:44:55 -04:00
import bodyParser from 'body-parser'
2022-09-29 12:53:19 -04:00
// import formidable from 'formidable'; //Heroku doesn't recognize this
2022-07-24 08:49:29 +03:00
//Bot section (PLACE IN ENV)
2022-09-14 08:34:38 -04:00
import { Client , Intents , MessageEmbed } from 'discord.js' ;
2022-07-24 08:49:29 +03:00
const token = process . env . token ;
const clientId = process . env . clientId ;
const clientSecret = process . env . clientSecret ;
const port = process . env . PORT || 3000 ;
const mongouri = process . env . mongouri ;
2022-07-31 10:03:21 +03:00
const client = new MongoClient ( mongouri , { useNewUrlParser : true , useUnifiedTopology : true , serverApi : ServerApiVersion . v1 });
const connection = client . connect ();
2022-07-24 08:49:29 +03:00
const bot = new Client ({
intents : [
Intents . FLAGS . GUILDS ,
Intents . FLAGS . GUILD_MESSAGES ,
Intents . FLAGS . GUILD_MESSAGE_REACTIONS ,
Intents . FLAGS . GUILD_VOICE_STATES ,
Intents . FLAGS . GUILD_EMOJIS_AND_STICKERS ,
Intents . FLAGS . GUILD_PRESENCES ,
Intents . FLAGS . GUILD_MEMBERS ,
Intents . FLAGS . DIRECT_MESSAGES ,
Intents . FLAGS . DIRECT_MESSAGE_REACTIONS ,
Intents . FLAGS . DIRECT_MESSAGE_TYPING ,
],
partials : [ 'CHANNEL' ]
});
2022-09-14 08:34:38 -04:00
bot . home_server = process . env . home_server ;
2022-07-24 08:49:29 +03:00
bot . on ( 'ready' , async () => { console . log ( 'BOT RUNNING' ); });
bot . login ( token );
async function getJSONResponse ( body ) {
let fullBody = '' ;
for await ( const data of body ) {
fullBody += data . toString ();
}
return JSON . parse ( fullBody );
}
2022-10-12 14:50:56 -04:00
async function setCurrentServer ( sid , id ) {
return new Promise (( resolve , reject ) => {
try {
if ( id ) {
const obj = {};
const arr = { text : [], voice : []};
const guild = bot . guilds . cache . get ( id );
const roles = [];
guild . roles . cache . filter (( role ) => { return ( ! role . managed ) }). forEach (( role ) => {
let newObj = {};
newObj . Id = role . id ;
newObj . name = role . name ;
newObj . color = role . hexColor ;
roles . push ( newObj );
});
const channels = guild . channels . cache ;
channels . forEach (( channel ) => {
const type = channel . type ;
if ( type == 'GUILD_TEXT' ) {
arr . text . push ({ name : channel . name , id : channel . id });
} else if ( type == 'GUILD_VOICE' ) {
arr . voice . push ({ name : channel . name , id : channel . id });
}
});
connection . then (( client ) => {
const dbo = client . db ( id ). collection ( 'SETUP' );
dbo . find (). toArray ( async ( err , docs ) => {
const m = new Map ();
m . set ( 'Id' , id );
await Promise . all ( docs . map ( async ( doc ) => {
m . set ( doc . _id , doc );
})). then (() => {
obj [ 'Id' ] = id ;
obj [ 'roles' ] = JSON . stringify ( roles );
obj [ 'channels' ] = JSON . stringify ( arr );
obj [ 'serverSettings' ] = JSON . stringify ( Object . fromEntries ( m ));
const dbo = client . db ( 'main' ). collection ( 'sessions' );
dbo . updateOne ({ sessionId : sid }, { $set : { currentServer : JSON . stringify ( obj ) }});
resolve ( 200 );
});
})
});
}
} catch ( err ) {
reject ( err );
}
});
}
2022-07-24 08:49:29 +03:00
const app = express ();
// app.use(express.json());
2022-07-26 08:30:21 +03:00
app . use ( express . static ( '/assets' ));
2022-10-11 09:22:14 -04:00
app . use ( '/CSS' , express . static ( './CSS' ));
2022-10-12 14:50:56 -04:00
app . use ( '/scripts' , express . static ( './scripts' ));
2022-09-29 11:44:55 -04:00
app . use ( bodyParser . urlencoded ({ extended : true }));
2022-07-24 08:49:29 +03:00
2022-08-12 20:01:29 -07:00
app . post ( '/user' , async ( request , response ) => {
2022-07-24 08:49:29 +03:00
const guilds = JSON . parse ( request . headers . guilds );
const id = request . headers . userid ;
for ( let i = 0 ; i < guilds . length ; i ++ ) {
const guild = bot . guilds . cache . get ( guilds [ i ]. id );
if ( guild && guild . ownerId == id ) {
guilds [ i ]. inServer = true ;
} else {
guilds [ i ]. inServer = false ;
}
}
2022-08-12 20:01:29 -07:00
//Add the guilds to the session data
connection . then (( client ) => {
const sessionId = uuidv4 ();
2022-09-25 21:29:53 -04:00
//Used for database clearing
const d = new Date ();
d . setHours ( 0 );
d . setMinutes ( 0 );
d . setSeconds ( 0 );
2022-08-12 20:01:29 -07:00
const dbo = client . db ( 'main' ). collection ( 'sessions' );
2022-09-25 21:29:53 -04:00
dbo . insertOne ({ sessionId : sessionId , userId : id , guilds : JSON . stringify ( guilds ), currentServer : null , timeStamp : d . getTime () });
2022-08-12 20:01:29 -07:00
response . send ( sessionId );
});
});
app . post ( '/logout' , async ( req , res ) => {
connection . then (( client ) => {
const sessionId = req . headers . sessionid ;
const dbo = client . db ( 'main' ). collection ( 'sessions' );
dbo . deleteOne ({ sessionId : sessionId });
});
res . sendStatus ( 200 );
});
app . post ( '/getSessionInfo' , async ( req , res ) => {
const session = req . headers . session ;
if ( session ) {
if ( uuidValidate ( session )) {
connection . then (( client ) => {
const dbo = client . db ( 'main' ). collection ( 'sessions' );
dbo . findOne ({ sessionId : session }). then (( doc ) => {
res . send ( doc );
})
})
}
}
});
2022-07-24 08:49:29 +03:00
app . post ( '/getServer' , async ( req , res ) => {
const id = req . headers . servernumber ;
//Get info
2022-07-31 10:03:21 +03:00
connection . then (( client ) => {
const dbo = client . db ( id ). collection ( 'SETUP' );
dbo . find (). toArray ( async ( err , docs ) => {
const m = new Map ();
m . set ( 'Id' , id );
await Promise . all ( docs . map ( async ( doc ) => {
m . set ( doc . _id , doc );
})). then (() => { res . send ( JSON . stringify ( Object . fromEntries ( m ))); })
})
});
2022-07-24 08:49:29 +03:00
// return res.sendFile('myGuilds.html', { root: '.' });
})
app . get ( '/getChannels' , async ( req , res ) => {
const id = req . headers . servernumber ;
const channels = bot . guilds . cache . get ( id ). channels . cache ;
const arr = { text : [], voice : []};
channels . forEach (( channel ) => {
const type = channel . type ;
if ( type == 'GUILD_TEXT' ) {
arr . text . push ({ name : channel . name , id : channel . id });
} else if ( type == 'GUILD_VOICE' ) {
arr . voice . push ({ name : channel . name , id : channel . id });
}
2022-08-12 20:01:29 -07:00
});
2022-07-24 08:49:29 +03:00
2022-07-27 15:34:38 +03:00
res . send ( arr );
2022-07-24 08:49:29 +03:00
});
2022-08-16 14:15:12 -07:00
//Headers: servernumber, sessionid
app . post ( '/setCurrentServer' , async ( req , res ) => {
2022-10-12 14:50:56 -04:00
setCurrentServer (). then (( code ) => {
res . sendStatus ( code );
}). catch (( err ) => {
2022-08-16 14:15:12 -07:00
console . error ( err );
res . sendStatus ( 500 );
2022-10-12 14:50:56 -04:00
});
2022-08-16 14:15:12 -07:00
});
2022-08-12 10:29:57 -07:00
app . get ( '/getCal' , async ( req , res ) => {
2022-08-14 15:12:30 -07:00
const userId = req . headers . userid || false ;
const guildId = req . headers . guildid || false ;
2022-08-12 10:29:57 -07:00
connection . then (( client ) => {
var times ;
const dbo = client . db ( 'main' ). collection ( 'reminderKeys' );
2022-08-14 15:12:30 -07:00
dbo . findOne ({ $or : [ { userId : userId }, { userId : guildId } ]}). then (( doc ) => {
2022-08-12 10:29:57 -07:00
if ( ! doc ) { return res . send ([[], []]); }
times = doc . times ;
let tbo = client . db ( 'main' ). collection ( 'reminders' );
2022-08-14 15:12:30 -07:00
// { $where: function() { return (times.indexOf(this.time) != -1 && this.userId == userId); }}
// tbo.find({time: {$in: times}}).toArray((err, docs) => { console.log("A", docs); throw 1; });
tbo . find ({ time : { $in : times }}). toArray (( err , docs ) => {
2022-08-12 10:29:57 -07:00
//There's gotta be a better way
let newdoc = [];
for ( let i = 0 ; i < docs . length ; i ++ ) {
newdoc . push ({});
for ( let j in docs [ i ]) {
2022-08-14 15:12:30 -07:00
if ( ! isNaN ( j ) && ( docs [ i ][ j ]. userId == userId || docs [ i ][ j ]. guildId == guildId )) {
// console.log(`${docs[i][j].userId} == ${userId}`, `${docs[i][j].guildId} == ${guildId}`);
2022-08-12 10:29:57 -07:00
newdoc [ i ][ j ] = docs [ i ][ j ];
}
}
newdoc [ i ]. _id = docs [ i ]. _id ;
newdoc [ i ]. time = docs [ i ]. time ;
newdoc [ i ]. amt = docs [ i ]. amt ;
//If there's nothing on that date, skip
// if (newdoc[i].amt == 0) { console.log(newdoc[i]); }
}
res . send ( JSON . stringify ([ times , newdoc ]));
});
});
})
});
2022-10-11 08:38:45 -04:00
//#region HTML gile serving
app . get ( '/myGuilds' , async ( req , res ) => {
return res . sendFile ( 'myGuilds.html' , { root : 'HTML' });
});
app . get ( '/dashboard' , async ( req , res ) => {
return res . sendFile ( 'dashboard.html' , { root : 'HTML' });
2022-07-24 08:49:29 +03:00
});
2022-10-11 08:38:45 -04:00
app . get ( '/premium' , async ( req , res ) => {
return res . sendFile ( 'premium.html' , { root : 'HTML' });
2022-07-24 08:49:29 +03:00
});
2022-10-11 08:38:45 -04:00
app . get ( '/index' , async ( req , res ) => {
return res . sendFile ( 'index.html' , { root : 'HTML' });
2022-07-24 08:49:29 +03:00
});
2022-10-11 08:38:45 -04:00
app . get ( '/calEvent' , async ( req , res ) => {
return res . sendFile ( 'calEvent.html' , { root : 'HTML' });
2022-08-12 10:29:57 -07:00
});
2022-10-11 08:38:45 -04:00
app . get ( '/newCalEvent' , async ( req , res ) => {
return res . sendFile ( 'newCalEvent.html' , { root : 'HTML' });
2022-08-12 10:29:57 -07:00
});
2022-10-11 08:38:45 -04:00
app . get ( '/calendar' , async ( req , res ) => {
return res . sendFile ( 'calendar.html' , { root : 'HTML' });
2022-09-14 08:34:38 -04:00
});
app . get ( '/team' , async ( req , res ) => {
2022-10-11 08:38:45 -04:00
return res . sendFile ( "team.html" , { root : 'HTML' });
2022-10-12 14:50:56 -04:00
});
app . get ( '/joinedGuild' , async ( req , res ) => {
res . sendFile ( 'joinedGuild.html' , { root : 'HTML' });
});
app . post ( '/joinedGuild' , async ( req , res ) => {
// res.sendFile('joinedGuild.html', { root: 'HTML' });
const { headers } = req ;
const { servernumber , sessionid } = headers ;
connection . then (( client ) => {
const dbo = client . db ( 'main' ). collection ( 'sessions' );
dbo . find (). toArray (( err , docs ) => {
const guilds = JSON . parse ( docs [ 0 ]. guilds );
try {
for ( let i = 0 ; i < guilds . length ; i ++ ) {
if ( guilds [ i ]. id == servernumber ) {
guilds [ i ]. inServer = true ;
setCurrentServer ( sessionid , servernumber );
return res . sendStatus ( 200 );
}
}
} catch ( err ) {
console . log ( err );
res . sendStatus ( 500 );
}
});
});
});
2022-08-12 10:29:57 -07:00
2022-10-11 08:38:45 -04:00
//#endregion
2022-10-11 09:22:14 -04:00
//#region INCLUDES
app . get ( '/cal.css' , async ( req , res ) => {
return res . sendFile ( 'cal.css' , { root : 'CSS' });
})
//#endregion
2022-09-14 08:34:38 -04:00
app . post ( "/suggestion" , async ( req , res )=> {
if ( req . headers . sessionid == 'null' ) {
return res . sendStatus ( 401 );
}
const suggestion = req . headers . suggestion ;
if ( suggestion ) {
connection . then (( client ) => {
const dbo = client . db ( "main" ). collection ( "sessions" );
dbo . findOne ({ "sessionId" : req . headers . sessionid }). then (( doc ) => {
if ( ! doc ) {
return res . sendStatus ( 410 );
}
const discId = doc . userId ;
const user = bot . users . cache . get ( discId );
const channel = bot . guilds . cache . get ( bot . home_server ). channels . cache . get ( '944330760146534492' );
const embd = new MessageEmbed ()
//If the bot doesn't have the user, just put the id in
var uid , icon ;
if ( ! user ) {
uid = `<@ ${ discId } >` ;
icon = 'https://github.com/ION606/selmer-bot-website/blob/main/assets/circleOutline.png?raw=true' ;
} else {
uid = ` ${ user . username } # ${ user . discriminator } ` ;
icon = user . displayAvatarURL ();
}
embd . setAuthor ({ name : ` ${ uid } ` , url : "" , iconURL : icon });
embd . setTitle ( `Selmer Bot Suggestion` );
embd . setColor ( "ORANGE" )
. setTimestamp ()
. setDescription ( suggestion )
. setThumbnail ( 'https://github.com/ION606/selmer-bot-website/blob/main/assets/suggestion.png?raw=true' )
. setFooter ({ text : 'This suggestion came from the Selmer Bot Website suggestion box' });
channel . send ({ embeds : [ embd ] })
res . sendStatus ( 200 );
});
});
}
})
2022-07-24 08:49:29 +03:00
2022-07-26 08:30:21 +03:00
//Stripe stuff
app . get ( '/.well-known/apple-developer-merchantid-domain-association' , async ( req , res ) => {
return res . sendFile ( 'apple-developer-merchantid-domain-association' , { root : '.' });
});
2022-08-12 14:18:33 -07:00
app . post ( '/verifypremium' , async ( req , res ) => {
if ( req . headers . userid ) {
const id = req . headers . userid ;
connection . then (( client ) => {
const dbo = client . db ( 'main' ). collection ( 'authorized' );
2022-08-14 10:59:22 -07:00
dbo . findOne ({ discordID : id }). then (( doc ) => {
2022-08-12 14:18:33 -07:00
if ( doc != undefined ) {
res . sendStatus ( 200 );
} else {
res . sendStatus ( 401 );
}
}). catch (( err ) => {
console . error ( err ); return res . sendStatus ( 500 );
})
});
}
});
2022-07-24 08:49:29 +03:00
app . post ( '/sendData' , async ( req , res ) => {
try {
2022-08-12 10:29:57 -07:00
if ( req . headers . reminders ) {
connection . then (( client ) => {
const delObjKeys = JSON . parse ( req . headers . delobjkeys );
// const userId = req.headers.userid;
const dbo = client . db ( 'main' ). collection ( 'reminders' );
const kbo = client . db ( 'main' ). collection ( 'reminderKeys' );
//Update the Time object
for ( var i in delObjKeys ) {
var obj = delObjKeys [ i ];
dbo . findOne ({ time : obj . time }). then (( doc ) => {
if ( doc ) {
// kbo.findOne({ 'userId': doc[obj.eventInd].userId }).then((doc) => {
// console.log(doc);
// }); return console.log(obj.time);
doc . amt -- ;
2022-08-14 15:12:30 -07:00
// console.log(doc[obj.eventInd]); return;
var searchId ;
if ( doc [ obj . eventInd ]. userId != null ) {
searchId = doc [ obj . eventInd ]. userId ;
} else if ( doc [ obj . eventInd ]. guildId != null ) {
searchId = doc [ obj . eventInd ]. guildId ;
}
kbo . findOne ({ 'userId' : searchId }). then (( kdoc ) => {
2022-08-12 10:29:57 -07:00
if (( kdoc . times . length - 1 ) > 0 ) {
2022-08-14 15:12:30 -07:00
kbo . updateOne ({ 'userId' : searchId }, { $pull : { times : obj . time }});
2022-08-12 10:29:57 -07:00
} else {
2022-08-14 15:12:30 -07:00
kbo . deleteOne ({ 'userId' : searchId });
2022-08-12 10:29:57 -07:00
}
});
//If there's nothing left in the list, delete it
if ( doc . amt > 0 ) {
delete doc [ obj . eventInd ];
// dbo.findOneAndUpdate({ time: obj.time }, newdoc);
dbo . findOneAndReplace ({ time : obj . time }, doc );
} else {
dbo . deleteOne ({ time : obj . time });
}
} // else { console.log("NONE", obj.time ); }
}). catch (( err ) => {
console . log ( "ERR" );
console . error ( err )
res . sendStatus ( 500 );
});
// kbo.findOneAndUpdate({ userId: userId }, { $pull: {}})
}
}). then (() => {
res . sendStatus ( 200 );
});
} else {
const pref = JSON . parse ( req . headers . serversettings );
connection . then ( async ( client ) => {
const dbo = client . db ( pref . Id ). collection ( 'SETUP' );
await dbo . updateOne ({ _id : 'WELCOME' }, { $set : { welcomechannel : pref . WELCOME . welcomechannel , welcomemessage : pref . WELCOME . welcomemessage }});
await dbo . updateOne ({ _id : 'LOG' }, { $set : { keepLogs : pref . LOG . keepLogs , logchannel : pref . LOG . logchannel , severity : pref . LOG . severity }});
2022-08-16 14:15:12 -07:00
await dbo . updateOne ({ _id : 'announcement' }, { $set : { channel : pref . announcement . channel , role : pref . announcement . role }});
2022-08-12 10:29:57 -07:00
}). then (() => { res . send ( "DONE" ); })
. catch (( err ) => {
console . error ( err );
res . send ( "FAILED" );
});
}
2022-07-24 08:49:29 +03:00
} catch ( err ) {
console . error ( err );
res . send ( "FAILED" );
}
});
2022-08-12 10:29:57 -07:00
//Reminder format = { time: 1212122, event: { guildId: "930148608400035860", userId: "12", name: "Some Generic Name", description: "Some description", offset: "15", link: "https://www.example.com" } }
app . post ( '/newCalEvent' , async ( req , res ) => {
if ( req . headers . newcalevent ) {
try {
const obj = JSON . parse ( req . headers . newcalevent );
// console.log(obj.time, typeof obj.time); return;
2022-08-14 15:12:30 -07:00
var searchId ;
if ( obj . event . userId != null ) {
searchId = obj . event . userId ;
} else if ( obj . event . guildId != null ) {
searchId = obj . event . guildId ;
} else { return res . sendStatus ( 400 ); }
2022-08-12 10:29:57 -07:00
connection . then (( client ) => {
// Update the Key object first to check if the time is already there
const kbo = client . db ( 'main' ). collection ( 'reminderKeys' );
2022-08-14 15:12:30 -07:00
kbo . findOne ({ 'userId' : searchId }). then (( doc ) => {
2022-08-12 10:29:57 -07:00
if ( doc ) {
if ( doc . times . indexOf ( obj . time ) == - 1 ) {
2022-08-14 15:12:30 -07:00
kbo . updateOne ({ 'userId' : searchId }, { $push : { times : obj . time } })
2022-08-12 10:29:57 -07:00
. catch (( err ) => { console . error ( err ); res . sendStatus ( 500 ); });
} else {
return res . sendStatus ( 409 );
}
} else {
2022-08-14 15:12:30 -07:00
doc = { 'userId' : searchId , times : [ obj . time ] }
2022-08-12 10:29:57 -07:00
kbo . insertOne ( doc );
}
//Update the Time object
const dbo = client . db ( 'main' ). collection ( 'reminders' );
dbo . findOne ({ time : obj . time }). then (( doc ) => {
let n = 0 ;
if ( doc ) {
n = doc . amt ;
doc . amt ++ ;
doc [ ` ${ n } ` ] = obj . event ;
dbo . findOneAndReplace ({ time : obj . time }, doc );
} else {
const d = new Date ( Number ( obj . time ));
doc = { "0" : obj . event , "time" : obj . time , "month" : d . getMonth (), "amt" : 1 }; //Month used for clearing when the calendar month begins (maybe modify the garbage collection with an `else if (day == 1? clear last month)` )
dbo . insertOne ( doc );
}
res . sendStatus ( 200 );
}). catch (( err ) => {
console . log ( "ERR" );
console . error ( err );
res . sendStatus ( 500 );
});
}). catch (( err ) => {
console . log ( "ERR" );
console . error ( err );
res . sendStatus ( 500 );
});
// //Make sure there hasn't been an error (header not yet sent);
// if (res.headersSent) { return console.log("ERROR"); }
});
} catch ( err ) {
console . error ( err );
return res . sendStatus ( 500 );
}
}
});
2022-09-29 11:44:55 -04:00
/*
app.post("/newics", async(req, res) => {
var fileupload = req.body.filetoupload;
var form = new formidable.IncomingForm();
form.parse(req, function(err, fields, files){
var oldpath = files.fileupload.path;
var newpath = "C:/Users/itama_za9au7b/Downloads/SBFiles/"+files.fileupload.name;
fs.rename(oldpath, newpath, function(err){
if(err) {
console.log(err);
res.sendStatus(500);
} else{
res.write("File Uploaded");
res.sendStatus(200);
}
});
});
});
*/
2022-08-12 10:29:57 -07:00
2022-07-24 08:49:29 +03:00
app . get ( '/' , async ({ query }, response ) => {
const { code } = query ;
if ( code ) {
try {
await fetch ( 'https://discord.com/api/oauth2/token' , {
method : 'POST' ,
body : new URLSearchParams ({
client_id : clientId ,
client_secret : clientSecret ,
code ,
grant_type : 'authorization_code' ,
2022-09-14 18:35:45 -04:00
redirect_uri : `https://www.selmerbot.com/` ,
2022-07-24 08:49:29 +03:00
scope : 'identify' ,
}),
headers : {
'Content-Type' : 'application/x-www-form-urlencoded' ,
},
}). then ( async response => {
const oauthData = await getJSONResponse ( response . body );
// console.log(oauthData);
}). catch ( err => { console . error ( err ); });
} catch ( error ) {
// NOTE: An unauthorized token will not throw an error
// tokenResponseData.statusCode will be 401
console . error ( error );
}
}
2022-10-11 08:38:45 -04:00
return response . sendFile ( 'index.html' , { root : 'HTML' });
2022-07-24 08:49:29 +03:00
});
2022-08-12 10:29:57 -07:00
app . get ( "*" ,( req , res ) => {
2022-10-11 08:38:45 -04:00
res . sendFile ( "404.html" , { root : 'HTML' });
2022-08-12 10:29:57 -07:00
})
2022-07-24 08:49:29 +03:00
app . listen ( port , () => console . log ( `App listening on port ${ port } ` ));