As I see it, here's how you'll have to do it:
first identify the groupStart message, and then keep looking at the next messages until you reach a new groupStart message.
Luckily JavaScript keeps elements in the order that they're displayed when you use document.getElementsByClassName so you should just be able to set a variable to true when you hit the target, and then back to false when you hit a new person. This is my code:
function block(userid) {
return setInterval(() => {
let deleteMessages = false;
[...document.getElementsByClassName('message-2qnXI6')].forEach(i => {
if(i) {
if(i.className.match('groupStart-23k01U')) {
if(([...i.children].find(i => i.className.match('contents-2mQqc9')).children[0].src || '/1/').split('/').find(i => i.match(/^\d+$/)) === userid) {
i.style.display = 'none'
deleteMessages = true
} else deleteMessages = false
}
else if(deleteMessages) i.style.display = 'none'
}
})
deleteMessages = false
}, 300)
}
The function block sets an interval for 300 seconds to:
First, get all the messages: [...document.getElementsByClassName('message-2qnXI6')]
Then for each message check to see if it's a groupStart element: if(i.className.match('groupStart-23k01U'))
If it is, it'll check to see if it's a message from the blocked user:
if(([...i.children].find(i => i.className.match('contents-2mQqc9')).children[0].src || '/1/').split('/').find(i => i.match(/^\d+$/)) === userid)
If it is, it'll delete that message and set deleteMessages to true:
i.style.display = 'none'
deleteMessages = true
If it isn't, it'll set deleteMessages to false, so that the next messages don't get deleted.
Going back, if the message isn't a groupStart message, it'll check to see if deleteMessages is true (which would be the first message in the group was from a blocked user, and therefore this message is from a blocked user). If it is, it'll delete it.
Everything should be reset with a simple ctrl+r
Just copy and paste this (the minified version of my code):
function block(e){return setInterval(()=>{let t=!1;[...document.getElementsByClassName("message-2qnXI6")].forEach(n=>{n&&(n.className.match("groupStart-23k01U")?([...n.children].find(e=>e.className.match("contents-2mQqc9")).children[0].src||"/1/").split("/").find(e=>e.match(/^\d+$/))===e?(n.style.display="none",t=!0):t=!1:t&&(n.style.display="none"))}),t=!1},300)}
into the console, and then to block someone type block('<userid>') (make sure the user id is a string and not a number), and it should start working. Also, when you do, it should return a number, just type clearInterval(number) to stop it from blocking new messages.
If you're wondering about this line:
if(([...i.children].find(i => i.className.match('contents-2mQqc9')).children[0].src || '/1/').split('/').find(i => i.match(/^\d+$/)) === userid)
There's a few hackey things I did here:
I start by getting an array of all the messages children, then I find the child with the userID in it (i.className.match('contents-2mQqc9')). If I don't I just use a placeholder to avoid errors.
Then I split via /s because the user id is one of the paths. Then I find which part of the path is the user id by checking to see if it's only numbers (i.match(/^\d+$/)). Finally once I've done all that I check to see if it's the same as the userid.
Here's a quick example:
https://cdn.discordapp.com/avatars/847295719724247388/c9af8fff1110025e6aae862492b4aa29.webp?size=256 (this isn't a real link) => ['https:', '', 'cdn.discordapp.com', 'avatars', '847295719724247388', 'c9af8fff1110025e6aae862492b4aa29.webp?size=256'] => '847295719724247388' is made completely of numbers, so: '847295719724247388'
Unfortunately, if you use this on too many messages by the same person in a row discord will really glitch out, so you'll have to watch for that (note this was testing it on 1000+ messages in a row by the same person). It seems like problems start to happen at around 100, but don't become an issue until it's up to 200 - 300, and even then it'll sometimes work if you wait for a second.
Hopefully if this doesn't work for you you'll at least have an idea of what to do.