I am writing discord bot, and I have a database (in JSON) with a prefix of guilds.
{
"guilds":{
"721463236070866955":{
"prefix":"!"
}
}
}
Then, I require a database by:
const db = require("./database/json");
After getting guild id by:
gld = new discord.Guild(client, data);
gid = gld.id();
I need to get prefix from JSON, but how?
db.guilds[gid].prefix would give you the prefix of the guild
However, using a JSON database is poor practice. You would be better using a db. Even something as simple as sql would suffice. (npm package better-sqlite3 is a pretty good one)
This would solve problems like
having to delete the cache and re-require the file
having to copy the entire contents into cache just to make simple changes to the file
Also there is a chance that your requesting the prefix before the guild has been added to the db so you will need to check for that
Simply if (!db.guilds[gid].prefix) { ....doesn't exist }
Related
I've been trying out GunJs for a couple of days now and I'm really enjoying it. As a starter project I've followed the Fireship chat dapp video aimed at building your own chat.
Here's the issue, now that I've finished the tutorial I would like to create my own chat. However, for some reason if I get a 'chat' node within my own app it seems to pick up on the same 'chat' node as the tutorial one that is online.
onMount(() => {
// Get Messages in large chat
db.get('chat')
.map()
.once(async (data, id) => {
if (data) {
// key for E2E - to do: change for web3
const key = '#foo';
var message = {
//transform the data
who: await db.user(data).get('alias'),
what: (await SEA.decrypt(data.what, key)) + '',
when: GUN.state.is(data, 'what'),
};
if (message.what) {
messages = [...messages.slice(-100), message]
}
}
})
})
This is also the case if I change the encryption key (then the messages just become undefined). Multiple questions arise from this:
Are graph node names unique within the whole of GunDb?
How do you handle conflicts where two gun-based apps call on the same node name?
Is this problem generally solved through filtering using 'header' props?
How do I make it pick up on only my data?
Even if I've read most of the docs, there seems to be something I'm missing in my comprehension of how the graph is generally seperated between apps. Any insight on how this works would be much appreciated.
Are graph node names unique within the whole of GunDb?
Yes.
How do you handle conflicts where two gun-based apps call on the same node name?
You don't. The expected result will be, they will overwrite each other.
Is this problem generally solved through filtering using 'header' props?
I don't think it's the right way to do it.
How do I make it pick up on only my data?
Use your own relay server.
Conclusion :
gunDB doesn't really care about the who fetch / put the data. If you want to protect your data, use your own relay server (not a public one), and put data in your user space. user space is readonly to the public, but read/write for the owner.
I'm trying to make a live JSON database of IDs and a tag. The Database refreshes by reading from the JSON file and I have traced my problem to Nodejs not writing to disk, and I don't quite know why.
This is my reading operation, and yes there is a file there with proper syntax.
let dbraw = fs.readFileSync('db.json');
var db = JSON.parse(dbraw);
This is my writing operation, where I need to save the updates to disk.
var authorid = msg.author.id
db[authorid] = "M";
fs.writeFileSync('db.json', JSON.stringify(db));
Am I doing something wrong? Is it a simple error I am just forgetting? Is there an easier/more efficient way to do this I am forgetting about? I can't seem to figure out what exactly is going wrong, but it has something to do with these two bits. There are no errors in my console, just the blank JSON file it reads every time on the Read Operation.
There is a problem with your JSON file's path.
Try using __dirname.
__dirname tells you the absolute path of the directory containing the currently executing file.
— source (DigitalOcean)
Example:
If the JSON file is in the root directory:
let dbraw = fs.readFileSync(__dirname + '/db.json');
var db = JSON.parse(dbraw);
If the JSON file is in a subdirectory:
let dbraw = fs.readFileSync(__dirname + '/myJsonFolder/' + 'db.json');
var db = JSON.parse(dbraw);
Side note: I suggest you read about Google Firestore, as it will be a faster way to work with real time updates.
Here's a simple block that does what is desired
const fs = require('fs');
let file_path = __dirname + '/db.json',
dbraw = fs.readFileSync(file_path),
db = JSON.parse(dbraw),
authorid = 'abc';
console.log(db);
db[authorid] = "M";
fs.writeFileSync(file_path, JSON.stringify(db));
dbraw = fs.readFileSync(file_path), db = JSON.parse(dbraw)
console.log(db);
I've added a couple of log statements for debugging. This works and so there may be something else that's missing or incorrect in your flow. The most probable issue would be that of different path references as pointed out by jfriend00 in the comment to your question.
As for better solutions, following are a few suggestions
use require for the json directly instead of file read if the file is small which will do the parsing for you
Use async fs functions
Stream the file if it's big in size
See if you can use a cache like redis or database as a storage means to reduce your app's serialization and deserialization overhead
I've searched for a very long time on every site I can get my hands on. Each provided no help and left me with the same issue of the object remains. The code for the command is here and the JSON file I am attempting to modify is here. Is there a solution for this? I've added a temporary one where I have to manually remove it myself by the bot DMing me with a request
You can use edit-json-file package from NPM.
It has an "unset(path) Remove a path from a JSON object." method.
An example can be:
const editJsonFile = require("edit-json-file");
let file = editJsonFile("C:/Users/worko/Desktop/GitHub/area-17/characters.json");
//Put your discord code here
file.unset("Tavi-chan Wood");
//or
file.unset("Tavi-chan Wood.content");
file.save();
I just wanted to know if there's a way to count how many times a message has been sent in my Discord server, so the bot can send a message. I'm new with coding, so I don't know many things. Thank you in advance!
Explanation
To store the amount of messages sent in a guild, you'll have to keep track of a count somehow. Each time a message is sent, you can increment it by 1. Then, upon a user's request, you can display that number.
One easy option would be to store this "message count" for each guild inside of a JSON file. However, this would greatly impact performance. Consider a database for much better speeds and reliability.
Example Setup
Before using this system, create a guilds.json file with a blank object ({}).
Declaring the necessary variables...
const fs = require('fs'); // fs is the built-in Node.js file system module.
const guilds = require('./guilds.json'); // This path may vary.
Adding the system to the message event listener...
client.on('message', message => {
// If the author is NOT a bot...
if (!message.author.bot) {
// If the guild isn't in the JSON file yet, set it up.
if (!guilds[message.guild.id]) guilds[message.guild.id] = { messageCount: 1 };
// Otherwise, add one to the guild's message count.
else guilds[message.guild.id].messageCount++;
// Write the data back to the JSON file, logging any errors to the console.
try {
fs.writeFileSync('./guilds.json', JSON.stringify(guilds)); // Again, path may vary.
} catch(err) {
console.error(err);
}
}
});
Using the system in a command...
// Grab the message count.
const messageCount = guilds[message.guild.id].messageCount;
// Send the message count in a message. The template literal (${}) adds an 's' if needed.
message.channel.send(`**${messageCount}** message${messageCount !== 1 ? 's' : ''} sent.`)
.catch(console.error);
JSON is highly prone to corruption if a queue system is not created that will make sure multiple reads and writes are not happening to a file all at the same time. For the purpose of what you want, I would use something like SQLite that requires minimal setup, is easy to learn, and has helper frameworks to make it easier to use such as Keyv and Sequelize.
Here is a good guide on how to use sqlite in the nodejs runtime environment.
I'm trying to set up mongodb on Windows 8 using node.js, Does anyone know why im getting this error. C:\users\phill\node_modules\mongodb\lib\mongodb\mongo_client.js:359 it also says at collection = db collection,,, can't call method 'collection' of null. I'm having a hard time setting it up. My goal is to be able to add to mongo db, and see that I add or pull up what I added, but adding something is good enough for me for now. I'm trying every thing I can find, even straight from the website, I tried everything I see on here as well. Think it maybe it's the way I have things set up. My node.js is saved in my c: drive there is a file that says, program files(86x) in there I have node_modules, npm and such. The path ends up being, computer > windows (C:) > program files(86x) > nodejs. My Mongodb is saved right on my C: drive the path end up being windows (C:) > mongodb-win32-x86_64-2008plus-2.4.8. In my C: I also created a file data and in it created another db. I have been told i should just use mongoose, I'm just learning so i open to any advice, links or anything that will help. I have one last question as well, i learned php and then found out about sql injections and stuff like that, i am not seeing anything about security at all, should i expect the same as well. For this i get text not defined, but i have been getting errors with everthing i have done, best i did was get stuck on a right concern screen.
var MongoClient = require('mongodb').MongoClient;
MongoClient.connect("mongodb://localhost:27017/integration_test", function(err, db) {
test.equal(null, err);
test.ok(db != null);
db.collection("replicaset_mongo_client_collection").update({a:1},
{b:1}, {upsert:true}, function(err, result) {
test.equal(null, err);
test.equal(1, result);
db.close();
test.done();
});
});
Tried this as well and getting a error,C:\users\phill\node_modules\mongodb\lib\mongodb\mongo_client.js:359.... at collection = db collection,,, can't call method 'collection' of null. im calling it in command prompt node filename.js I'm saving it where my node.js file is, I have pulled up files before and created a server.
var Db = require('mongodb').Db,
MongoClient = require('mongodb').MongoClient,
Server = require('mongodb').Server,
ReplSetServers = require('mongodb').ReplSetServers,
ObjectID = require('mongodb').ObjectID,
Binary = require('mongodb').Binary,
GridStore = require('mongodb').GridStore,
Grid = require('mongodb').Grid,
Code = require('mongodb').Code,
BSON = require('mongodb').pure().BSON,
assert = require('assert');
var db = new Db('test', new Server('localhost', 27017));
// Fetch a collection to insert document into
db.open(function(err, db) {
var collection = db.collection("simple_document_insert_collection_no_safe");
// Insert a single document
collection.insert({hello:'world_no_safe'});
// Wait for a second before finishing up, to ensure we have written the item to disk
setTimeout(function() {
// Fetch the document
collection.findOne({hello:'world_no_safe'}, function(err, item) {
assert.equal(null, err);
assert.equal('world_no_safe', item.hello);
db.close();
})
}, 100);
});
In your first code example, you said:
For this i get text not defined
I assume you meant "test not defined?" Your script only requires the mongodb library, and I don't believe test is a core nodejs function, so that would explain the error.
To reference the driver documentation for db.collection(), an assert library is used, but also properly imported (as you did in your second example).
Within your callback to db.open(), you don't check if an error occurred. That might shed some light on why db is null in that function.
Regarding your question about the equivalent of SQL injection with MongoDB, the main areas of concern are places where you might pass untrusted input into evaluated JavaScript, or using such input to construct free-form query objects (not simply using a string, but more like dropping an object into your BSON query). Both of these links should provide more information on the subject:
What type of attacks can be used vs MongoDB?
How does MongoDB address SQL or Query injection?