Weird string argument behaviour

If the message has ":" in it then the bot takes the last slice of the message after ":". This may be due to how my command is made for example the URL remover code (kind of lazy) but it really shouldn't.
public async messageRun(message: CardinalCommand.Message, args: CardinalCommand.Args) {
await args.repeat('url', { times: 50 }).catch(() => null); // remove urls from the message
const isAfk = await this.container.db.afk.count({
where: {
memberId: message.member.id,
guildId: message.guildId
}
});

if (isAfk !== 0) {
return sendTemporaryMessage(message, {
embeds: [new CardinalEmbedBuilder().setStyle('fail').setDescription('You are already AFK')]
});
}

let afkMessage = (await args.rest('string').catch(() => 'AFK')).slice(0, 250);
return await this.goAfk(message, afkMessage);
}
public async messageRun(message: CardinalCommand.Message, args: CardinalCommand.Args) {
await args.repeat('url', { times: 50 }).catch(() => null); // remove urls from the message
const isAfk = await this.container.db.afk.count({
where: {
memberId: message.member.id,
guildId: message.guildId
}
});

if (isAfk !== 0) {
return sendTemporaryMessage(message, {
embeds: [new CardinalEmbedBuilder().setStyle('fail').setDescription('You are already AFK')]
});
}

let afkMessage = (await args.rest('string').catch(() => 'AFK')).slice(0, 250);
return await this.goAfk(message, afkMessage);
}
No description
No description
No description
Solution:
anyway just use string then do ```ts const urlRegex = /https?://(www.)?[-a-zA-Z0-9@:%.+~#=]{1,256}.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%+.~#?&//=]*)/g; afkMessage.replaceAll(urlRegex, '').replaceAll(/\s{2,}/g, ' ').trim();...
Jump to solution
13 Replies
Favna
Favna5mo ago
(and once again I will say you would have none of these issues if you used slash commands which has superior arg parsing) Why don't you use args.rest('string')? That'll grab all the string content after the command name automatically. For example !afk: taking a dump becomes : taking a dump at which point you can just string slice the : (use startsWith to ensure you only ever slice that and nothing else)
Oreo ™
Oreo ™OP5mo ago
Yeah I have a slash command option for the command too but users prefer using the prefix command. And that's basically what I'm doing right now as well
No description
Oreo ™
Oreo ™OP5mo ago
I'm just confused why it's behaving weird when there is a ":" in the message
Favna
Favna5mo ago
Set a maximum as the second parameter: args.rest('string', { maximum: 250 }) and you don't need to slice it. I don't know what your URL argument is. You haven't shared it yet. That said, have you considered that there is a : in https:// Either way I don't see why you would use a URL arg type when you don't need to get a URL
Oreo ™
Oreo ™OP5mo ago
Yeah I just use it to as a quick and lazy way to remove URLs from the afk message that users provide. But the main problem is if someone run the command >afk word: more words the afk message becomes more words instead of word: more words so I was just wondering what sapphire does for the URL arg and the string argument,
Favna
Favna5mo ago
import { Result } from '@sapphire/result';
import { URL } from 'node:url';
import { Identifiers } from '../errors/Identifiers';

export function resolveHyperlink(parameter: string): Result<URL, Identifiers.ArgumentHyperlinkError> {
const result = Result.from(() => new URL(parameter));
return result.mapErr(() => Identifiers.ArgumentHyperlinkError) as Result<URL, Identifiers.ArgumentHyperlinkError>;
}
import { Result } from '@sapphire/result';
import { URL } from 'node:url';
import { Identifiers } from '../errors/Identifiers';

export function resolveHyperlink(parameter: string): Result<URL, Identifiers.ArgumentHyperlinkError> {
const result = Result.from(() => new URL(parameter));
return result.mapErr(() => Identifiers.ArgumentHyperlinkError) as Result<URL, Identifiers.ArgumentHyperlinkError>;
}
it's very basic
Solution
Favna
Favna5mo ago
anyway just use string then do
const urlRegex = /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/g;

afkMessage.replaceAll(urlRegex, '').replaceAll(/\s{2,}/g, ' ').trim();
const urlRegex = /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/g;

afkMessage.replaceAll(urlRegex, '').replaceAll(/\s{2,}/g, ' ').trim();
Oreo ™
Oreo ™OP5mo ago
I still get the same behaviour
No description
No description
Favna
Favna5mo ago
Hm I'd have to analyze it then ig Can you make a GH issue with a small repro command?
Oreo ™
Oreo ™OP5mo ago
No need, i managed to get it working i just had to tweak the regex a bit for some weird reason but why was the url parsing messing with the final string anyways "word:" matches the url regex? for args.pick('url')
Favna
Favna5mo ago
oh I grabbed the regex from strackoverflow the url arg doesnt use regex, I pasted what it does above. here
Oreo ™
Oreo ™OP5mo ago
okay so that matched "word:"
Favna
Favna5mo ago
Node's URL is V8's URL and that follows, nay, is the spec
Want results from more Discord servers?
Add your server