I'm currently trying to make a purge command right now (following reconlx's Purge Command tutorial for DJS v13), and I keep receiving a DiscordAPI Error.
The command only works once, however, it doesn't reply with embeds like it's supposed to, then crashes along with every other command there is. It does become functional again after a certain period of time then the cycle repeats over and over again.
I have made sure that I had the right intents (which I do) and such, but nothing seems to work... I have no idea what in the world is causing the error. Anyone who would be willing to help is doing me a favour.
Oh, and here's the code for purge.js and the error in question down below.
const { MessageEmbed } = require("discord.js");
const ms = require("ms");
module.exports = {
name: "purge",
description: "Purges messages",
userPermissions: ["MANAGE_MESSAGES"],
options: [
{
name: "amount",
description: "Amount of messages to purge",
type: "INTEGER",
required: true,
},
],
run: async (client, interaction) => {
const amount = interaction.options.getInteger("amount");
const limitEmbed = new MessageEmbed()
.setColor("#2F3136")
.setTitle("You may only purge 100 messages at a time!")
.setFooter({ text: "Error: Limit Reached" })
if (amount > 100)
return interaction.followUp({
embeds:
[limitEmbed],
});
const messages = await interaction.channel.messages.fetch({
limit: amount + 1,
});
const filtered = messages.filter(
(msg) => Date.now() - msg.createdTimestamp < ms("14 days")
);
await interaction.channel.bulkDelete(filtered)
const successEmbed = new MessageEmbed()
.setColor("#2F3136")
.setTitle(`Successfully purged ${filtered.size - 1} messages!`)
.setFooter({ text: "Action Successfully Performed" })
interaction.followUp({
embeds:
[successEmbed],
});
},
};
Error:
DiscordAPIError: Unknown Message
at RequestHandler.execute (C:\Users\admin\Desktop\Tonkotsu\node_modules\discord.js\src\rest\RequestHandler.js:350:13)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async RequestHandler.push (C:\Users\admin\Desktop\Tonkotsu\node_modules\discord.js\src\rest\RequestHandler.js:51:14)
at async InteractionWebhook.send (C:\Users\admin\Desktop\Tonkotsu\node_modules\discord.js\src\structures\Webhook.js:196:15) {
method: 'post',
path: '/webhooks/950050048618688572/aW50ZXJhY3Rpb246OTk5MjYyNTIyMTc3NzQ5MDAzOmhGaUJVQkF6YjduVUlZNTJsT1MwV254T2FYdEJiaUNMWDdwUWloYzhyNnJudERLMHhxak96RTlkTmpDQW5sdEhONnhKSGkyZkdlQndmWGJQSFM0dk52bGduZ3hBTlE3S3g4R2JBRWFRdDNEbmtrb3Z6a0hpVk8yU2hIYllyemhm?wait=true',
code: 10008,
httpStatus: 404,
requestData: {
json: {
content: undefined,
tts: false,
nonce: undefined,
embeds: [
{
title: 'Successfully purged 3 messages!',
type: 'rich',
description: null,
url: null,
timestamp: 0,
color: 3092790,
fields: [],
thumbnail: null,
image: null,
author: null,
footer: {
text: 'Action Successfully Performed',
icon_url: undefined
}
}
],
components: undefined,
username: undefined,
avatar_url: undefined,
allowed_mentions: undefined,
flags: undefined,
message_reference: undefined,
attachments: undefined,
sticker_ids: undefined
},
files: []
}
}
You should use interaction.reply(...) instead of interaction.followUp(...), followUp is used when you already replied to a message and want to continue replying to the interaction. So it will throw an error if you trying to use it on an interaction who hasn't been replied yet.
Related
I've tried this a few different ways and can't seem to get it to work.
I am trying to handle an error when a user enters an already existing username. The backend works fine, however I am trying to get sweetalert to respond appropriately
front end react jsx
const [errors, setErrors] = useState({
error: false,
message: ''
});
const saveUser = async(userData) =>{
await axios.post('/save_score', userData).then((res)=>{
if(res.status === 200){
Swal.fire({
icon: 'success',
title: 'Score saved!',
text: `${res.data.username} scored ${res.data.score} points`,
showCancelButton: true,
cancelButtonText: 'Hiscores',
confirmButtonText: 'Play again'
})
}
}).catch((err)=>{
if(err.response.status === 400){
setErrors({
error: true,
message: err.response.data.usernameError
})
}
});
}
const gameOver = (score) => {
Swal.fire({
title: 'Game over',
text: `You scored ${score} points! Save your score?`,
allowOutsideClick: false,
showConfirmButton: true,
showCancelButton: true,
confirmButtonText: 'Yes',
cancelButtonText: 'No'
}).then((response)=>{
if(response.isConfirmed){
//user confirmed
Swal.fire({
title: 'Enter your username',
input: 'text',
inputLabel: 'Username: ',
showCancelButton: true,
inputValidator: (value) => {
if(!value){
return 'Must enter a username!';
} else {
var userData = {username: value, score: score};
saveUser(userData).then(()=>{
console.log(errors);
})
}
}
})
} else {
console.log('user cancelled');
}
})
}
the problem I've been having with this specific attempt is that the state isn't changing. when I log after my saveUser().then(), the state comes back as its initialized even when I am trying to throw the username exists error.
I've also tried creating an error object, and inside the axios post's error, I set that objects error key to true and the errors response to that objects message key, but when that happens it seems axios post comes after any sort of error handling and it doesn't respond correctly.
let me know if this is enough info
This question already has answers here:
How to create a channel then find the ID
(2 answers)
Closed 6 months ago.
I'm currently making a simple Ticket System for my Bot and I want to send a Message to the new Channel my Bot created after clicking on a Button. The Channel create and everything else worked fine, but I don't know how to get the Channel ID from that new Channel. Does anyone know more than me? (I'm using discord.js v14)
Code from the Event after clicking on the Button:
const { EmbedBuilder, PermissionsBitField } = require("discord.js")
module.exports = {
data: {
name: 'panelbutton'
},
async execute(interaction, client) {
client.config = require('../../config');
const ticketchannel = interaction.guild.channels.create({
name: `${interaction.user.username}`,
permissionOverwrites: [
{
id: interaction.guild.id,
deny: [PermissionsBitField.Flags.ViewChannel]
},
{
id: interaction.user.id,
allow: [PermissionsBitField.Flags.ViewChannel, PermissionsBitField.Flags.SendMessages],
deny: [PermissionsBitField.Flags.UseApplicationCommands]
}
]
});
const wait = new EmbedBuilder()
.setTitle('Created! :white_check_mark:')
.setDescription(`Your Channel is created!`)
.setTimestamp(Date.now())
.setFooter({
text: client.config.bot.footer
});
await interaction.reply({
embeds: [wait], ephemeral: true
});
}
}
interaction.guild.channels.create returns a Promise resolving to a GuildChannel object which has an id property.
Add await before interaction.guild.channels.create and you should be able to access the ID using ticketchannel.id.
You can use Promise.Prototype.then() or create a variable to define the channel created, which you already did.
Promise.Prototype.then():
await interaction.guild.channels.create({
name: `${interaction.user.username}`,
permissionOverwrites: [
{
id: interaction.guild.id,
deny: [PermissionsBitField.Flags.ViewChannel]
},
{
id: interaction.user.id,
allow: [PermissionsBitField.Flags.ViewChannel, PermissionsBitField.Flags.SendMessages],
deny: [PermissionsBitField.Flags.UseApplicationCommands]
}
]
}).then(channel => {
const channelID = channel.id
console.log(channelID)
})
Creating a variable:
const ticketChannel = await interaction.guild.channels.create({
name: `${interaction.user.username}`,
permissionOverwrites: [
{
id: interaction.guild.id,
deny: [PermissionsBitField.Flags.ViewChannel]
},
{
id: interaction.user.id,
allow: [PermissionsBitField.Flags.ViewChannel, PermissionsBitField.Flags.SendMessages],
deny: [PermissionsBitField.Flags.UseApplicationCommands]
}
]
})
const ticketChannelID = ticketChannel.id
I'm currently working on a kick command (following reconlx's Kick, Ban, and Unban command tutorial). All commands stop working (including the kick command).
If anyone can take a look, it'd be helpful.
Code for kick.js and the error is down below.
const { MessageEmbed, Message } = require("discord.js");
module.exports = {
name: 'kick',
description: 'Kicks a member',
userPermissions: ["KICK_MEMBERS"],
options: [
{
name: "member",
description: "The member you wish to kick",
type: "USER",
required: true
},
{
name: "reason",
description: "Reason for kicking",
type: "STRING",
required: false
},
],
/**
* #param {Client} client
* #param {CommandInteraction} interaction
* #param {String[]} args
*/
run: async (client, interaction, args) => {
const target = interaction.options.getMember("target");
const reason =
interaction.options.getString("reason") || "No reason(s) provided";
const rolePositionCheck = new MessageEmbed()
.setTitle("You can't kick a person with a higher role than yours!")
.setFooter({ text: "Error: Lower Role Position"})
if (
target.roles.highest.position >=
interaction.member.roles.highest.position
)
return interaction.followUp({
embeds:
[rolePositionCheck],
});
// Message which is sent to the person kicked
const kickMessage = new MessageEmbed()
.setTitle(`You've been kicked from ${interaction.guild.name}`)
.setFooter({ text: `Reason: ${reason}` })
await target.send({ embeds: [kickMessage] });
// The action of kicking, along with the reason
target.kick(reason)
// Message which is sent to the mod who kicked.
const kickAftermath = new MessageEmbed()
.setTitle(`${target.user.tag} has been kicked!`)
.setFooter({ text: `${reason}` })
interaction.followUp({
embeds:
[kickAftermath],
});
},
};
Error
TypeError: Cannot read properties of null (reading 'roles')
at Object.run (C:\Users\admin\Desktop\Tonkotsu\SlashCommands\moderation\kick.js:38:20)
at Client.<anonymous> (C:\Users\admin\Desktop\Tonkotsu\events\interactionCreate.js:27:13)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
Here is the code so far for my discord music bot. I believe the bot has the appropriate permissions, and is able to join the voice channel of the person who called the "!play" command. The issue I am having is that I can't seem to figure out why the audio stream is stuck on the "buffering" state. The docs states that the "buffering" state should either go through or fail, but it appears to be stuck.
client.on("messageCreate", async message => {
if (message.content.slice(0, 6) == "!play ") {
// check input to see if it is a youtube URL
let input = message.content.slice(6);
if (isYoutubeUrl(input)) {
url = input;
} else {
formatInput(input);
url = await searchVideo(searchTerm);
}
if (message.member.voice.channelId !== null) {
const permissions = message.member.voice.channel.permissionsFor(message.client.user);
if (!permissions.has("CONNECT") || !permissions.has("SPEAK")) {
return message.channel.send(
"I need the permissions to join and speak in your voice channel!"
);
}
const connection = joinVoiceChannel({
channelId: message.member.voice.channel.id,
guildId: message.guild.id,
adapterCreator: message.guild.voiceAdapterCreator
})
const stream = await ytdl(url, { filter:'audioonly' });
const player = createAudioPlayer();
var resource = createAudioResource(stream, { seek: 0, volume: 1 });
player.play(resource);
connection.subscribe(player);
} else {
message.reply("You need to be in a voice channel to play music!");
}
}
})
Here is what comes up when I console.log the player itself
<ref *1> AudioPlayer {
_events: [Object: null prototype] {},
_eventsCount: 0,
_maxListeners: undefined,
subscribers: [
PlayerSubscription {
connection: [VoiceConnection],
player: [Circular *1]
}
],
_state: {
status: 'buffering',
resource: AudioResource {
playbackDuration: 0,
started: false,
silenceRemaining: -1,
edges: [Array],
playStream: [OggDemuxer],
metadata: null,
silencePaddingFrames: 5,
audioPlayer: [Circular *1]
},
onReadableCallback: [Function: onReadableCallback],
onFailureCallback: [Function: onFailureCallback],
onStreamError: [Function: onStreamError]
},
behaviors: { noSubscriber: 'pause', maxMissedFrames: 5 },
debug: [Function (anonymous)],
[Symbol(kCapture)]: false
}
Turns out that the stream was not the issue. I just needed to use the "getVoiceConnection" component from the "#discordjs/voice" package and broadcast the stream to that connection instead.
I added another field(contacts) to my apollo graphql mutation but when retrieving the field it produces false data. Even if the matching mongodb field has real data or not, graphql returns mutliple fields with null values.
I've already tried removing __typename in the apollo client graphql options but it doesn't help. Current stack is:
reactjs 16.8.5
react-apollo 2.5.2
mongodb 3.6.11
mongoose 5.3.6
apollo-server 2.3.1
I don't understand why it does this since I have another subdocument that is almost identical but returns correctly.
// CLIENTSIDE
// APOLLO SETUP
const cache = new InMemoryCache({
dataIdFromObject: object => object.key || null
})
const AuthLink = (operation, forward) => {
const token = cookies._uid
operation.setContext(context => ({
...context,
headers: {
...context.headers,
authorization: token
}
}))
return forward(operation)
}
const httpLink = new HttpLink({
uri:"/graphql",
credentials: "include"
})
// mutation
export const LOGIN_MUTATION = gql`
mutation loginMutation($email: String!, $password: String!) {
login(input: {email: $email, password: $password}) {
token
user {
_id
contacts { // This is the subfield in question
_id
username
}
subscriptions { // This subfield returns corretly
_id
title
levels {
_id
}
}
}
error {
path
message
}
}
}
`
// SERVERSIDE
// APOLLO SETUP
const baseSchema = `
schema {
query: Query,
mutation: Mutation
}
`
const schema = makeExecutableSchema({
typeDefs: [
userTypeDefs,
],
resolvers: merge(
{},
userResolvers,
)
})
const {ObjectId} = mongoose.Types
ObjectId.prototype.valueOf = function() {
return this.toString()
}
export default new ApolloServer({
introspection: true,
credentials: true,
schema,
context: ({req, res}) => ({
url: req.protocol + "://" + req.get("host"),
req
})
})
// USER MONGOOSE MODEL
export const UserSchema = new mongoose.Schema(
{
contacts: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "User"
}
],
firstName: {
type: String
},
lastName: {
type: String
},
username: {
type: String,
lowercase: true,
unique: true,
required: [true, "can't be blank"],
match: [/^[a-zA-Z0-9]+$/, "is invalid"],
index: true
},
sentRequests: [
{
username: {
type: String,
default: ""
}
}
],
subscriptions: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Course"
}
],
password: {
default: "",
required: [true, "can't be blank"],
type: String
}
},
{timestamps: true}
)
UserSchema.plugin(uniqueValidator, {message: "is already taken."})
export default mongoose.model("User", UserSchema)
// USER GRAPHQL SCHEMA
type User {
_id: ID
contacts: [User]
email: String!
username: String
subscriptions: [Course]
createdAt: String
updatedAt: String
}
type AuthPayload {
token: String
user: User
error: [Error]
}
input LoginInput {
email: String!
password: String!
}
type Mutation {
login(input: LoginInput): AuthPayload
}
// USER RESOLVER
const login = async (parent, args, ctx, info) => {
let email = args.email
let user = await User.findOne({email})
.populate("subscriptions")
.populate("contacts")
.exec()
if (!user) {
arrayOfErrors.push({
path: "email",
message: "invalid email"
})
} else if (user) {
console.log("user: ", user)
return {
user,
error: arrayOfErrors
}
}
Mutation: {
login
}
// CONSOLE LOG CLIENTSIDE
user:
confirmed: true
contacts: Array(3) // returns an array of 3 items?? It's [] in mongodb
0: {_id: null, username: null}
1: {_id: null, username: null}
2: {_id: null, username: null}
length: 3
__proto__: Array(0)
subscriptions: Array(1)
0: {_id: "5cd36fc1c8d1e222b99d9c58", title: "Korean Class 101 Study",
length: 1
__proto__: Object
__proto__: Object
// CONSOLE LOG SERVERSIDE
POST /graphql 200 64.359 ms - -
user: {
contacts: [ ],
subscriptions:
[ { _id: 5cd6f7f8212af32c75555d4b,
subscribers: 2,
owner: 5cd36edec8d1e222b99d9c57,
createdAt: 2019-05-09T00:09:37.845Z,
updatedAt: 2019-05-11T16:36:14.661Z,
__v: 23 } ],
password: '$2b$10$bkjiazklcoqlkJSJSAioxoAqkoajsdjnqjkiaallaadfadfp7zS',
_id: 5cd36edec8d1e222b99d9c57,
email: 'example#test.com',
username: 'example',
createdAt: 2019-05-09T00:05:50.314Z,
updatedAt: 2019-05-29T17:23:21.545Z,
__v: 32
}
I expected an empty array to return [ ], instead graphql returns an array of 3 items with null values. Even if I add real contacts into the database it still returns the 3 items with null values.
The subscriptions are returning correctly yet it is almost identical to the contacts field with the exception of being a type "Course" in the mongoose model instead of type "User".
I doubt anyone will ever come across this type of error, but here's the solution in case you do. During development I had placed this code in my resolver for testing purposes. Removing it solved the problem.
// USER RESOLVER
...
Query: {...},
/* code to remove
User: {
contacts: user => {
return ["Mo", "Larry", "Curly"]
}
}
*/
Mutation: {...}
A very trivial thing but having not been in this actual code for several months made it difficult to spot. I never thought the 3 stooges would ever give me so much headache.