Thank you for formating the code. But for some reason, it still doesn’t fire the event
Man, you’re stuck on a website starter project. Add package.json and add express
and etc. Double check you have node
in your container
I have it. Do you want to see the entire package.json? I imported a bot I created from github, reinstalled the packages and everything went good for a lot of time, and the rest still works. Idk why this isn’t working.
Well, then, I think, your module is not being imported by any other. Check that your file is required by some other module
@TheBigerGamer do you have a package.json file?
If your code is in a different file than your main file…
//Other file
exports.run = async (app, db, ...) {
//your code goes here
};
//Main file
const beingCalled = require("path/to/file.js").run(app, db, ...);
In this way, you aren’t creating a new app and your code is actually being called.
Have this in events/ready.js: require('../modules/dashboard')(client);
Yes I have:
"name": "global-protector",
"version": "8.3.1",
"description": "My first Discord bot made in Discord.js",
"main": "bot.js",
"dependencies": {
"bufferutil": "^3.0.2",
"child_process": "^1.0.2",
"discord.js": "^11.2.1",
"djs-collection-persistent": "^0.1.4",
"ejs": "^2.5.7",
"enmap": "^0.4.2",
"enmap-level": "^1.0.0",
"express": "^4.16.2",
"express-session": "^1.15.6",
"helmet": "^3.9.0",
"marked": "^0.3.6",
"moment": "^2.19.1",
"moment-duration-format": "^1.3.0",
"morgan": "^1.9.0",
"passport": "^0.4.0",
"passport-discord": "^0.1.2",
"path": "^0.12.7",
"process-nextick-args": "^1.0.7",
"rebuild": "^0.1.2",
"url": "^0.11.0",
"util-deprecate": "^1.0.2",
"showdown": "^1.8.1",
"cheerio": "^0.22.0",
"node-bypasser": "^1.8.0",
"simple-youtube-api": "^5.0.0",
"ytdl-core": "^0.18.5",
"opusscript": "^0.0.6",
"prism-media": "^0.0.2",
"isgd": "^1.1.3",
"quick.db": "^6.3.2",
"weather-js": "^2.0.0",
"snekfetch": "^4.0.4"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node bot.js"
},
"engines": {
"node": "8.x"
},
"author": "DarkenLight Mage",
"license": "Apache-2.0",
"devDependencies": {
"jshint": "^2.9.5"
}
}
I have this in the file: module.exports = client => {
, but if you see above, I require it as you said.
then it should work?
Nop. Still doesn’t work. Maybe it is a bug?
Can you give anyone access to your code. I’m sure it’s something that we just can’t see from the forum. If not, that’s totally fine, we’ll just have to try our best.
How are you calling the file?
I’ll just paste the entire dashboard.js file here. I think it’s easier. (Btw, this is not something I’ve done. [And the huge comments aren’t mine.])
/*
DASHBOARD EXAMPLE
This is a very simple dashboard example, but even in its simple state, there are still a
lot of moving parts working together to make this a reality. I shall attempt to explain
those parts in as much details as possible, but be aware: there's still a lot of complexity
and you shouldn't expect to really understand all of it instantly.
Pay attention, be aware of the details, and read the comments.
Note that this *could* be split into multiple files, but for the purpose of this
example, putting it in one file is a little simpler. Just *a little*.
*/
// quick.db
const db = require('quick.db')
// Native Node Imports
const url = require("url");
const path = require("path");
const fs = require("fs");
// Used for Permission Resolving...
const Discord = require("discord.js");
// Express Session
const express = require("express");
const app = express();
// Express Plugins
// Specifically, passport helps with oauth2 in general.
// passport-discord is a plugin for passport that handles Discord's specific implementation.
const passport = require("passport");
const session = require("express-session");
const Strategy = require("passport-discord").Strategy;
// Helmet is a security plugin
//const helmet = require('helmet');
// Used to parse Markdown from things like ExtendedHelp
const md = require("marked");
// For logging
const morgan = require("morgan");
// For stats
const moment = require("moment");
require("moment-duration-format");
module.exports = client => {
if (client.config.dashboard.enabled !== "true")
return client.log("log", "Dashboard disabled", "INFO");
// It's easier to deal with complex paths.
// This resolves to: yourbotdir/dashboard/
const dataDir = path.resolve(`${process.cwd()}${path.sep}dashboard`);
// This resolves to: yourbotdir/dashboard/templates/
// which is the folder that stores all the internal template files.
const templateDir = path.resolve(`${dataDir}${path.sep}templates`);
app.set("trust proxy", 5); // Proxy support
// The public data directory, which is accessible from the *browser*.
// It contains all css, client javascript, and images needed for the site.
app.use(
"/public",
express.static(path.resolve(`${dataDir}${path.sep}public`), {
maxAge: "10d"
})
);
app.use(morgan("combined")); // Logger
// uhhhh check what these do.
passport.serializeUser((user, done) => {
done(null, user);
});
passport.deserializeUser((obj, done) => {
done(null, obj);
});
/*
This defines the **Passport** oauth2 data. A few things are necessary here.
clientID = Your bot's client ID, at the top of your app page. Please note,
older bots have BOTH a client ID and a Bot ID. Use the Client one.
clientSecret: The secret code at the top of the app page that you have to
click to reveal. Yes that one we told you you'd never use.
callbackURL: The URL that will be called after the login. This URL must be
available from your PC for now, but must be available publically if you're
ever to use this dashboard in an actual bot.
scope: The data scopes we need for data. identify and guilds are sufficient
for most purposes. You might have to add more if you want access to more
stuff from the user. See: https://discordapp.com/developers/docs/topics/oauth2
See config.js.example to set these up.
*/
var protocol;
if (client.config.dashboard.secure === "true") {
client.protocol = "https://";
} else {
client.protocol = "http://";
}
protocol = client.protocol;
client.callbackURL = `${protocol}${client.config.dashboard.domain}/callback`;
client.log("log", `Callback URL: ${client.callbackURL}`, "INFO");
passport.use(
new Strategy(
{
clientID: client.appInfo.id,
clientSecret: client.config.dashboard.oauthSecret,
callbackURL: client.callbackURL,
scope: ["identify", "guilds"]
},
(accessToken, refreshToken, profile, done) => {
process.nextTick(() => done(null, profile));
}
)
);
// Session data, used for temporary storage of your visitor's session information.
// the `secret` is in fact a 'salt' for the data, and should not be shared publicly.
app.use(
session({
secret: client.config.dashboard.sessionSecret,
resave: false,
saveUninitialized: false
})
);
// Initializes passport and session.
app.use(passport.initialize());
app.use(passport.session());
// The domain name used in various endpoints to link between pages.
app.locals.domain = client.config.dashboard.domain;
// The EJS templating engine gives us more power
app.engine("html", require("ejs").renderFile);
app.set("view engine", "html");
// body-parser reads incoming JSON or FORM data and simplifies their
// use in code.
var bodyParser = require("body-parser");
app.use(bodyParser.json()); // to support JSON-encoded bodies
app.use(
bodyParser.urlencoded({
// to support URL-encoded bodies
extended: true
})
);
/*
Authentication Checks. checkAuth verifies regular authentication,
whereas checkAdmin verifies the bot owner. Those are used in url
endpoints to give specific permissions.
*/
function checkAuth(req, res, next) {
if (req.isAuthenticated()) return next();
req.session.backURL = req.url;
res.redirect("/login");
}
function cAuth(req, res) {
if (req.isAuthenticated()) return;
req.session.backURL = req.url;
res.redirect("/login");
}
function checkAdmin(req, res, next) {
if (req.isAuthenticated() && req.user.id === client.config.ownerID || req.isAuthenticated() && req.user.id === client.config.subownerID)
return next();
req.session.backURL = req.originalURL;
res.redirect("/");
}
var privacyMD = "";
fs.readFile(
`${process.cwd()}${path.sep}dashboard${path.sep}public${
path.sep
}PRIVACY.md`,
function(err, data) {
if (err) {
console.log(err);
privacyMD = "Error";
return;
}
privacyMD = data
.toString()
.replace(/\{\{botName\}\}/g, client.user.username)
.replace(
/\{\{email\}\}/g,
client.config.dashboard.legalTemplates.contactEmail
);
if (client.config.dashboard.secure !== "true") {
privacyMD = privacyMD.replace(
"Sensitive and private data exchange between the Site and its Users happens over a SSL secured communication channel and is encrypted and protected with digital signatures.",
""
);
}
}
);
var termsMD = "";
fs.readFile(
`${process.cwd()}${path.sep}dashboard${path.sep}public${path.sep}TERMS.md`,
function(err, data) {
if (err) {
console.log(err);
privacyMD = "Error";
return;
}
termsMD = data
.toString()
.replace(/\{\{botName\}\}/g, client.user.username)
.replace(
/\{\{email\}\}/g,
client.config.dashboard.legalTemplates.contactEmail
);
}
);
// Index page. If the user is authenticated, it shows their info
// at the top right of the screen.
app.get("/", (req, res) => {
if (req.isAuthenticated()) {
res.render(path.resolve(`${templateDir}${path.sep}index.ejs`), {
bot: client,
auth: true,
user: req.user
});
} else {
res.render(path.resolve(`${templateDir}${path.sep}index.ejs`), {
bot: client,
auth: false,
user: null
});
}
});
app.get("/stats", (req, res) => {
if (client.config.dashboard.protectStats === "true") {
cAuth(req, res);
}
const duration = moment
.duration(client.uptime)
.format(" D [days], H [hrs], m [mins], s [secs]");
//const members = client.guilds.reduce((p, c) => p + c.memberCount, 0);
const members = `${client.users.filter(u => u.id !== "1").size} (${
client.users.filter(u => u.id !== "1").filter(u => u.bot).size
} bots)`;
const textChannels = client.channels.filter(c => c.type === "text").size;
const voiceChannels = client.channels.filter(c => c.type === "voice").size;
const guilds = client.guilds.size;
res.render(path.resolve(`${templateDir}${path.sep}stats.ejs`), {
bot: client,
auth: req.isAuthenticated() ? true : false,
user: req.isAuthenticated() ? req.user : null,
stats: {
servers: guilds,
members: members,
text: textChannels,
voice: voiceChannels,
uptime: duration,
commands: client.commandsNumber,
memoryUsage: (process.memoryUsage().heapUsed / 1024 / 1024).toFixed(2),
dVersion: Discord.version,
nVersion: process.version,
bVersion: client.version
}
});
});
app.get("/legal", function(req, res) {
md.setOptions({
renderer: new md.Renderer(),
gfm: true,
tables: true,
breaks: false,
pedantic: false,
sanitize: false,
smartLists: true,
smartypants: false
});
/*var showdown = require('showdown');
var converter = new showdown.Converter(),
textPr = privacyMD,
htmlPr = converter.makeHtml(textPr),
textTe = termsMD,
htmlTe = converter.makeHtml(textTe);
res.render(path.resolve(`${templateDir}${path.sep}legal.ejs`), {
bot: client,
auth: req.isAuthenticated() ? true : false,
user: req.isAuthenticated() ? req.user : null,
privacy: htmlPr.replace(/\\'/g, `'`),
terms: htmlTe.replace(/\\'/g, `'`),
edited: client.config.dashboard.legalTemplates.lastEdited
});*/
res.render(path.resolve(`${templateDir}${path.sep}legal.ejs`), {
bot: client,
auth: req.isAuthenticated() ? true : false,
user: req.isAuthenticated() ? req.user : null,
privacy: md(privacyMD),
terms: md(termsMD),
edited: client.config.dashboard.legalTemplates.lastEdited
});
});
// The login page saves the page the person was on in the session,
// then throws the user to the Discord OAuth2 login page.
app.get(
"/login",
(req, res, next) => {
if (req.session.backURL) {
req.session.backURL = req.session.backURL;
} else if (req.headers.referer) {
const parsed = url.parse(req.headers.referer);
if (parsed.hostname === app.locals.domain) {
req.session.backURL = parsed.path;
}
} else {
req.session.backURL = "/";
}
next();
},
passport.authenticate("discord")
);
app.get(
"/callback",
passport.authenticate("discord", {
failureRedirect: "/"
}),
(req, res) => {
if (req.session.backURL) {
res.redirect(req.session.backURL);
req.session.backURL = null;
} else {
res.redirect("/");
}
}
);
app.get("/admin", checkAdmin, (req, res) => {
res.render(path.resolve(`${templateDir}${path.sep}admin.ejs`), {
bot: client,
user: req.user,
auth: true
});
});
app.get("/dashboard", checkAuth, (req, res) => {
const perms = Discord.EvaluatedPermissions;
res.render(path.resolve(`${templateDir}${path.sep}dashboard.ejs`), {
perms: perms,
bot: client,
user: req.user,
auth: true
});
});
app.get("/add/:guildID", checkAuth, (req, res) => {
req.session.backURL = "/dashboard";
var invitePerm = client.config.dashboard.invitePerm;
var inviteURL = `https://discordapp.com/oauth2/authorize?client_id=${
client.appInfo.id
}&scope=bot&guild_id=${
req.params.guildID
}&response_type=code&redirect_uri=${encodeURIComponent(
`${client.callbackURL}`
)}&permissions=${invitePerm}`;
if (client.guilds.has(req.params.guildID)) {
res.send(
'<p>The bot is already there... <script>setTimeout(function () { window.location="/dashboard"; }, 1000);</script><noscript><meta http-equiv="refresh" content="1; url=/dashboard" /></noscript>'
);
} else {
res.redirect(inviteURL);
}
});
app.post("/manage/:guildID", checkAuth, (req, res) => {
const guild = client.guilds.get(req.params.guildID);
if (!guild) return res.status(404);
const isManaged =
guild && !!guild.member(req.user.id)
? guild.member(req.user.id).permissions.has("MANAGE_GUILD")
: false;
if (req.user.id === client.config.ownerID || req.user.id === client.config.subownerID) {
console.log(`Admin bypass for managing server: ${req.params.guildID}`);
} else if (!isManaged) {
res.redirect("/");
}
const settings = client.settings.get(guild.id);
for (const key in settings) {
var value = req.body[key];
//console.log(typeof value);
//console.log(value);
/*if (value.length > 1) {
for (var i = 0; i < value.length; i++) {
console.log(value[i]);
value[i] = value[i].replace(',', '');
console.log(value[i]);
}
} else {*/
if (value.indexOf(",") > -1) {
settings[key] = value.split(",");
//console.log('S: ' + settings[key]);
//console.log(typeof settings[key]);
//console.log('Split');
//console.log(typeof value);
//console.log(value);
} else if (key === "inviteWhitelist") {
var iWArray = [];
value = value.replace(/\s/g, "");
value.indexOf(",") > -1
? (iWArray = value.split(","))
: iWArray.push(value);
settings[key] = iWArray;
}
if (key === "swearWords") {
var sWArray = [];
value = value.replace(/\s/g, "");
value.indexOf(",") > -1
? (sWArray = value.split(","))
: sWArray.push(value);
settings[key] = sWArray;
} else {
settings[key] = value;
//console.log(typeof value);
//console.log(value);
}
//settings[key] = req.body[key];
}
client.settings.set(guild.id, settings);
res.redirect(`/manage/${req.params.guildID}`);
});
app.get("/manage/:guildID", checkAuth, (req, res) => {
const guild = client.guilds.get(req.params.guildID);
if (!guild) return res.status(404);
const isManaged =
guild && !!guild.member(req.user.id)
? guild.member(req.user.id).permissions.has("MANAGE_GUILD")
: false;
if (req.user.id === client.config.ownerID || req.user.id === client.config.subownerID) {
console.log(`Admin bypass for managing server: ${req.params.guildID}`);
} else if (!isManaged) {
res.redirect("/dashboard");
}
res.render(path.resolve(`${templateDir}${path.sep}manage.ejs`), {
bot: client,
guild: guild,
user: req.user,
auth: true
});
});
app.get("/leave/:guildID", checkAuth, async (req, res) => {
const guild = client.guilds.get(req.params.guildID);
if (!guild) return res.status(404);
const isManaged =
guild && !!guild.member(req.user.id)
? guild.member(req.user.id).permissions.has("MANAGE_GUILD")
: false;
if (req.user.id === client.config.ownerID || req.user.id === client.config.subownerID) {
console.log(`Admin bypass for managing server: ${req.params.guildID}`);
} else if (!isManaged) {
res.redirect("/dashboard");
}
await guild.leave();
if (req.user.id === client.config.ownerID || req.user.id === client.config.subownerID) {
return res.redirect("/admin");
}
res.redirect("/dashboard");
});
app.get("/reset/:guildID", checkAuth, async (req, res) => {
const guild = client.guilds.get(req.params.guildID);
if (!guild) return res.status(404);
const isManaged =
guild && !!guild.member(req.user.id)
? guild.member(req.user.id).permissions.has("MANAGE_GUILD")
: false;
if (req.user.id === client.config.ownerID || req.user.id === client.config.subownerID) {
console.log(`Admin bypass for managing server: ${req.params.guildID}`);
} else if (!isManaged) {
res.redirect("/dashboard");
}
client.settings.set(guild.id, client.config.defaultSettings);
res.redirect(`/manage/${req.params.guildID}`);
});
app.get("/commands", (req, res) => {
if (req.isAuthenticated()) {
res.render(path.resolve(`${templateDir}${path.sep}commands.ejs`), {
bot: client,
auth: true,
user: req.user,
md: md
});
} else {
res.render(path.resolve(`${templateDir}${path.sep}commands.ejs`), {
bot: client,
auth: false,
user: null,
md: md
});
}
});
app.get("/logout", function(req, res) {
req.logout();
res.redirect("/");
});
app.get("*", function(req, res) {
// Catch-all 404
res.send(
'<p>404 File Not Found. Please wait...<p> <script>setTimeout(function () { window.location = "/"; }, 1000);</script><noscript><meta http-equiv="refresh" content="1; url=/" /></noscript>'
);
});
/*app.get("/api/:action", async (req, res) => {
let apicodes = await db.fetch(`apicodes`)
console.log('1')
let action = req.params.action
if (apicodes) {
console.log('2')
if (apicodes.keys.includes(req.query.key)) {
if (apicodes.secrets.includes(req.query.secret)) {
if (action) {
if (action === 'check') {
let check = await db.fetch(`gban_${req.params.userid}`)
if (check) {
res.send(check)
} else {
res.send('Not Banned')
}
} else {
if (action === 'ban') {
let user = req.query.userid,
reason = req.query.reason,
evidence = req.query.evidence,
moderator = req.query.moderator,
requester = req.query.botid;
let request = {type: 'ban', userID: user, reason: reason, evidence: evidence, moderator: moderator, botid: requester, status: 'Not checked'}
await db.set(`banrequests_${requester}`)
} else {
if (action === 'unban') {
let user = req.query.userid,
reason = req.query.reason,
moderator = req.query.moderator,
requester = req.query.botid;
let request = {type: 'unban', userID: user, reason: reason, moderator: moderator, botid: requester, status: 'Not checked'}
await db.set(`banrequests_${requester}`)
} else {
if (action === 'editban') {
if (req.query.reason) {
let user = req.query.userid,
reason = req.query.reason,
moderator = req.query.moderator,
requester = req.query.botid;
let request = {type: 'editban', userID: user, reason: reason, moderator: moderator, botid: requester, status: 'Not checked'}
await db.set(`banrequests_${requester}`)
} else {
if (req.query.evidence) {
let user = req.query.userid,
evidence = req.query.evidence,
moderator = req.query.moderator,
requester = req.query.botid;
let request = {type: 'editban', userID: user, evidence: evidence, moderator: moderator, botid: requester, status: 'Not checked'}
await db.set(`banrequests_${requester}`)
}
}
} else {
if (action === 'requests') {
let requester = req.query.botid
let requests = await db.fetch(`banrequests_${requester}`)
if (requests) {
res.send(requests)
} else {
res.send('No requests.')
}
} else {
if (action === 'checkcon') {
res.status(200).send('OK.')
}
}
}
}
}
}
} else {
console.log('2')
res.send('Invalid API call method.')}//.status(401)
} else res.send('Invalid API auth secret.')//.status(401)
} else res.send('Invalid API auth key.')//.status(401)
} else res.send('API code check broken')//.status(401)
});*/
console.log('a')
const getAPICodes = async () => await db.fetch(`apicodes`);
const getBannedStatus = async id => await db.fetch(`gban_${id}`);
const banRequest = async (req, type) => {
const { userid: userId } = req.params;
const { reason, evidence, moderator, botid: requester } = req.query;
const request = {
type: type || "ban",
userID: userId,
reason: reason,
evidence: evidence,
moderator: moderator,
botid: requester,
status: "Not checked"
};
return await db.set(`banrequests_${requester}`, request);
};
const actionHandler = async (req, res) => {
console.log('1')
const apiCodes = await getAPICodes();
const { keys: apiCodesKeys, secrets: apiCodesSecrets } = apiCodes;
const { action, userid: userId } = req.params;
const { key, secret } = req.query;
const passingState =
apiCodesKeys.includes(key) && apiCodesSecrets.includes(secret);
if (!action || !apiCodes || !passingState) return res.status(401).json({
message: "Unauthorized",
code: 401
})
switch (action) {
case "check": {
const check = getBannedStatus(userId);
if (check) {
res.send(check);
} else {
res.send("Not Banned");
}
}
case "ban": {
res.json(banRequest(req, "ban"));
}
case "unban": {
res.json(banRequest(req, "unban"));
}
case "editban": {
res.json(banRequest(req, "editban"));
}
case "requests": {
res.json(await db.get(`banrequests_${req.paramd.botid}`));
}
case "checkon": {
res.sendStatus(200);
}
}
};
app.get("/api/:action", async (req, res) => await actionHandler(req, res));
client.site = app
.listen(client.config.dashboard.port, function() {
client.log(
"log",
`Dashboard running on port ${client.config.dashboard.port}`,
"INFO"
);
})
.on("error", err => {
client.log("ERROR", `Error with starting dashboard: ${err.code}`);
return process.exit(0);
});
};
I call the dashboard.js in the ready event with: require('../modules/dashboard')(client);
Try
const file = require(file).client()
But then why the other pages work, but not the ones I add? I don’t think the problem is with how the file is called.
You have app.get('*')
, so any middleware after that line will be thrown out. Put your code above it, or put that line at the end of the code
PS. comments are not that huge, half of the serious code (in a perfect scenario) should be just comments
Still gave me the 404 error.
In case you want to see the 404 handler, here it is:
app.get("*", function(req, res) {
// Catch-all 404
res.send(
'<p>404 File Not Found. Please wait...<p> <script>setTimeout(function () { window.location = "/"; }, 1000);</script><noscript><meta http-equiv="refresh" content="1; url=/" /></noscript>'
);
});
I’ve seen it already, can you share the project name? And, what path are you requesting? Maybe there should be four-o-four because you’re going for a wrong path
My project’s name is global-protector. And wdym by path?
Oh. It works now. Strange. I used all these alot of times:
https://global-protector.glitch.me/api/ban
https://global-protector.glitch.me/api/unban
https://global-protector.glitch.me/api/editban
https://global-protector.glitch.me/api/requests
https://global-protector.glitch.me/api/check
And they didn’t work. But it now works. Thank you @jarvis394.