使用 MessageComponentInteraction 收集器更新 Discord Message Embed 的更快更简洁的方法
Faster and cleaner way to update Discord Message Embed with a MessageComponentInteraction collector
我正在尝试为我的 discord 机器人 (TypeScript) 创建赛马命令。
代码本身工作正常,但我必须更新包含比赛和参与者的嵌入。问题是为了让它正确更新,我必须在每次 collector.on("collect")
触发时设置它的描述。我想问一下有没有更好、更高效、更干净的更新方式。谢谢!
代码:
const bet = interaction.options.get("bet").value;
class Horse {
name: string;
owner: User;
speed: number;
position: Array<string>;
constructor(name: string) {
this.name = name;
this.owner = null;
this.speed = 0;
this.position = [""];
}
}
const horses = [
new Horse(aimless.pick(names, { remove: true })),
new Horse(aimless.pick(names, { remove: true })),
new Horse(aimless.pick(names, { remove: true })),
new Horse(aimless.pick(names, { remove: false })),
];
const hasJoined: Array<Horse["owner"]> = [];
const row = new MessageActionRow();
for (const horse of horses) {
row.addComponents(
new MessageButton()
.setCustomId(horse.name)
.setLabel(horse.name)
.setStyle("SECONDARY")
);
}
const embed = new MessageEmbed()
.setTitle("Place your bets!")
.setDescription(
`**${horses[0].name} - ${
horses[0].owner !== null ? horses[0].owner.username : "Nobody"
}
${horses[0].position}
${horses[1].name} - ${
horses[1].owner !== null ? horses[1].owner.username : "Nobody"
}
${horses[1].position}
${horses[2].name} - ${
horses[2].owner !== null ? horses[2].owner.username : "Nobody"
}
${horses[2].position}
${horses[3].name} - ${
horses[3].owner !== null ? horses[3].owner.username : "Nobody"
}
${horses[3].position}**`
);
await interaction.editReply({
embeds: [embed],
components: [row],
});
const filter = async (i: MessageComponentInteraction) => {
let profile: any;
try {
profile = await profileModel.findOne({ userID: i.user.id });
if (!profile) {
await profileModel.create({
userID: i.user.id,
serverID: i.guild?.id,
username: i.user.username,
bananas: 100,
deposit: 0,
});
profile.save();
}
} catch (e) {
await i.editReply("Something went wrong! :( Please retry.");
} finally {
if (hasJoined.includes(i.user)) {
return false;
}
if (profile.bananas < bet) {
interaction.editReply(`${i.user} you don't have enough bananas!`);
}
return profile.bananas >= bet;
}
};
const collector = interaction.channel.createMessageComponentCollector({
filter,
time: 60000,
});
collector.on("collect", async (int) => {
await int.deferUpdate();
for (const btn of row.components) {
if (btn.customId === (int.component as MessageButton).customId) {
(btn as MessageButton).setDisabled(true).setStyle("SUCCESS");
hasJoined.push(int.user);
horses.find((h) => h.name === btn.customId).owner = int.user;
console.log(horses);
}
}
embed.setDescription(
`**${horses[0].name} - ${
horses[0].owner !== null ? horses[0].owner.username : "Nobody"
}
${horses[0].position}
${horses[1].name} - ${
horses[1].owner !== null ? horses[1].owner.username : "Nobody"
}
${horses[1].position}
${horses[2].name} - ${
horses[2].owner !== null ? horses[2].owner.username : "Nobody"
}
${horses[2].position}
${horses[3].name} - ${
horses[3].owner !== null ? horses[3].owner.username : "Nobody"
}
${horses[3].position}**`
);
await int.editReply({
embeds: [embed],
components: [row],
});
});
},
});`
你可以把它变成一个函数:
const displayHorses = (horses: Array<Horse>) => {
return `**${horses[0].name} - ${
horses[0].owner !== null ? horses[0].owner.username : "Nobody"
}
${horses[0].position}
${horses[1].name} - ${
horses[1].owner !== null ? horses[1].owner.username : "Nobody"
}
${horses[1].position}
${horses[2].name} - ${
horses[2].owner !== null ? horses[2].owner.username : "Nobody"
}
${horses[2].position}
${horses[3].name} - ${
horses[3].owner !== null ? horses[3].owner.username : "Nobody"
}
${horses[3].position}**`;
};
然后每次:
embed.setDescription(displayHorses(horses));
如果你想进一步压缩它,你可以映射马数组。
const displayHorses = (horses: Array<Horse>) => {
return horses.map(
({ name, owner, position }) =>
`**${name}** - ${owner !== null ? owner.username : "Nobody"}
${position}`
);
};
最后,作为提示,如果您使用的是 14+,您甚至可以进一步将其压缩为:
const displayHorses = (horses: Array<Horse>) => {
return horses.map(
({ name, owner, position }) =>
`**${name}** - ${owner?.username ?? "Nobody"}
${position}`
);
};
我正在尝试为我的 discord 机器人 (TypeScript) 创建赛马命令。
代码本身工作正常,但我必须更新包含比赛和参与者的嵌入。问题是为了让它正确更新,我必须在每次 collector.on("collect")
触发时设置它的描述。我想问一下有没有更好、更高效、更干净的更新方式。谢谢!
代码:
const bet = interaction.options.get("bet").value;
class Horse {
name: string;
owner: User;
speed: number;
position: Array<string>;
constructor(name: string) {
this.name = name;
this.owner = null;
this.speed = 0;
this.position = [""];
}
}
const horses = [
new Horse(aimless.pick(names, { remove: true })),
new Horse(aimless.pick(names, { remove: true })),
new Horse(aimless.pick(names, { remove: true })),
new Horse(aimless.pick(names, { remove: false })),
];
const hasJoined: Array<Horse["owner"]> = [];
const row = new MessageActionRow();
for (const horse of horses) {
row.addComponents(
new MessageButton()
.setCustomId(horse.name)
.setLabel(horse.name)
.setStyle("SECONDARY")
);
}
const embed = new MessageEmbed()
.setTitle("Place your bets!")
.setDescription(
`**${horses[0].name} - ${
horses[0].owner !== null ? horses[0].owner.username : "Nobody"
}
${horses[0].position}
${horses[1].name} - ${
horses[1].owner !== null ? horses[1].owner.username : "Nobody"
}
${horses[1].position}
${horses[2].name} - ${
horses[2].owner !== null ? horses[2].owner.username : "Nobody"
}
${horses[2].position}
${horses[3].name} - ${
horses[3].owner !== null ? horses[3].owner.username : "Nobody"
}
${horses[3].position}**`
);
await interaction.editReply({
embeds: [embed],
components: [row],
});
const filter = async (i: MessageComponentInteraction) => {
let profile: any;
try {
profile = await profileModel.findOne({ userID: i.user.id });
if (!profile) {
await profileModel.create({
userID: i.user.id,
serverID: i.guild?.id,
username: i.user.username,
bananas: 100,
deposit: 0,
});
profile.save();
}
} catch (e) {
await i.editReply("Something went wrong! :( Please retry.");
} finally {
if (hasJoined.includes(i.user)) {
return false;
}
if (profile.bananas < bet) {
interaction.editReply(`${i.user} you don't have enough bananas!`);
}
return profile.bananas >= bet;
}
};
const collector = interaction.channel.createMessageComponentCollector({
filter,
time: 60000,
});
collector.on("collect", async (int) => {
await int.deferUpdate();
for (const btn of row.components) {
if (btn.customId === (int.component as MessageButton).customId) {
(btn as MessageButton).setDisabled(true).setStyle("SUCCESS");
hasJoined.push(int.user);
horses.find((h) => h.name === btn.customId).owner = int.user;
console.log(horses);
}
}
embed.setDescription(
`**${horses[0].name} - ${
horses[0].owner !== null ? horses[0].owner.username : "Nobody"
}
${horses[0].position}
${horses[1].name} - ${
horses[1].owner !== null ? horses[1].owner.username : "Nobody"
}
${horses[1].position}
${horses[2].name} - ${
horses[2].owner !== null ? horses[2].owner.username : "Nobody"
}
${horses[2].position}
${horses[3].name} - ${
horses[3].owner !== null ? horses[3].owner.username : "Nobody"
}
${horses[3].position}**`
);
await int.editReply({
embeds: [embed],
components: [row],
});
});
},
});`
你可以把它变成一个函数:
const displayHorses = (horses: Array<Horse>) => {
return `**${horses[0].name} - ${
horses[0].owner !== null ? horses[0].owner.username : "Nobody"
}
${horses[0].position}
${horses[1].name} - ${
horses[1].owner !== null ? horses[1].owner.username : "Nobody"
}
${horses[1].position}
${horses[2].name} - ${
horses[2].owner !== null ? horses[2].owner.username : "Nobody"
}
${horses[2].position}
${horses[3].name} - ${
horses[3].owner !== null ? horses[3].owner.username : "Nobody"
}
${horses[3].position}**`;
};
然后每次:
embed.setDescription(displayHorses(horses));
如果你想进一步压缩它,你可以映射马数组。
const displayHorses = (horses: Array<Horse>) => {
return horses.map(
({ name, owner, position }) =>
`**${name}** - ${owner !== null ? owner.username : "Nobody"}
${position}`
);
};
最后,作为提示,如果您使用的是 14+,您甚至可以进一步将其压缩为:
const displayHorses = (horses: Array<Horse>) => {
return horses.map(
({ name, owner, position }) =>
`**${name}** - ${owner?.username ?? "Nobody"}
${position}`
);
};