Why does my ffmpeg audio sound slower and deeper - sample rate mismatch - javascript

ok so this is a discord bot to record voice chat
https://hatebin.com/hgjlazacri
Now the bot works perfectly fine but the issue is that the audio sounds a bit deeper and slower than normal.. Why does it happen? how can I make the audio sound 1:1..
const Discord = require('discord.js');
const client = new Discord.Client();
const ffmpegInstaller = require('#ffmpeg-installer/ffmpeg');
const ffmpeg = require('fluent-ffmpeg');
ffmpeg.setFfmpegPath(ffmpegInstaller.path);
const fs = require('fs-extra')
const mergeStream = require('merge-stream');
const config = require('./config.json');
const { getAudioDurationInSeconds } = require('get-audio-duration');
const cp = require('child_process');
const path1 = require('path');
const Enmap = require('enmap');
const UserRecords = require("./models/userrecords.js")
const ServerRecords = require("./models/serverrecords.js")
let prefix = `$`
class Readable extends require('stream').Readable { _read() {} }
let recording = false;
let currently_recording = {};
let mp3Paths = [];
const silence_buffer = new Uint8Array(3840);
const express = require('express')
const app = express()
const port = 3000
const publicIP = require('public-ip')
const { program } = require('commander');
const { path } = require('#ffmpeg-installer/ffmpeg');
const version = '0.0.1'
program.version(version);
let debug = false
let runProd = false
let fqdn = "";
const mongoose = require("mongoose");
const MongoClient = require('mongodb').MongoClient;
mongoose.connect('SECRRET',{
useNewUrlParser: true
}, function(err){
if(err){
console.log(err);
}else{
console.log("Database connection initiated");
}
});
require("dotenv").config()
function bufferToStream(buffer) {
let stream = new Readable();
stream.push(buffer);
return stream;
}
client.commands = new Enmap();
client.on('ready', async () => {
console.log(`Logged in as ${client.user.tag}`);
let host = "localhost"
let ip = await publicIP.v4();
let protocol = "http";
if (!runProd) {
host = "localhost"
} else {
host = `35.226.244.186`;
}
fqdn = `${protocol}://${host}:${port}`
app.listen(port, `0.0.0.0`, () => {
console.log(`Listening on port ${port} for ${host} at fqdn ${fqdn}`)
})
});
let randomArr = []
let finalArrWithIds = []
let variable = 0
client.on('message', async message => {
console.log(`fuck`);
if(message.content === `$record`){
mp3Paths = []
finalArrWithIds = []
let membersToScrape = Array.from(message.member.voice.channel.members.values());
membersToScrape.forEach((member) => {
if(member.id === `749250882830598235`) {
console.log(`botid`);
}
else {
finalArrWithIds.push(member.id)
}
})
const randomNumber = Math.floor(Math.random() * 100)
randomArr = []
randomArr.push(randomNumber)
}
const generateSilentData = async (silentStream, memberID) => {
console.log(`recordingnow`)
while(recording) {
if (!currently_recording[memberID]) {
silentStream.push(silence_buffer);
}
await new Promise(r => setTimeout(r, 20));
}
return "done";
}
console.log(generateSilentData, `status`)
function generateOutputFile(channelID, memberID) {
const dir = `./recordings/${channelID}/${memberID}`;
fs.ensureDirSync(dir);
const fileName = `${dir}/${randomArr[0]}.aac`;
console.log(`${fileName} ---------------------------`);
return fs.createWriteStream(fileName);
}
if (!fs.existsSync("public")) {
fs.mkdirSync("public");
}
app.use("/public", express.static("./public"));
if (!message.guild) return;
if (message.content === config.prefix + config.record_command) {
if (recording) {
message.reply("bot is already recording");
return
}
if (message.member.voice.channel) {
recording = true;
const connection = await message.member.voice.channel.join();
const dispatcher = connection.play('./audio.mp3');
connection.on('speaking', (user, speaking) => {
if (speaking.has('SPEAKING')) {
currently_recording[user.id] = true;
} else {
currently_recording[user.id] = false;
}
})
let members = Array.from(message.member.voice.channel.members.values());
members.forEach((member) => {
if (member.id != client.user.id) {
let memberStream = connection.receiver.createStream(member, {mode : 'pcm', end : 'manual'})
let outputFile = generateOutputFile(message.member.voice.channel.id, member.id);
console.log(outputFile, `outputfile here`);
mp3Paths.push(outputFile.path);
silence_stream = bufferToStream(new Uint8Array(0));
generateSilentData(silence_stream, member.id).then(data => console.log(data));
let combinedStream = mergeStream(silence_stream, memberStream);
ffmpeg(combinedStream)
.inputFormat('s32le')
.audioFrequency(44100)
.audioChannels(2)
.on('error', (error) => {console.log(error)})
.audioCodec('aac')
.format('adts')
.pipe(outputFile)
}
})
} else {
message.reply('You need to join a voice channel first!');
}
}
if (message.content === config.prefix + config.stop_command) {
let date = new Date();
let dd = String(date.getDate()).padStart(2, '0');
let mm = String(date.getMonth() + 1).padStart(2, '0');
let yyyy = date.getFullYear();
date = mm + '/' + dd + '/' + yyyy;
let currentVoiceChannel = message.member.voice.channel;
if (currentVoiceChannel) {
recording = false;
await currentVoiceChannel.leave();
let mergedOutputFolder = './recordings/' + message.member.voice.channel.id + `/${randomArr[0]}/`;
fs.ensureDirSync(mergedOutputFolder);
let file_name = `${randomArr[0]}` + '.aac';
let mergedOutputFile = mergedOutputFolder + file_name;
let download_path = message.member.voice.channel.id + `/${randomArr[0]}/` + file_name;
let mixedOutput = new ffmpeg();
console.log(mp3Paths, `mp3pathshere`);
mp3Paths.forEach((mp3Path) => {
mixedOutput.addInput(mp3Path);
})
console.log(mp3Paths);
//mixedOutput.complexFilter('amix=inputs=2:duration=longest');
mixedOutput.complexFilter('amix=inputs=' + mp3Paths.length + ':duration=longest');
let processEmbed = new Discord.MessageEmbed().setTitle(`Audio Processing.`)
processEmbed.addField(`Audio processing starting now..`, `Processing Audio`)
processEmbed.setThumbnail(`https://media.discordapp.net/attachments/730811581046325348/748610998985818202/speaker.png`)
processEmbed.setColor(` #00FFFF`)
const processEmbedMsg = await message.channel.send(processEmbed)
async function saveMp3(mixedData, outputMixed) {
console.log(`${mixedData} MIXED `)
return new Promise((resolve, reject) => {
mixedData.on('error', reject).on('progress',
async (progress) => {
let processEmbedEdit = new Discord.MessageEmbed().setTitle(`Audio Processing.`)
processEmbedEdit.addField(`Processing: ${progress.targetSize} KB converted`, `Processing Audio`)
processEmbedEdit.setThumbnail(`https://media.discordapp.net/attachments/730811581046325348/748610998985818202/speaker.png`)
processEmbedEdit.setColor(` #00FFFF`)
processEmbedMsg.edit(processEmbedEdit)
console.log('Processing: ' + progress.targetSize + ' KB converted');
}).on('end', () => {
console.log('Processing finished !');
resolve()
}).saveToFile(outputMixed);
console.log(`${outputMixed} IT IS HERE`);
})
}
// mixedOutput.saveToFile(mergedOutputFile);
await saveMp3(mixedOutput, mergedOutputFile);
console.log(`${mixedOutput} IN HEREEEEEEE`);
// We saved the recording, now copy the recording
if (!fs.existsSync(`./public`)) {
fs.mkdirSync(`./public`);
}
let sourceFile = `${__dirname}/recordings/${download_path}`
console.log(`DOWNLOAD PATH HERE ${download_path}`)
const guildName = message.guild.id;
const serveExist = `/public/${guildName}`
if (!fs.existsSync(`.${serveExist}`)) {
fs.mkdirSync(`.${serveExist}`)
}
let destionationFile = `${__dirname}${serveExist}/${file_name}`
let errorThrown = false
try {
fs.copySync(sourceFile, destionationFile);
} catch (err) {
errorThrown = true
await message.channel.send(`Error: ${err.message}`)
}
const usersWithTag = finalArrWithIds.map(user => `\n <#${user}>`);
let timeSpent = await getAudioDurationInSeconds(`public/${guildName}/${file_name}`)
let timesSpentRound = Math.floor(timeSpent)
let finalTimeSpent = timesSpentRound / 60
let finalTimeForReal = Math.floor(finalTimeSpent)
if(!errorThrown){
//--------------------- server recording save START
class GeneralRecords {
constructor(generalLink, date, voice, time) {
this.generalLink = generalLink;
this.date = date;
this.note = `no note`;
this.voice = voice;
this.time = time
}
}
let newGeneralRecordClassObject = new GeneralRecords(`${fqdn}/public/${guildName}/${file_name}`, date, usersWithTag, finalTimeForReal)
let checkingServerRecord = await ServerRecords.exists({userid: `server`})
if(checkingServerRecord === true){
existingServerRecord = await ServerRecords.findOne({userid: `server`})
existingServerRecord.content.push(newGeneralRecordClassObject)
await existingServerRecord.save()
}
if(checkingServerRecord === false){
let serverRecord = new ServerRecords()
serverRecord.userid = `server`
serverRecord.content.push(newGeneralRecordClassObject)
await serverRecord.save()
}
//--------------------- server recording save STOP
}
//--------------------- personal recording section START
for( member of finalArrWithIds) {
let personal_download_path = message.member.voice.channel.id + `/${member}/` + file_name;
let sourceFilePersonal = `${__dirname}/recordings/${personal_download_path}`
let destionationFilePersonal = `${__dirname}${serveExist}/${member}/${file_name}`
await fs.copySync(sourceFilePersonal, destionationFilePersonal);
const user = client.users.cache.get(member);
console.log(user, `user here`);
try {
ffmpeg.setFfmpegPath(ffmpegInstaller.path);
ffmpeg(`public/${guildName}/${member}/${file_name}`)
.audioFilters('silenceremove=stop_periods=-1:stop_duration=1:stop_threshold=-90dB')
.output(`public/${guildName}/${member}/personal-${file_name}`)
.on(`end`, function () {
console.log(`DONE`);
})
.on(`error`, function (error) {
console.log(`An error occured` + error.message)
})
.run();
}
catch (error) {
console.log(error)
}
// ----------------- SAVING PERSONAL RECORDING TO DATABASE START
class PersonalRecords {
constructor(generalLink, personalLink, date, time) {
this.generalLink = generalLink;
this.personalLink = personalLink;
this.date = date;
this.note = `no note`;
this.time = time;
}
}
let timeSpentPersonal = await getAudioDurationInSeconds(`public/${guildName}/${file_name}`)
let timesSpentRoundPersonal = Math.floor(timeSpentPersonal)
let finalTimeSpentPersonal = timesSpentRoundPersonal / 60
let finalTimeForRealPersonal = Math.floor(finalTimeSpentPersonal)
let newPersonalRecordClassObject = new PersonalRecords(`${fqdn}/public/${guildName}/${file_name}`, `${fqdn}/public/${guildName}/${member}/personal-${file_name}`, date, finalTimeForRealPersonal)
let checkingUserRecord = await UserRecords.exists({userid: member})
if(checkingUserRecord === true){
existingUserRecord = await UserRecords.findOne({userid: member})
existingUserRecord.content.push(newPersonalRecordClassObject)
await existingUserRecord.save()
}
if(checkingUserRecord === false){
let newRecord = new UserRecords()
newRecord.userid = member
newRecord.content.push(newPersonalRecordClassObject)
await newRecord.save()
}
// ----------------- SAVING PERSONAL RECORDING TO DATABASE END
const endPersonalEmbed = new Discord.MessageEmbed().setTitle(`Your performance was amazing ! Review it here :D`)
endPersonalEmbed.setColor('#9400D3')
endPersonalEmbed.setThumbnail(`https://media.discordapp.net/attachments/730811581046325348/745381641324724294/vinyl.png`)
endPersonalEmbed.addField(`📅 Date`, `${date}`)
endPersonalEmbed.addField(`⏰ Time spent by you`, `${finalTimeForRealPersonal} minute(s)`)
endPersonalEmbed.addField(`🔻 Download`, `${fqdn}/public/${guildName}/${member}/personal-${file_name}`)
endPersonalEmbed.setFooter(`Use \`$myrecordings\` to get a list of all your recordings !`)
user.send(endPersonalEmbed)
}
// ----------------- personal recording section OVER
const endEmbed = new Discord.MessageEmbed().setTitle(`I will be honest, that recording session was sick !`)
endEmbed.setColor('#9400D3')
endEmbed.addField(`🎙️ Voices`, usersWithTag)
endEmbed.addField(`⏰ Time spent`, `${finalTimeForReal} minute(s)`)
endEmbed.addField(`🔻 Download`, `${fqdn}/public/${guildName}/${file_name}`)
endEmbed.setThumbnail(`https://media.discordapp.net/attachments/730811581046325348/745370416352067704/microphone.png`)
endEmbed.setFooter(`Check your DMs for a recording of your personal voice during this session.`)
message.channel.send(endEmbed)
} else {
message.reply('You need to join a voice channel first!');
}
}
if (message.content.indexOf(prefix) !== 0) return;
const args = message.content.slice(prefix.length).trim().split(/ +/g);
const command = args.shift().toLowerCase();
const cmd = client.commands.get(command);
if (!cmd) return;
cmd.run(client, message, args);
});
fs.readdir('./commands/', async (err, files) => {
if (err) return console.error;
files.forEach(file => {
if (!file.endsWith('.js')) return;
let props = require(`./commands/${file}`);
let cmdName = file.split('.')[0];
console.log(`Loaded command '${cmdName}'`);
// Register extra Listeners
client.commands.set(cmdName, props);
});
});
async function main() {
program.option('-debug')
program.option('-prod')
program.parse(process.argv)
console.log(program.opts())
if (program.Debug != undefined) {
debug = !debug
}
if (program.Prod != undefined) {
runProd = !runProd
}
if (runProd) {
client.login(process.env.DISCORD_TOKEN_PROD).catch(e => {
console.log("ERROR")
console.log(e)
})
} else {
client.login(process.env.DISCORD_TOKEN_TEST).catch(e => {
console.log("ERROR")
console.log(e)
})
}
}
main()
Now the bot works perfectly fine but the issue is that the audio sounds a bit deeper and slower than normal.. Why does it happen? how can I make the audio sound 1:1..
How do i fix the sample rate mismatch
Note; I have already tried to set Audio freq as 48000 but it has made no difference.

Related

How to write file using fs.createWriteStream

am trying to build a web scraper that downloads all the pdfs in a website. i've written all the logic necessary to do this but for some reason it downloads an empty pdf file which is not suppose to be so, the problem seems to be coming from the downloadFile function when i try to pipe the data which for some reason seems not to be working because i get an empty pdf file after the function is ran. i'll would appreciate it if someone can help me out with this problem, thanks.
here's a sample of my code:
app.js
const fs = require("fs");
const path = require("path");
const cheerio = require("cheerio");
const axiosInstance = require("./getAxios");
const axios = axiosInstance();
const Surl = "https://www.health.gov.ng/";
// linkList sample: "https://www.health.gov.ng/index.php?option=com_content&view=article&id=143&Itemid=512";
let = connectionFailCount = 0;
let linkList = [];
let dlinkList = [];
const getWebsiteLinks = async (Surl) => {
try {
console.log(`Crawling all links from: ${Surl}`);
const response = await axios.get(Surl);
const $ = cheerio.load(response.data);
const ranges = $("a").each(function (idx, el) {
if ($(el).attr("href")) {
return $(el).attr("href");
}
});
for (let index = 0; index < ranges.length; index++) {
let raw_links = $("a")[index].attribs.href;
if (raw_links.startsWith("/")) {
linkList.push(Surl + raw_links);
}
}
if (linkList.length > 0) {
console.log(`Finished crawling links: Found ${linkList.length} links`);
console.log(
"--------------------------------------------------------\n\n"
);
}
return;
} catch (error) {
if (connectionFailCount === 0) {
connectionFailCount += 1;
getWebsiteLinks(Surl);
console.log(`Connection error. \n
Reconnecting to server....`);
} else if (connectionFailCount === 5) {
console.error(`Can not connect to server. Try again later.`);
}
}
};
const downloadLinks = async (linkList) => {
try {
console.log("Crawling links to find pdf links. this may take a while...");
for (const link of linkList) {
const response = await axios.get(link);
// Skip where there's delayed server response
if (response.code === "ECONNRESET") continue;
const $ = cheerio.load(response.data);
$("a").each(function (idx, el) {
if ($(el)?.attr("href")?.endsWith(".pdf")) {
let addr = $(el).attr("href");
let dlink = Surl + addr;
dlinkList.push({
pathName: addr,
url: dlink,
});
}
});
}
console.log(dlinkList);
if (dlinkList.length > 0) {
console.log(`Crawling Finish: Found ${dlinkList.length} pdf links`);
console.log(
"--------------------------------------------------------\n\n"
);
}
} catch (error) {
if (connectionFailCount === 0) {
connectionFailCount += 1;
console.log(`Connection error. \n
Reconnecting to server: ${connectionFailCount} count`);
downloadLinks(linkList);
}
if (connectionFailCount === 3) {
console.error(`Can not connect to server. Try again later.`);
return;
}
// console.error("downloadLinksError: ", error);
}
};
const downloadFiles = async (dlinkList) => {
console.log("Creating directory to save PDF files");
const appRoot = path.dirname(path.resolve(__dirname));
// Had to change and restructure code due to error
const folderName = `PDF/${Surl.split("/").pop()}`;
const subFolderName = Surl.split("/").pop();
try {
if (!fs.existsSync(path.join(appRoot, folderName))) {
fs.mkdirSync(path.join(appRoot, "PDF"));
fs.mkdirSync(path.join(`${appRoot}/PDF`, subFolderName));
}
dlinkList.forEach(async (link) => {
let name = link.pathName;
let url = link.url;
let file = fs
.createWriteStream(
`${appRoot}/${folderName}/${name.split("/").pop()}`,
"utf-8"
)
.on("error", (err) => {
console.error("createWriteStreamError: ", err);
});
try {
console.log("Downloading PDF file...");
const { data } = await axios({
url,
method: "GET",
responseType: "stream",
});
if (data) {
console.log("PDF file Downloaded");
data.pipe(file);
}
} catch (error) {
console.error(error);
}
});
return;
} catch (error) {
console.error("downloadFilesError: ", error);
}
};
(async () => {
await getWebsiteLinks(Surl);
await downloadLinks(linkList);
await downloadFiles(dlinkList);
})();
getAxios.js
const axios = require("axios");
const https = require("https");
module.exports = function () {
const domain = "https://www.health.gov.ng/";
let instance;
if (!instance) {
//create axios instance
instance = axios.create({
baseURL: domain,
timeout: 60000, // Increase time out incase of network delay or delayed server response
maxContentLength: 500 * 1000 * 1000, // Increase maximum response ata length
httpsAgent: new https.Agent({ keepAlive: true }),
headers: { "Content-Type": "application/xml" },
});
}
return instance;
};

message event updating discord.js from v12 to v13

I have a discord bot, and I was using v12. When the new v13 version came out, I tried to update my bot but it was too much for me. Now, I tried again and it went a little better. Now at least it gets on, but doesn´t reply! When I execute the help command, it returns me this error:
TypeError: message.channel.startTyping is not a function
at Client.module.exports (/app/events/messageCreate.js:172:21)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
This is my bot.js file:
const { Client, Intents } = require('discord.js');
const Discord = require("discord.js");
const { I18n } = require("locale-parser");
const Mongoose = require("mongoose");
const client = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES] });
//client.errors = require("./modules/errors");
client.config = require("./config.json");
client.i18n = new I18n({ defaultLocale: "en" });
Mongoose.connect(client.config.mongo_uri, {
useNewUrlParser: true,
useUnifiedTopology: true
});
client.database = Mongoose.connection;
client.database.on("error", err => {
throw err;
});
client.database.once("open", async () => {
require("./models");
require("./handlers/eventHandler")(client);
require("./handlers/moduleHandler")(client);
client.login(process.env.BOT_TOKEN);
});
And this one, is app/events/messageCreate.js:
const Discord = require("discord.js");
const embeds = require("../modules/embeds.js");
const cooldown = {};
const Uses = require("../models/uses.js");
const Enmap = require("enmap");
const db = require("megadb"); //aca definimos db para lo que necesitemos mas adelante
let desactivadodb = new db.crearDB("ComandosDesactivados");
const fs = require("fs");
const guildModel = require("../models/guildModel");
var language = "";
module.exports = async message => {
try {
const bot = message.client;
const funcs = require("../modules/functions.js");
bot.color = funcs.color(message);
bot.lang = funcs.lang(message) || "en";
bot.langs = message.guild.language || language;
const msg = message;
if (msg.author.bot || !msg.guild) return;
let prefix = bot.config.prefixes[0];
let argsSlice = prefix.length;
if (!msg.content.toLowerCase().startsWith(prefix.toLowerCase())) {
let content = msg.content.trim();
let mention1 = "<#!" + bot.user.id + ">";
let mention2 = "<#" + bot.user.id + ">";
if (content == mention1 || content == mention2)
return embeds.mention(msg, prefix, bot);
if (content.startsWith(mention1)) argsSlice = mention1.length;
else if (content.startsWith(mention2)) argsSlice = mention2.length;
else return;
}
let args = msg.content
.slice(argsSlice)
.trim()
.split(/ +/g);
let command = args.shift().toLowerCase();
let cmdFile =
bot.commands.get(command) ||
bot.commands.find(
cmdFile => cmdFile.aliases && cmdFile.aliases.includes(command)
);
if (!cmdFile) return;
if (message.guild && !message.guild.language) {
let language = "en";
let guildDocument = await guildModel.findOne({
guildID: message.guild.id
});
if (guildDocument && guildDocument.language)
message.guild.language = guildDocument.language;
}
if (!message.guild) {
let language = "en"
};
if (cmdFile.guildOnly && !message.guild)
return await message.channel.send(
message.client.i18n.get(language, "errors", "command_guild_only")
);
if (
!cmdFile.enabled ||
desactivadodb.tiene(
`ComandosDesactivados_${command}_${message.guild.id}`,
`g${message.guild.id}`
)
)
return await message.channel.send(
message.client.i18n.get(
message.guild.language,
"errors",
"command_disabled"
)
);
if (
cmdFile.ownerOnly &&
!message.client.config.owners.includes(message.author.id)
)
return await message.channel.send(
message.client.i18n.get(
language,
"errors",
"command_owner_only",
{ command: cmdFile.name }
)
);
if (cmdFile.nsfwOnly && !message.channel.nsfw)
return await message.channel.send(
message.client.i18n.get(language, "errors", "nsfw_only", {
command: cmdFile.name
})
);
if (
cmdFile.permissions &&
!// message.client.config.owners.includes(message.author.id) ||
message.member.permissions.has(cmdFile.permissions || "ADMINISTRATOR")
)
return await message.channel.send(
message.client.i18n.get(
language,
"errors",
"not_enough_permission",
{ permissions: cmdFile.permissions.join(", ") }
)
);
if (
cmdFile.botpermissions &&
!message.guild.me.permissions.has(
cmdFile.botpermissions || "ADMINISTRATOR"
)
)
return await message.channel.send(
message.client.i18n.get(
language,
"errors",
"not_bot_enough_permission",
{ permissions: cmdFile.botpermissions.join(", ") }
)
);
let numuses = 1;
Uses.findOne(
{
command: cmdFile.name
},
(err, res) => {
if (err) console.log(err);
if (!res) {
const newDoc = new Uses({
command: cmdFile.name,
uses: 0
});
newDoc.save().catch(err => console.log(err));
} else {
res.uses = res.uses + numuses;
res.save().catch(err => console.log(err));
}
}
);
if (cmdFile.cooldown) {
if (!cooldown[msg.author.id]) cooldown[msg.author.id] = {};
let time = cooldown[msg.author.id][cmdFile.name] || 0;
if (time && time > Date.now()) {
let wait = ((time - Date.now()) / 1000).toFixed(2);
return message.channel.send(
message.client.i18n.get(
language,
"errors",
"wait_cooldown",
{ cooldown: wait, command: cmdFile.name }
)
);
}
cooldown[msg.author.id][cmdFile.name] =
Date.now() + cmdFile.cooldown * 1000;
}
message.channel.startTyping();
cmdFile.exec(bot, msg, args).then(message.channel.stopTyping());
} catch (err) {
console.error(err);
}
};
I just changed the Client thing of the bot.js, but I think I don´t understand the actual module.exports and I am very sure that there is where the error is.
In discord.js v13 TextChannel.startTyping() method was replaced by TextChannel.sendTyping() which you have to use now! As moving to v13 guide says: "This method automatically stops typing after 10 seconds, or when a message is sent"!

Deleting Messages with time

So I want it to delete some specific messages if the date/Minutes is 55 and the month is this month! Although I got some Discord API errors as specified below! I was trying to make a delay and to make sure that the msg even exists but no luck it gave me the same error!
const ytdl = require('ytdl-core');
const editJsonFile = require("edit-json-file");
var fs = require('file-system');
var path = require('path');
const prefix = "v_";
let count;
exports.run = async (client, message, args, ops) => {
const channel = client.channels.cache.get("813794049445462036");
const channel2 = client.channels.cache.get("813801699469819984");
const channelog = client.channels.cache.get("814561365510586400");
const monthlog = client.channels.cache.get("814758448700719155");
let number = editJsonFile(`premium/premium.json`);
let endDate = editJsonFile(`premium/endate.json`);
let count = editJsonFile(`premium/count.json`);
let month = editJsonFile(`premium/month.json`);
month.save();
number.save();
endDate.save();
count.save();
count.set(`p`, 0);
count.set(`p1`, 0);
count.save();
let p = count.get(`p`);
let p1 = count.get(`p1`);
//Reset
setTimeout(async function() {
channel2.messages.fetch({ limit: 100 }).then(messages => {
messages.forEach(async message => {
p = count.get(`p`);
p1 = count.get(`p1`);
var today = new Date();
var date = today.getMinutes()
var montht = new Date();
var monthcheck = montht.getMonth();
if (date == 55) {
setTimeout(async function() {
monthlog.messages.fetch({ limit: 100 }).then(messages => {
messages.forEach(message3 => {
p = count.get(`p`);
p1 = count.get(`p1`);
console.log(monthcheck);
if (message3.content == 2) {
let number = editJsonFile(`premium/premium.json`);
number.save();
const userid2 = number.get(`${p1}`);
setTimeout(async function() {
if (message != undefined){
await message.delete({ timeout: 250 });
}
}, 0)
setTimeout(async function() {
if (message3 != undefined){
await message3.delete({ timeout: 500 });
}
}, 1000)
setTimeout(async function() {
channel.messages.fetch({ limit: 100 }).then(messages => {
messages.forEach(message2 => {
p = count.get(`p`);
p1 = count.get(`p1`);
console.log(userid2);
console.log(`${message2.content}`);
console.log(`${p1}`)
if(userid2 == message2.content) {
setTimeout(async function() {
await message2.delete({ timeout: 100 });
}, 0)
number = editJsonFile(`premium/premium.json`);
number.unset(`${p1}`)
number.save();
}
endDate.unset(`${p1}`);
endDate.save();
month.unset(`${p1}`);
month.save();
setTimeout(async function() {
channelog.send(`💿 <#${userid2}>'s premium has expired from partnering!'`)
}, 500)
message.delete();
})
})
}, 5000)
}
else {
p = count.get(`p`);
p1 = count.get(`p1`);
pf = count.get(`pf`);
pf1 = count.get(`pf1`);
if (p == p1) {
endDate.set(`${p1}`, message.content)
endDate.save();
month.set(`${p1}`, message3.content)
month.save();
}
else {
endDate.set(`${p1}`, message.content)
endDate.save();
month.set(`${p1}`, message3.content)
month.save();
count.set(`p1`, p1+1);
count.save();
}
}
})
})
}, 3000);
}
})
})
}, 5000)
setTimeout(function() {
channel.messages.fetch({ limit: 100 }).then(messages => {
messages.forEach(message => {
p = count.get(`p`);
p1 = count.get(`p1`);
number = editJsonFile(`premium/premium.json`);
number.set(`${p}`, message.content)
number.save();
count = editJsonFile(`premium/count.json`);
count.set(`p`, p+1);
count.save();
})
})
}, 1000)
count = editJsonFile(`premium/count.json`);
count.set(`p`, 0);
count.set(`p1`, 0);
count.save();
number.save();
}
This is the error I got for both of the times I tested with my code:
C:\Users\cedri\Desktop\vibe-main\node_modules\discord.js\src\rest\RequestHandler.js:154
throw new DiscordAPIError(request.path, data, request.method, res.status);
^
DiscordAPIError: Unknown Message
at RequestHandler.execute (C:\Users\cedri\Desktop\vibe-main\node_modules\discord.js\src\rest\RequestHandler.js:154:13)
at processTicksAndRejections (node:internal/process/task_queues:93:5)
at async RequestHandler.push (C:\Users\cedri\Desktop\vibe-main\node_modules\discord.js\src\rest\RequestHandler.js:39:14)
at async MessageManager.delete (C:\Users\cedri\Desktop\vibe-main\node_modules\discord.js\src\managers\MessageManager.js:126:5)
at async Timeout._onTimeout (C:\Users\cedri\Desktop\vibe-main\events\premium.js:60:23) {
method: 'delete',
path: '/channels/813801699469819984/messages/814796597518139413',
code: 10008,
httpStatus: 404
}
Unknown Message occurs most commonly when you are trying to delete a message that does not exist.
This is happening because you are using an unreliable syntax for finding the channels. #get was changed in V12, I would use #find.
To combat this, you should use
await message.guild.channels.fetch(); //fetches all channels
const channel = client.channels.cache.find(channel => channel.id === "<id here>");
To make sure you search through all channels, use an await message.guild.channels.fetch()
Here is the changelog for V12

Discord.js A different js file for each command

Hello so I am learning javascript and can't figure out how to have multiple .js files for each command I have some code that I followed online however it does not seem to work for me (I am on discord.js v12.2)
const Discord = require('discord.js');
const client = new Discord.Client();
const fs = require('fs');
const { prefix, token } = require('./config.json');
client.commands = new Discord.Collection();
client.on('ready', () => {
console.log(`Logged in as ${client.user.tag}!`);
client.user.setActivity("Type ~help for commands")
});
fs.readdir('./cmds', (err,files) => {
if (err) {
console.log(err);
}
let cmdFiles = files.filter(f => f.split(".").pop() === "js");
if (cmdFiles.length === 0){
console.log("No files found");
return;
}
cmdFiles.forEach((f,i) => {
let props = require(`./cmds/${f}`);
console.log(`${i+1}: ${f} loaded`);
client.commands.set(props.help.name, props);
})
})
client.on('message',msg => {
if (msg.channel.type === "dm") return;
if (msg.author.bot) return;
if (msg.channel.type === "dm") return;
if (msg.author.bot) return;
let msg_array = msg.content.split(" ");
let args1 = msg.content.slice(prefix.length).trim().split(' ');
let args = msg_array.slice(1);
let cmd = args1.shift().toLowerCase();
let command = client.commands.get(cmd);
if (!msg.content.startsWith(prefix)) return;
if (client.commands.has(cmd)) {
command = client.commands.get(cmd);
if (cmd){
command.run(client,msg,args,args1);
}
}
});
client.login(token);
The error message I am getting with this code is
TypeError: Cannot read property 'name' of undefined
at C:\Users\rubyn\Desktop\AlexLearning\index.js:27:40
at Array.forEach (<anonymous>)
at C:\Users\rubyn\Desktop\AlexLearning\index.js:24:14
at FSReqCallback.oncomplete (fs.js:164:23)
Thank you for taking time to read this :)
You need to require all of your "cmds" first at the top. You can create an object with those "cmds" that you can later reference in the forEach. Have the key for each "cmd" in the object be the value of ${f};
UPDATE
const Discord = require('discord.js');
const client = new Discord.Client();
const fs = require('fs');
const { prefix, token } = require('./config.json');
// Require all your individual cmd files
const cmd1 = require(`./cmds/cmd1`);
const cmd2 = require(`./cmds/cmd2`);
const cmd3 = require(`./cmds/cmd3`);
const cmd4 = require(`./cmds/cmd4`);
// create an object to reference them later
const cmdObj = {
cmd1,
cmd2,
cmd3,
cmd4
};
client.commands = new Discord.Collection();
client.on('ready', () => {
console.log(`Logged in as ${client.user.tag}!`);
client.user.setActivity("Type ~help for commands")
});
fs.readdir('./cmds', (err,files) => {
if (err) {
console.log(err);
}
let cmdFiles = files.filter(f => f.split(".").pop() === "js");
if (cmdFiles.length === 0){
console.log("No files found");
return;
}
cmdFiles.forEach((f,i) => {
// Dynamically reference an object property
let props = cmdObj[f];
console.log(`${i+1}: ${f} loaded`);
client.commands.set(props.help.name, props);
})
})
client.on('message',msg => {
if (msg.channel.type === "dm") return;
if (msg.author.bot) return;
if (msg.channel.type === "dm") return;
if (msg.author.bot) return;
let msg_array = msg.content.split(" ");
let args1 = msg.content.slice(prefix.length).trim().split(' ');
let args = msg_array.slice(1);
let cmd = args1.shift().toLowerCase();
let command = client.commands.get(cmd);
if (!msg.content.startsWith(prefix)) return;
if (client.commands.has(cmd)) {
command = client.commands.get(cmd);
if (cmd){
command.run(client,msg,args,args1);
}
}
});
client.login(token);

Chunks of code being ignored. No errors, no logs. Might be API related

The code below doesn't give any errors but I have a weird bug anyway. I have four streams to aggregate twitter feeds to a discord channel. 3 of those often work. but whenever I run the code there is always a feed not coming through, no line is getting executed in that stream. This often happens with the IntelFeed and/or covid-19feed. When I wait for some time or repeatedly rerun the code it starts working. I think it may be due to the structure of the code (not having enough time to fulfill the conditions) or due to the API. But I can't confirm the latter one.
const Discord = require('discord.js');
const botconfig = require("./botconfig.json");
const { Client, RichEmbed } = require('discord.js');
const twitterFeedsModel = require('./models/twitterFeedsModel');
const client = new Discord.Client();
const mongoose = require('mongoose', {useNewUrlParser: true}, { useUnifiedTopology: true });
mongoose.connect('mongodb://localhost/twitterFeedDatabeses');
const Twit = require('twit');
const T = new Twit({
consumer_key: botconfig.consumer_key,
consumer_secret: botconfig.consumer_key_secret,
access_token: botconfig.access_token,
access_token_secret: botconfig.access_token_secret,
});
client.on("ready", () => {
console.log(`Logged in as ${client.user.tag}!`);
//Newsfeed
const stream = T.stream("statuses/filter", { follow: ["5402612", "1652541", "831470472", "26792275", "380648579", "426802833", "144274618", "31696962", "1642135962", "16561457"]});
const scr_name = ['BBCbreaking', 'Reuters', 'pewglobal', 'ForeignPolicy', 'AFP', 'AP_Politics', 'economics', 'dw_europe', 'BBCNewsAsia', 'RadioFreeAsia']
stream.on("tweet", function (tweet) {
if(!scr_name.includes(tweet.user.screen_name)) return;
client.channels.get("646745474514026506").send(`https://twitter.com/${tweet.user.screen_name}/status/${tweet.id_str}`);
});
//Covid-19stream
const secondStream = T.stream("statuses/filter", {follow: "2985479932"});
const secondScr_name = "BNODesk"
secondStream.on("tweet", function (tweet){
console.log(tweet.user.screen_name)
if(secondScr_name.includes(tweet.user.screen_name)) {
const tweetContent = tweet.text.split(" ");
console.log(tweetContent)
const filteredWords = ['thank', 'Thank', 'you', 'you.', 'you!']
console.log("It does include Breakin: " + tweetContent.includes("BREAKING:"))
if(!filteredWords.some(word => tweet.text.includes(word))){
if(tweetContent.includes("BREAKING:")){
console.log("It does include breaking (after if-statement): " + tweetContent.includes("BREAKING:"))
client.channels.get("645733080061181965").send(`https://twitter.com/${tweet.user.screen_name}/status/${tweet.id_str}`)
client.channels.get('645733080061181965').send('I found out this tweet covers important news')
} else if(!tweet.text.startsWith("#")){
client.channels.get("645733080061181965").send(`https://twitter.com/${tweet.user.screen_name}/status/${tweet.id_str}`)
client.channels.get("645733080061181965").send(`Hello <#283206528004259850>, there is a new tweet!`)
}
}
}
});
//GRUNNstream
const thirdStream = T.stream("statuses/filter", { follow: ["14907733", "22465767", "18549902", "451432440", "97639259", "2343981858"]});
const thirdScr_name = ['rtvnoord', 'oogtv', 'dvhn_nl', 'P2000Groningen', 'polgroningen', 'Sikkom050']
thirdStream.on("tweet", function (tweet) {
if(thirdScr_name.includes(tweet.user.screen_name)) {
client.channels.get("632705489108729867").send(`https://twitter.com/${tweet.user.screen_name}/status/${tweet.id_str}`);
}
});
// intelstream
const fourthStream = T.stream("statuses/filter", {follow: ['3331851939', '2407993940', '1140336427550552000', '2790057867', '2315512764', '1517300821', '70529694', '62248461', '146958450', '85904241', '762565517026664400']});
const fourthScr_name = ['IntelCrab', 'IntelDoge', 'IntelAgencyNGO', 'lummideast', 'bellingcat', 'obretix', 'JanesINTEL', 'BarzanSadiq', 'ragipsoyly', 'leventkemal', 'OmerOzkizilcik']
fourthStream.on("tweet", function (tweet) {
if(fourthScr_name.includes(tweet.user.screen_name)) {
client.channels.get("646745512011235339").send(`https://twitter.com/${tweet.user.screen_name}/status/${tweet.id_str}`);
}
});
});
module.exports.run = client.on('message', message => {
if (!message.content.startsWith(botconfig.prefix) || message.author.bot) return;
const args = message.content.slice(botconfig.prefix.length).split(/ +/);
const command = args.shift().toLowerCase();
if (command.length === 0) {
return message.channel.send(`I ain't gonna fill the command in by myself fam`);
}
if (command === 'add_twitter_feed'){
if (!args.length){
return message.channel.send("Please enter a valid value!")};
var twitterUsername_feed = args;
T.get('users/show', { screen_name: twitterUsername_feed.join() }, function (err, data, response) {
console.log(data.id)
const twitterFeedVar = new twitterFeedsModel({
_id: mongoose.Types.ObjectId(),
twitterUsernameAddedToFeed: twitterUsername_feed.join(),
twitterUsername_idAddedToFeed: data.id,
})
twitterFeedVar.save()
.then(result => console.log(result))
.catch(err => console.log(err))
twitterFeedVar.find()
.then(doc => {
message.channel.send(doc)
})
})
}
/*if (command === `savelist`) {
Test.find()
.then(doc => {
message.channel.send(doc)
})
}
*/
if (command === 'twitter_user_id'){
if (!args.length){
return message.channel.send("Please enter a valid value!")};
var twitterUsername_lookup = args;
console.log(`${message.member.user.tag} requested the ID of the following user: ` + twitterUsername_lookup.join())
T.get('users/show', { screen_name: twitterUsername_lookup.join() }, function (err, data, response) {
console.log(data)
message.channel.send(`This is the ID of ` + twitterUsername_lookup.join() + `: ` + data.id)
if (!data.id) {
return message.channel.send(`Twitter user not found.`)
}
})
message.delete()
}
if (command === `hello`){
return message.channel.send("Hi there :)")
}
if (command === `feedlist`){
var scr_name2 = ['BBCbreaking', 'Reuters', 'pewglobal', 'ForeignPolicy', 'AFP', 'AP_Politics', 'economics', 'dw_europe', 'BBCNewsAsia', 'RadioFreeAsia']
return message.channel.send(scr_name2)
}
if (command === `reload`) {
message.channel.send(`Reloading...`)
console.clear();
client.destroy()
client.login(botconfig.token);
message.channel.send(`Bot reloaded succesfully!`);
return;
}
});
module.exports.help = {
name: "testtest"
}
client.login(botconfig.token);

Categories

Resources