【问题标题】:Edit part of a Message Embed (Discord.JS)编辑消息嵌入的一部分 (Discord.JS)
【发布时间】:2021-10-30 09:24:39
【问题描述】:

我有一个包含 10 条嵌入消息的频道(每条消息嵌入 1 条)。每个嵌入都是人们在赛道上的最佳单圈时间排行榜。

每个嵌入的布局是

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 秒

不改变频道中的任何其他嵌入

【问题讨论】:

  • 欢迎来到 Stack Overflow!您似乎在要求某人为您编写一些代码。 Stack Overflow 是一个问答网站,而不是代码编写服务。请see here学习如何写出有效的问题。
  • 我不确定 %100,但我认为必须在编辑时将嵌入替换为全新的嵌入
  • @elitezen 我希望情况并非如此。想知道是否有一种方法可以简单地为每个 .addfields() 分配一个“标签”,因为没有更好的术语,以便能够编辑它们。
  • 您的代码目前是否按预期工作?或者你只是想优化
  • 目前,我只需输入!pb(个人最佳),它会发送一条消息询问曲目名称,等待曲目名称,然后是一系列 3 .awaitMessages() 来收集每个用户和单圈时间,将所有信息存储在变量中,然后 .edit() 是包含所有信息的原始嵌入(显然只是用新的 MessageEmbed 覆盖了整个嵌入) - 它可以工作。尝试优化/快捷方式,因此我不必输入 7 个不同的变量来编辑嵌入(轨道、user1、user2、user3、user1pb、user2pb、user3pb)

标签: javascript discord discord.js embed


【解决方案1】:

您不一定需要创建一个全新的嵌入并将所有信息输入其中。您可以从消息中获取当前嵌入,并编辑您需要编辑的特定字段。这是一个您可以适应您的系统的示例:

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() 添加到集合中。并且由于这些字段已经按照最快圈速排在第一位,因此只会保留给定用户的最快圈速;同一用户的任何更长的单圈时间都将被过滤掉。

请注意,我只是简单地测试了这个编辑,如果有任何逻辑错误或由它引起的进一步问题(或者它是否完全无法工作),请告诉我。

【讨论】:

  • 自己用 eval 试试这个。我已经发送了带有标题和 3 个字段的嵌入,每个字段包含 lapUser、lapTime。然后我使用const chan = client.channels.cache.get('682014685431595027'); const msg = chan.messages.fetch('883361737313751120'); 获取频道和消息我在let currentEmbed = msg.embeds[0]; 收到一个错误,指出“无法读取未定义的属性嵌入”。我也在 v12 上。
  • 确保await(或使用.then().fetch() 的结果,因为它返回Promise。如果您使用的是 v12,那么您需要进行的唯一更改将在此行:return msg.edit({embeds: [currentEmbed]});。您需要在 v12 上将其更改为 return msg.edit(currentEmbed)
  • 如果获取不适合您,您也可以直接参考发送原始嵌入时创建的消息用于测试目的,即message.channel.send(originalEmbed).then(msg => ...)
  • 已经改变了 msg.edit() 函数。我会添加等待。忘记了,我通常这样做。 Ty,很快就会回复。
  • 必须详细说明您的部分代码,因为我用于 lapTime 的格式实际上是分钟:秒,所以您有 currentEmbed.fields.sort((a, b) => Number(a.value.split(" second")[0]) - Number(b.value.split(" second")[0])); 我将其更改为 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])); 对它们进行排序有效的总秒数。除此之外,排序字段非常非常巧妙。只是为了大便和咯咯笑,如何按 .addField(name, data) 名称排序?
猜你喜欢
  • 2020-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-08
  • 2019-11-17
  • 1970-01-01
  • 2020-06-25
  • 2021-08-25
相关资源
最近更新 更多