discord js I need to fetch and delete messages more than discord limit (100) allows - discord.js

let purgingCounter = splitMsg[1];
function purging() {
client.channels.cache.get(channelTarget).messages.fetch({ limit: [1]})
.then(data => {
let messageArr = [...data];
console.log(messageArr[0][1]);
console.log(`Second log ${messageArr[0][1].id}`);
client.channels.cache.get(channelTarget).messages.delete(messageArr[0][1].id);
console.log(`purged`);
purgingCounter-=1;
})
.then(() => {
if (purgingCounter>0) {
purging();
}
});
};
purging();
Once deleted I want to check if user wanted to delete more than set limit and repeat the function (because discord has a limit of 100), but it gets called twice and ends up crashing after deleting one message.

async function purging (counter) {
let data = await client.channels.cache.get(channelTarget).messages.fetch({ limit: [100]})
let messageArr = [...data];
for (let i=0; i<messageArr.length; i++) {
console.log(`Ids purging: ${messageArr[i][1].id}`);
await client.channels.cache.get(channelTarget).messages.delete(messageArr[i][1].id);
counter-=1;
if (counter<=0) {
return;
}
};
//Check if user wanted to delete more than limit, Timeout makes sure it's the last bit of code to execute
setTimeout(() => {
console.log(`calling back ${counter}`);
if (counter>0) {
purging(counter);
} else { return };
}, 1);
}
purging(splitMsg[1]);
basically this is what I wanted, it works, it deletes messages over limit and doesn't delete more than asked.

Related

how can i delete multiples request at the same time using axios and an array of URL

im doing an app and the first code is working deleting a "task" in my API, but in my app each task have a checkbox input, so, i want to delete all the tasks that are checked.
i used this code to delete single task with a button.
const baseURLtasksId = `https://63cf2168e52f5878299ab5e2.mockapi.io/api/users/${userid}/tasks/${taskId}`
axios.delete(baseURLtasksId, { done: true }).then()
}
ArrayUrlById this is an array of all the URL's that are checked
const deleteAll = () => {
let ArrayUrlById = []
ArrayUrlById = isChecked.map((cId) => {
let arrayURL = `https://63cf2168e52f5878299ab5e2.mockapi.io/api/users/${userid}/tasks/${cId}`
return arrayURL
})
console.log(ArrayUrlById); // here i have an array of the URL
// i need to delete now multiples tasks, using an array of URL and sending {done:true} for each one
}
i tried with this code, but not working properly, beacuse never delete all of them, even in the console send all the delete request to the endpoint with a 200 status, but after i refresg the website, is not deleting all of them that are checked
const deleteAll = () => {
let ArrayUrlById = []
console.log('aqui');
ArrayUrlById = isChecked.map((c) => {
let arrayURL = `https://63cf2168e52f5878299ab5e2.mockapi.io/api/users/${userid}/tasks/${c}`
return arrayURL
})
console.log(ArrayUrlById);
const requests = ArrayUrlById.map(url => axios.delete(url));
axios.all(requests)
.then(responses => {
responses.forEach(response => console.log(response.data));
})
.catch(error => {
console.log(error);
})
}
enter image description here

React Native - Not able to add and delete data from array correctly

I am creating an App in which I have two screens -- One is Feed and Bookmark. Each Feed has bookmark icon from which we can add and delete bookmark. If I add bookmark from feed then It will be added to list and if I delete that then list will be updated with existing once but the issue is that sometime data added double at the time of addition and sometimes at time of deletion array did not get the index of selected item and stays there and sometimes my list got disturbed with showing half items.
Code to click bookmark button on feed
const selectBookmark = () => {
item.bookmarked = !item.bookmarked;
setBookMarkSelected(!item.bookmarked);
setBookmarkClicked(true);
setBookmarkLoader(true);
};
Call API each time at updating bookmark
const bookmarkResponse = await addDeleteBookmark(
email,
userId,
item.cardId,
userSelectedChannel,
token,
item.bookmarked,
item.createdAt,
item.cardType,
)
.then(res => {
setBookmarkLoader(false);
if (res !== 'error') {
console.log('not in else');
updatebookMark();
} else {
console.log(' in else');
item.bookmarked = !item.bookmarked;
}
})
.catch(function (error) {
setBookmarkLoader(false);
});
};
**when I get response from API I call updateBookmark function too update local database **
const updatebookMark = () => {
// code to update feed Array locally
let newArray = [...feedArray];
let id = item.cardId;
const index = newArray.findIndex(object => {
return object.cardId === id;
});
if (index !== -1) {
newArray[index].bookmarked = item.bookmarked;
addFeedsToLocalDB(newArray);
}
// code to update bookmark Array locally
let bookmarks = [...bookmarkArray];
// bookmark added then add new bookmark
if (item.bookmarked) {
const index = bookmarkArray.findIndex(object => {
return object.cardId === id;
});
if (index === -1) {
bookmarks.push(item);
addBookMarksTOLocalDB(bookmarks);
}
} else {
// if deletion then delete from bookmark
const indexBookmark = bookmarks.findIndex(object => {
return object.cardId === id;
});
console.log('bookmark card indexBookmark image', indexBookmark);
bookmarks.splice(indexBookmark, 1);
// console.log('bookmarked after splicing image', bookmarks);
addBookMarksTOLocalDB(bookmarks);
// setBookmarksArray(bookmarks);
}
let homeArray = [...homeCards];
const indexHome = newArray.findIndex(object => {
return object.cardId === id;
});
if (indexHome !== -1) {
homeArray[indexHome].bookmarked = item.bookmarked;
addHomeToLocalDB(homeArray);
}
};
but the issue is that this addition and deletion bookmark is causing issue and I am not able to get that.

Timeout reset in React

I have a page with multiple forms on it. Anytime the form is submitted, I increase the value of actionsInARow (that is stored in context). What I want to do is, as soon as this value is >0, start a 2 second timer where we will re-fetch data from the database. But, anytime the user submits another form, I want to reset the timer. Below is the implementation I have so far, implemented on the component at the page level. Is there a better way to do this?
const [timerId, setTimerId] = React.useState(0);
useEffect(() => {
if(actionsInARow === 0) {
return;
}
if(timerId !== 0) {
window.clearTimeout(timerId)
}
let timeoutId
timeoutId = window.setTimeout(() => {
setTimerId(0)
// dispach event in context to reset the count to 0
dispatch({ type: "RESET_COUNT" });
// re-run fetch request here...
}, 2000)
setTimerId(timeoutId);
return () => {
if(timeoutId !== 0) {
window.clearTimeout(timeoutId)
}
}
}, [actionsInARow]);
Well for one thing you don't need the duplicate code to clear the timeout, the cleanup function will handle that for you so remove those 3 lines in the body. You also don't need the state of timerId, unless you're using that somewhere else.
Those changes would look like this
useEffect(() => {
if(actionsInARow === 0) {
return;
}
let timeoutId = window.setTimeout(() => {
// dispach event in context to reset the count to 0
dispatch({ type: "RESET_COUNT" });
// re-run fetch request here...
}, 2000)
return () => {
window.clearTimeout(timeoutId)
}
}, [actionsInARow]);

Is there a way to compile this into a smaller segment of code?

I am writing a discord bot to ping a user at a set interval. And I want to know if there is a way to compile this to not have to copy and paste the entire script to have the same thing happen for other users.
client.on('message', message => {
if(message.content === '&ping zach forever') {
setInterval(() => {
var yourchannel = client.channels.cache.get('704506336339034115');
yourchannel.send('<#UserID>');
}, "5000");
}});
client.on('message', message => {
if(message.content === '&ping maxx forever') {
setInterval(() => {
var yourchannel = client.channels.cache.get('704506336339034115');
yourchannel.send('<#UserID>');
}, "5000");
}});
I have no experience with discord bots in particular, but as general JavaScript advice:
const users = ["zach", "maxx"];
client.on('message', message => {
const splits = message.content.split(' ');
if (splits.length === 3 && splits[0] === '&ping' && splits[2] === 'forever' && users.includes(splits[1])) {
setInterval(() => {
var yourchannel = client.channels.cache.get('704506336339034115');
yourchannel.send('<#UserID>');
}, "5000");
}
});
Simply expand the users array with the required names. You can also modify the array at runtime with .push() and .splice(). If you'd like the bot to trigger even if there is text after the command, check for splits.length >= 3 instead.
PS. As a general rule, using var is frowned upon these days. Use const for values only assigned once, and let otherwise.
Edit:
Here's a bit more fleshed out example, that includes hardcoded user ID's for each name, applies the duration (in seconds), and also includes a &stop command to stop pinging a certain person. (Code is not tested to run correctly, since I don't have a discord bot account, and don't want to make one either)
const users = new Map(Object.entries({
"zach": "UserID1",
"maxx": "UserID2"
}));
const active = new Map();
client.on('message', message => {
const splits = message.content.split(' ');
if (splits.length === 3 && splits[0] === '&ping' && users.has(splits[1])) {
const channel = client.channels.cache.get('704506336339034115');
const message = `<#${users.get(splits[1])}>`;
const time = Number(splits[2]);
if (isNaN(time) && splits[2] !== 'forever') {
// Passed a time that wasn't a number - possibly send back an error message
} else {
const id = setInterval(() => channel.send(message), 5000);
active.set(splits[1], id);
if (!isNaN(time)) setTimeout(() => clearInterval(id), time * 1000);
}
}
if (splits.length === 2 && splits[0] === '&stop') {
const id = active.get(splits[1]);
if (id) {
clearInterval(id);
active.delete(splits[1]);
}
}
});

Show status of `For` loop to user

I have an action which will take quite some time to complete. It will be looping through an array with over 250k entries. With each entry it will be doing some logic. I want to inform the user of the actions progress, which would be:
let progress = (i / array.length) * 100
How can I add this to redux store or components state so that I can communicate the current progress in the UI?
I tried dispatching an action (as you can see below) which updates the stores progress with the current iterator but the reducer only executes when the for loop is created.
export const generateKeyMap = (mapFrom, mapTo) => {
return async (dispatch) => {
await dispatch(startGeneration()); <-- This only runs when I use a setTimeout for the following action.
setTimeout(() => {
dispatch(buildKeyMap(mapFrom, mapTo));
}, 100);
};
};
export const buildKeyMap = (mapFrom, mapTo) => {
return async (dispatch) => {
let keyMap = {};
for (let i = 0; i < mapFrom.length; i++) {
await dispatch(reportProgress(i)); // <-- This does not update in store until for loop is done.
let randomIndex = randomIntFromInterval(0, mapTo.length - 1);
let key = mapFrom[i].toString();
let value = mapTo[randomIndex].toString();
Object.assign(keyMap, { [key]: value });
mapTo.splice(randomIndex, 1);
}
await dispatch(stopGeneration());
return { type: actionTypes.DELIVERKEYMAP, payload: keyMap };
}
};

Resources