Tengo un canal que contiene 10 mensajes incrustados (1 incrustado por mensaje). Cada inserción es una tabla de clasificación de los mejores tiempos de vuelta de las personas, por pista.
El diseño de cada inserción es
const trackName = new MessageEmbed .setTitle(trackName) .addField(user1, lapTime) .addField(user2, lapTime) .addField(user3, lapTime)Supongamos, por ejemplo, que la tercera inserción se parece a esto:
| Nombre de la pista 3
| Juan 37 segundos
| Chris 39 segundos
| Jeff 40 segundos
Más allá de simplemente editar la inserción y enviar toda la información actualizada manualmente, ¿cómo podría actualizar solo una ranura en particular? Por ejemplo, supongamos que Clark llega con una vuelta de 38 segundos, ¿cómo movería a Chris al tercero, eliminaría a Jeff y agregaría a Clark al segundo para que la inserción se vea como tal?
| Nombre de la pista 3
| Juan 37 segundos
| Clark 38 segundos
| Chris 39 segundos
Sin cambiar ninguna otra inserción en el canal
No necesariamente necesita crear una inserción completamente nueva e ingresar toda la información en ella. Puede obtener la inserción actual del mensaje y editar los campos específicos que necesita editar. Aquí hay un ejemplo que podría adaptar para trabajar con su sistema:
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]}); } Probé este método editTrack usando uno de los comandos de evaluación de mis bots:
La inserción original se editó con éxito con la nueva información. Y solo requería el objeto Message que contenía la inserción, el usuario de la nueva vuelta y el tiempo de la nueva vuelta.
Editar basado en el comentario de OP:
Para que la respuesta funcione al editar la pista incrustada con un usuario existente, que tiene un nuevo tiempo de vuelta, se debe realizar una ligera modificación. Antes de eliminar el cuarto campo de la inserción, debe hacer algo como esto:
const names = new Set(); currentEmbed.fields = currentEmbed.fields.filter(field => !names.has(field.name) && names.add(field.name) ); Esto es lo que está haciendo ese código. Primero, creamos un Set . Los conjuntos son estructuras iterables similares a las matrices, pero solo pueden contener valores únicos. Por lo tanto, podemos usar conjuntos para garantizar que no haya repeticiones del nombre de un usuario. A continuación, filtramos los campos; solo permanecerán los campos cuyo usuario no esté ya contenido en los names . Si el nombre de un usuario no está ya en names , se agrega al conjunto a través .add() . Y debido a que los campos ya están ordenados con el tiempo de vuelta más rápido en primer lugar, solo permanecerá la vuelta más rápida de un usuario determinado; se filtrarán los tiempos de vuelta más largos del mismo usuario.
Tenga en cuenta que solo probé esta edición brevemente, avíseme si hay algún error lógico u otros problemas causados por ella (o si no funciona por completo).
Gracias a la útil respuesta de Cannicide , me llevó por el camino correcto.
Para lograr el resultado final de ordenar los tiempos y sobrescribir los tiempos existentes, terminé con la siguiente función. Requiero que todos los tiempos se presenten en el formato: MINUTOS:SEGUNDOS (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); }