编辑消息嵌入的一部分 (Discord.JS)
Edit part of a Message Embed (Discord.JS)
我有一个包含 10 条嵌入消息的频道(每条消息嵌入 1 条消息)。每个嵌入都是人们最好的单圈时间排行榜,由 Track 提供。
每个嵌入的布局是
const trackName = new MessageEmbed
.setTitle(trackName)
.addField(user1, lapTime)
.addField(user2, lapTime)
.addField(user3, lapTime)
假设第三个嵌入看起来像这样:
| 曲目 3 名称
|约翰 37 秒
|克里斯 39 秒
|杰夫 40 秒
除了简单地编辑嵌入并手动发送所有更新的信息之外,我如何才能只更新一个特定的广告位?例如,假设 Clark 跑了 38 秒,我如何将 Chris 移到第 3 位,移除 Jeff,并将 Clark 添加到第 2 位,这样嵌入看起来就这样
| 曲目 3 名称
|约翰 37 秒
|克拉克 38 秒
|克里斯 39 秒
不改变频道中的任何其他嵌入
您不一定需要创建一个全新的嵌入并将所有信息输入其中。您可以从消息中获取当前嵌入,并编辑您需要编辑的特定字段。这是一个您可以适应您的系统的示例:
function editTrack(msg, newUser, newTime) {
//Assume `msg` is the message in the channel containing the embed you want to edit
//currentEmbed is now the embed you want to edit
let currentEmbed = msg.embeds[0];
//Add `newUser` and its `newTime` to the embed as a new field, in the last position
currentEmbed.addField(newUser, newTime);
//Sorts the embed's fields by the lap times of each user, from lowest to highest
//This example numerically sorts the fields by the number in their value
//This does most of the work for you; the laps are now in the correct order
currentEmbed.fields.sort((a, b) => Number(a.value.split(" second")[0]) - Number(b.value.split(" second")[0]));
//If you want to display only the top 3, remove the 4th field of the embed (if any)
if (currentEmbed.fields.length == 4) currentEmbed.fields.splice(3, 1);
//Now, we need to edit the message with our updated embed (djs 13.x syntax)
return msg.edit({embeds: [currentEmbed]});
}
我使用我的一个机器人的 eval 命令测试了这个 editTrack
方法:
之前-
之后 -
使用新信息成功编辑原始嵌入。它只需要包含嵌入、新圈的用户和新圈的时间的 Message
对象。
根据 OP 的评论编辑:
为了在编辑轨道嵌入时与现有用户一起工作时的答案,他有一个新的单圈时间,需要进行轻微的修改。在删除嵌入的第 4 个字段之前,您必须执行如下操作:
const names = new Set();
currentEmbed.fields = currentEmbed.fields.filter(field =>
!names.has(field.name) && names.add(field.name)
);
代码的作用如下。首先,我们创建一个 Set
。集合是类似于数组的可迭代结构,但它们只能包含唯一值。因此,我们可以使用集合来确保没有重复的用户名。接下来,我们过滤字段;只有用户未包含在 names
中的字段才会保留。如果用户名不在 names
中,它会通过 .add()
添加到集合中。并且由于这些字段已经按照最快圈速排在第一位进行了排序,因此只会保留给定用户的最快圈速;同一用户的任何更长单圈时间将被过滤掉。
请注意,我只是简单地测试了这个编辑,如果有任何逻辑错误或由它引起的其他问题(或者如果它无法完全工作),请告诉我。
感谢 Cannicide's 有用的回答,它让我走上了正确的道路。
为了达到排序时间和覆盖现有时间的最终结果,我最终实现了以下功能。我要求所有时间都以以下格式提交:MINUTES:SECONDS (0:35 = 35s | 4:24 = 4m24s | 62:08 = 1h2m8s).
function editLb(theMessage, newUser, newTime) {
//get the embed you want to edit
let currentEmbed = theMessage.embeds[0];
//Check all existing fields for the same newUser, if the same newUser
//is found, replace that entire field with the name: "Placeholder"
//and the value: "999:99". This will also remove any existing duplicates.
currentEmbed.fields.forEach(field => {
if (field.name == newUser) {
field.name = `Placeholder`;
field.value = `999:99`;
}
})
//add the newUser and the newTime to a new field
currentEmbed.addField(`${newUser}`, `${newTime}`);
//sort all available fields effectively by seconds, by taking
// (minutes*60) + (seconds)
currentEmbed.fields.sort((a, b) => Number((a.value.split(":")[0])*60 + (a.value.split(":")[1])) - Number((b.value.split(":")[0])*60 + (b.value.split(":")[1])));
//If there are now 4 fields, remove the slowest(last) one.
if (currentEmbed.fields.length == 4) currentEmbed.fields.splice(3, 1);
}
我有一个包含 10 条嵌入消息的频道(每条消息嵌入 1 条消息)。每个嵌入都是人们最好的单圈时间排行榜,由 Track 提供。
每个嵌入的布局是
const trackName = new MessageEmbed
.setTitle(trackName)
.addField(user1, lapTime)
.addField(user2, lapTime)
.addField(user3, lapTime)
假设第三个嵌入看起来像这样:
| 曲目 3 名称
|约翰 37 秒
|克里斯 39 秒
|杰夫 40 秒
除了简单地编辑嵌入并手动发送所有更新的信息之外,我如何才能只更新一个特定的广告位?例如,假设 Clark 跑了 38 秒,我如何将 Chris 移到第 3 位,移除 Jeff,并将 Clark 添加到第 2 位,这样嵌入看起来就这样
| 曲目 3 名称
|约翰 37 秒
|克拉克 38 秒
|克里斯 39 秒
不改变频道中的任何其他嵌入
您不一定需要创建一个全新的嵌入并将所有信息输入其中。您可以从消息中获取当前嵌入,并编辑您需要编辑的特定字段。这是一个您可以适应您的系统的示例:
function editTrack(msg, newUser, newTime) {
//Assume `msg` is the message in the channel containing the embed you want to edit
//currentEmbed is now the embed you want to edit
let currentEmbed = msg.embeds[0];
//Add `newUser` and its `newTime` to the embed as a new field, in the last position
currentEmbed.addField(newUser, newTime);
//Sorts the embed's fields by the lap times of each user, from lowest to highest
//This example numerically sorts the fields by the number in their value
//This does most of the work for you; the laps are now in the correct order
currentEmbed.fields.sort((a, b) => Number(a.value.split(" second")[0]) - Number(b.value.split(" second")[0]));
//If you want to display only the top 3, remove the 4th field of the embed (if any)
if (currentEmbed.fields.length == 4) currentEmbed.fields.splice(3, 1);
//Now, we need to edit the message with our updated embed (djs 13.x syntax)
return msg.edit({embeds: [currentEmbed]});
}
我使用我的一个机器人的 eval 命令测试了这个 editTrack
方法:
之前-
之后 -
使用新信息成功编辑原始嵌入。它只需要包含嵌入、新圈的用户和新圈的时间的 Message
对象。
根据 OP 的评论编辑:
为了在编辑轨道嵌入时与现有用户一起工作时的答案,他有一个新的单圈时间,需要进行轻微的修改。在删除嵌入的第 4 个字段之前,您必须执行如下操作:
const names = new Set();
currentEmbed.fields = currentEmbed.fields.filter(field =>
!names.has(field.name) && names.add(field.name)
);
代码的作用如下。首先,我们创建一个 Set
。集合是类似于数组的可迭代结构,但它们只能包含唯一值。因此,我们可以使用集合来确保没有重复的用户名。接下来,我们过滤字段;只有用户未包含在 names
中的字段才会保留。如果用户名不在 names
中,它会通过 .add()
添加到集合中。并且由于这些字段已经按照最快圈速排在第一位进行了排序,因此只会保留给定用户的最快圈速;同一用户的任何更长单圈时间将被过滤掉。
请注意,我只是简单地测试了这个编辑,如果有任何逻辑错误或由它引起的其他问题(或者如果它无法完全工作),请告诉我。
感谢 Cannicide's 有用的回答,它让我走上了正确的道路。
为了达到排序时间和覆盖现有时间的最终结果,我最终实现了以下功能。我要求所有时间都以以下格式提交:MINUTES:SECONDS (0:35 = 35s | 4:24 = 4m24s | 62:08 = 1h2m8s).
function editLb(theMessage, newUser, newTime) {
//get the embed you want to edit
let currentEmbed = theMessage.embeds[0];
//Check all existing fields for the same newUser, if the same newUser
//is found, replace that entire field with the name: "Placeholder"
//and the value: "999:99". This will also remove any existing duplicates.
currentEmbed.fields.forEach(field => {
if (field.name == newUser) {
field.name = `Placeholder`;
field.value = `999:99`;
}
})
//add the newUser and the newTime to a new field
currentEmbed.addField(`${newUser}`, `${newTime}`);
//sort all available fields effectively by seconds, by taking
// (minutes*60) + (seconds)
currentEmbed.fields.sort((a, b) => Number((a.value.split(":")[0])*60 + (a.value.split(":")[1])) - Number((b.value.split(":")[0])*60 + (b.value.split(":")[1])));
//If there are now 4 fields, remove the slowest(last) one.
if (currentEmbed.fields.length == 4) currentEmbed.fields.splice(3, 1);
}