* Fetches all messages from a channel, up to a maximum count, using `before`-based pagination. * Discord returns messages newest-first; we collect them all then reverse for chronological order.
( botToken: string, channelId: string, maxMessages: number )
| 71 | * Discord returns messages newest-first; we collect them all then reverse for chronological order. |
| 72 | */ |
| 73 | async function fetchChannelMessages( |
| 74 | botToken: string, |
| 75 | channelId: string, |
| 76 | maxMessages: number |
| 77 | ): Promise<{ messages: DiscordMessage[]; lastActivityTs?: string }> { |
| 78 | const allMessages: DiscordMessage[] = [] |
| 79 | let beforeId: string | undefined |
| 80 | let lastActivityTs: string | undefined |
| 81 | |
| 82 | while (allMessages.length < maxMessages) { |
| 83 | const limit = Math.min(MESSAGES_PER_PAGE, maxMessages - allMessages.length) |
| 84 | const params: Record<string, string> = { limit: String(limit) } |
| 85 | if (beforeId) { |
| 86 | params.before = beforeId |
| 87 | } |
| 88 | |
| 89 | const messages = (await discordApiGet( |
| 90 | `/channels/${channelId}/messages`, |
| 91 | botToken, |
| 92 | params |
| 93 | )) as DiscordMessage[] |
| 94 | |
| 95 | if (!messages || messages.length === 0) break |
| 96 | |
| 97 | if (!lastActivityTs && messages.length > 0) { |
| 98 | lastActivityTs = messages[0].timestamp |
| 99 | } |
| 100 | |
| 101 | allMessages.push(...messages) |
| 102 | |
| 103 | // The last message in the batch is the oldest; use its ID for the next page |
| 104 | beforeId = messages[messages.length - 1].id |
| 105 | |
| 106 | // If we got fewer than requested, there are no more messages |
| 107 | if (messages.length < limit) break |
| 108 | } |
| 109 | |
| 110 | return { messages: allMessages.slice(0, maxMessages), lastActivityTs } |
| 111 | } |
| 112 | |
| 113 | /** |
| 114 | * Converts fetched messages into a single document content string. |
no test coverage detected