> ## Documentation Index
> Fetch the complete documentation index at: https://chameleon.voidlogger.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Collectors and files

> Wait for messages or component interactions, and send files from disk or memory.

## Await messages

```ts theme={"theme":{"light":"github-light","dark":"github-dark"}}
const messages = await client.collectors.awaitMessages(channelId, {
  max: 2,
  time: 15_000,
  filter: (message) => !message.author.bot
})
```

The promise resolves with whatever was collected before timeout, not by throwing.

## Await a component click

```ts theme={"theme":{"light":"github-light","dark":"github-dark"}}
const ctx = await client.collectors.awaitComponent(messageId, {
  time: 15_000,
  filter: (ctx) => ctx.customId === 'confirm'
})

if (!ctx) {
  console.log('Timed out')
  return
}

await ctx.reply({ content: 'Confirmed', ephemeral: true })
```

## Send files

You can send files from memory:

```ts theme={"theme":{"light":"github-light","dark":"github-dark"}}
const file = new AttachmentBuilder(
  Buffer.from('Hello from memory'),
  { name: 'hello.txt' }
)

await client.messages.send(channelId, {
  content: 'Memory file',
  files: [file]
})
```

Or from disk:

```ts theme={"theme":{"light":"github-light","dark":"github-dark"}}
const file = new AttachmentBuilder('./report.txt')
```

## Modal uploads

V2 modal upload fields surface submitted files through `ctx.attachments[fieldId]`.

That gives you resolved attachment objects rather than only raw IDs.

## Worth knowing

* `awaitMessages(...)` resolves with the messages collected so far when time runs out
* `awaitComponent(...)` resolves to `null` on timeout, so timeout handling should be explicit
* `AttachmentBuilder` works with both disk paths and in-memory buffers
