Automatic file upload to a Discord channel - node.js

So I'm trying to write a Discord selfbot (e.g. a bot that uses your token to write stuff from your own Discord account), using a Discord.js npm module and so far I'm doing this only for purpose of writing stuff every set interval of time.
I've successfully managed to get it to spam random words (using random-words npm module) and also the contents of a certain text file by lines. The final stage is getting it to upload random files within a certain folder to that channel, every set interval of time. How do I do that?
My code so far (token values and server/channel ids are hidden, naturally :P)
const discord = require("discord.js");
const TOKEN = "";
const bot = new discord.Client();
var fs = require("fs")
var fileContent = fs.readFileSync("text.txt", "utf8");
fileContent=fileContent.split("\n");
var ind=0
bot.on("ready",()=>{
console.log("Ready!");
var server = bot.guilds.find("id","")
var chan = new discord.TextChannel(server,{"id":""});
bot.setInterval(()=>
{
chan.send(fileContent[ind%fileContent.length]).then(msg=>{
console.log(msg.content); ind++;
});
},5000);
})
bot.login(TOKEN);
The current text file content sending feature doesn't have to stay. In fact, ideally I'd only like the bot to have an automatic file upload feature.

You can use glob library to find the list of all files in a specified folder, and then
From
Discord.js - stable release - textChannel#send()
you send files by
var glob = require("glob")
glob("*", {cwd: __dirname + "/folder"}, function (er, files) {
// files is an array of filenames.
// er is an error object or null.
channel.send({
files: files.map(filePath => ({
attachment: filePath,
name: "whateveryouwant"
}))[Math.floor(Math.random() * files.length)]
})
.then(console.log)
.catch(console.error);
})

Related

TypeError: throw new TypeError('CLIENT_MISSING_INTENTS'); Issue

I am recieving this message even though I added intents to my Index.js
Discord.js version: 13.3.1
Node: 16.6.1
Code of my Index.js
const config = require('../config.json');
const mongoose = require('mongoose');
const Discord = require("discord.js");
const bot = new Discord.Client();
const { Intents } = require('discord.js');
const client = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES] });
bot.on("ready", () => {
console.log(`Bot is online!\n${bot.users.size} users, in ${bot.guilds.size} servers connected.`);
});
// HERE IS MONGODB BUT NOT SHOWING
const Client = require('./Structures/Client');
const WelcomeSchema = require(`../src/Models/welcome`)
bot.on("guildMemberAdd", async (member, guil) => {
WelcomeSchema.findOne({ guildId: member.guild.id }, async (err, data) => {
if(!data) return;
const user = member.user;
const channel = member.guild.channels.cache.get(data.channelId);
channel.send({embed: {color: "BLUE", description: `sd`}})
})
})
const client = new Client(config);
client.start();
Would mean a lot if you could help me find the issue. Thanks!
I now realise that there are quite a few issues with the code you have provided.
No. 1 - Client Definitions
It looks like you're defining three different clients. (bot, client, and possibly Client.)
You should organise your code in such a way that all events and commands are tied to one client object, as having multiple clients running can lead to rate-limiting and performance issues. (as well as being completely and utterly pointless.)
The error seems to be stating that bot is not given any intents during its creation, which could be fixed with the use of...
// ...
const bot = new Discord.Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES] });
// ...
No. 2: Reference to an Undefined Variable
On the line where you define client at the start of the file, you use new Client, despite the fact that Client has not been imported yet, and is imported later in the file. This won't work, as Client is undefined at that point in the program.
No. 3: Re-assignment of a constant
It also seems that you re-assign another const client near the end of your file. This will cause an error, as client is already a defined constant which cannot be over-written.
No. 4: Access to Message Intents (maybe???)
As of recently, discord requires that you enable Gateway Intents to be able to access certain events and data (such as Server Messages and Members).
To enable the intents, head to the Discord Developer Dashboard for your bot, select "Bot" from the sidebar, and enable the intents you need access to.
While this intent is not required to be able to read messages until April 30th, 2022, if your bot specifies the GUILD_MESSAGES intent, this option needs to be enabled.
If your bot is in more than 100 servers, you will need to verify your bot to be able to continue accessing data which requires these intents. More about that here.

Node.js Google Cloud Storage Get Multiple Files' Metadata

I have several files on Google Cloud Storage that are named as 0.jpg, 1.jpg, 2.jpg, etc. I want to get the metadata for each file without setting file names separately. Then, want to send these metadata information to React application. In React application, when one clicks on an image, the popup displays the metadata information for this clicked image.
For only one file, I used the following code:
const express = require("express");
const cors = require("cors");
// Imports the Google Cloud client library
const { Storage } = require("#google-cloud/storage");
const bucketName = "bitirme_1";
const filename = "detected/0.jpg";
const storage = new Storage();
const app = express();
app.get("/api/metadata", cors(), async (req, res, next) => {
try {
// Gets the metadata for the file
const [metadata] = await storage
.bucket(bucketName)
.file(filename)
.getMetadata();
const metadatas = [
{id: 0, name: `Date: ${metadata.updated.substring(0,10)}, Time: ${metadata.updated.substring(11,19)}`},
{id: 1, name: metadata.contentType}
];
res.json(metadatas);
} catch (e) {
next(e);
}
});
const port = 5000;
app.listen(port, () => console.log(`Server started on port ${port}`));
I first set the bucket name. Then, set filename array as (89 is the number of files):
const filename = Array(89).fill(1).map((_, i) => ('detected/' + i + '.jpg'));
These files are in detected folder. When I try this, it gives me this error:
Error: No such object: bitirme_1/detected/0.jpg, detected/1.jpg, detected/2.jpg, detected/3.jpg, detected/4.jpg,detected/5.jpg,detected/6.jpg, ....
How can I solve the getting multiple files' metadata issue?
Also, I want to get the number of files in a bucket (or, in the detected folder). I searched the API but cannot found anything. I do not want to enter the total number of files as 89, want to get it from the API.
I found the solution for finding the number of files in a bucket or a folder in a bucket. This is the solution:
const [files] = await storage.bucket(bucketName).getFiles();
const fileStrings = files.map(file => file.name);
const fileSliced = fileStrings.map(el => el.slice(9, 11));
for (i = 0; i < fileSliced.length; i++) {
if (fileSliced[i].includes('.')) {
fileSliced[i] = fileSliced[i].slice(0, 1);
}
}
const fileNumbers = fileSliced.map(function(item) {
return parseInt(item, 10);
});
const numOfFiles = Math.max(...fileNumbers) + 1;
console.log(numOfFiles);
First, I got the all files with file names in a string array. In my case, file names are detected/0.jpg, detected/1.jpg, detected/2.jpg, etc. I just only want to the number part of the file name; hence, I sliced the string array starting from 9th index up to 11th index(not included). As a result, I got only the numbers except one digit numbers.
To handle one digit case, which have '.' at the end of the sliced name, I also removed '.' from these one digit file names.
As a result, I got ['0', '1', '2', '3', ...]. Next, I convert this string array to number array using parseInt function. Finally, to get the number of files, I got the maximum of the array and add 1 to this number.
I have an image detail component that includes location of sender ip, download option and exiting the popup page. This detail popup page opens at /#i where i is the name of image file, such as 1.jpg, 2.jpg. So, for example when I click the first image, the popup page opens at /#1. In this popup page, I want to get metadata information for the opened image. But, I could not find a solution for this.

Read all JSON files contained in a dynamically updated folder

I've got multiple json files contained within a directory that will dynamically be updated by users. The users can add categories which will create new json files in that directory, and they can also remove categories which would delete json files in that directory. I'm looking for a method to read all json files contained in that folder directory, and push all the json files into a single object array. I imagine asynchronously would be desirable too.
I'm very new to using fs. I've management to read single json files by directory using
const fs = require('fs');
let data = fs.readFileSync('./sw_lbi/categories/category1.json');
let categories = JSON.parse(data);
console.log(categories);
But of course this will only solve the synchronous issue when using require()
As I'll have no idea what json files will be contained in the directory because the users will also name them, I'll need a way to read all the json files by simply calling the folder directory which contains them.
I'm imagining something like this (which obviously is foolish)
const fs = require('fs');
let data = fs.readFileSync('./sw_lbi/categories');
let categories = JSON.parse(data);
console.log(categories);
What would be the best approach to achieve this?
Thanks in advance.
First of all you need to scan this directory for files, next you need to filter them and select only JSONs, and at the end just read every file and do what you need to do
const fs = require('fs');
const path = require('path')
const jsonsInDir = fs.readdirSync('./sw_lbi/categories').filter(file => path.extname(file) === '.json');
jsonsInDir.forEach(file => {
const fileData = fs.readFileSync(path.join('./sw_lbi/categories', file));
const json = JSON.parse(fileData.toString());
});

React gives Error: not supported error when I try and import local module

I have a local module (speech.js) in my create-react-app src folder that is the google text to speech code on their website. I adjusted it to be an arrow function and use that specific export syntax.
const textToSpeech = require('#google-cloud/text-to-speech');
// Import other required libraries
const fs = require('fs');
const util = require('util');
export const main = async () => {
// Creates a client
const client = new textToSpeech.TextToSpeechClient();
// The text to synthesize
const text = "Hello world";
// Construct the request
const request = {
input: {text: text},
// Select the language and SSML Voice Gender (optional)
voice: {languageCode: 'en-US', ssmlGender: 'NEUTRAL'},
// Select the type of audio encoding
audioConfig: {audioEncoding: 'MP3'},
};
// Performs the Text-to-Speech request
const [response] = await client.synthesizeSpeech(request);
// Write the binary audio content to a local file
const writeFile = util.promisify(fs.writeFile);
await writeFile('output.mp3', response.audioContent, 'binary');
console.log('Audio content written to file: output.mp3');
};
What I'm not understanding is why this syntax isn't working in App.js.
import {main} from './speech';
I get the error, Error: not support and "4 stack frames were collapsed". Quite informative!
Does anyone know what the error could be here? I thought as long as I used es6 style imports and exports I wouldn't receive errors. Could this be due to the first require() statement of speech.js? Any help would be appreciated. I've felt like banging my head against the wall for the past 40 minutes.
May not be the correct answer but I believe it has a good chance of being right. I believe that since node is just a runtime environment and not a part of the actual browser, you aren't able to use node modules with react (a frontend framework). The solution to this quandary would be to use something like electron.

Extract WAV header on javascript frontend (ReactJS)

I'm trying to analyze a file I'll be uploading from react, I need to know if it can be uploaded based on several factors.
I found https://github.com/TooTallNate/node-wav
It works great on nodejs and I'm trying to use it on react. The sample creates a readable stream and pipes it to the wav reader.
var fs = require('fs');
var wav = require('wav');
var file = fs.createReadStream('track01.wav');
var reader = new wav.Reader();
// the "format" event gets emitted at the end of the WAVE header
reader.on('format', function (format) {
//Format of the file
console.log(format);
});
file.pipe(reader);
Using FilePond controller I'm able to get a base64 string of the file. But I can't figure out how to pass it to the reader
this is what I have so far on ReactJS:
var reader = new wav.Reader();
reader.on('format', function (format) {
//Format of file
console.log('format', format);
});
const buffer = new Buffer(base64String, 'base64')
const readable = new Readable()
readable._read = () => { }
readable.push(buffer)
readable.push(null)
readable.pipe(reader)
But I get Error: bad "chunk id": expected "RIFF" or "RIFX", got "u+Zj"
Since this file works on NodeJS with the same lib is obvious I'm doing something wrong.
EDIT:
this was a problem with my Base64 string, this method works if anyone needs to analyze a wav on the frontend

Resources