0

I am trying to create a script that fetches messages from an API and then filters out messages that contain an image. The API has different endpoints, each with their own batch of messages. I am simply trying to collect all of them. In this example there is 3 links that's why it logs out "test" three times.

My issue is that the messageGetter() function doesn't fully finish looping before the broadcast() function is called. So right now when I execute the script for the first time it broadcasts an empty array but on the second execution it has the contents I need.

How could I fix this?

module.exports = {
  async execute(app) {
    await fetchImages(app);
    await interaction.reply("Getting Images");
  },
};

async function fetchImages(app) {
  app.link.forEach(async (link) => {
    if (link.type === 0) {
      await messageGetter(link);
    }
  });
  console.log("here");
  broadcast({ type: "imageLinks", data: imageLinks });
  imageLinks.splice(0, imageLinks.length);
}

async function messageGetter(link, limit = 500) {
  const sum_messages = [];
  let last_id;

  while (true) {
    const options = { limit: 100 };
    if (last_id) {
      options.before = last_id;
    }

    const messages = await link.messages.fetch(options);
    sum_messages.push(...messages.values());
    last_id = messages.last().id;

    if (messages.size != 100 || sum_messages >= limit) {
      break;
    }
  }

  sum_messages.forEach((message) => {
    if (message.attachments.size > 0) {
      message.attachments.forEach((attachment) => {
        if (attachment.url.match(/\.(jpeg|jpg|gif|png)$/i)) {
          imageLinks.push(attachment.url);
        }
      });
    }
  });
console.log("test");
}

Log Output:

here
test
test
test
Pazulay
  • 215
  • 1
  • 3
  • 11
  • With `async` and `await`, it's often a better idea to use a plain `for` loop instead of a `.forEach`, because `.forEach` does not know about `async` functions, and it ignores values returned from its callbacks anyway. – Pointy Aug 01 '23 at 13:16

1 Answers1

0

Your problem it's here

app.link.forEach(async (link) => {
   if (link.type === 0) {
     await messageGetter(link);
   }
});

Because forEach won't wait for the execution of the messageGetter() function, you can use a for-of loop that will work as you want. Example:

async function fetchImages(app) {
  for(const link of app.link) {
    if (link.type === 0) {
      await messageGetter(link);
    }
  }
  console.log("here");
  broadcast({ type: "imageLinks", data: imageLinks });
  imageLinks.splice(0, imageLinks.length);
}
GuilhRib
  • 16
  • 2