feat(client): iterHistory method
also fixed a few issues with getHistory
This commit is contained in:
parent
4f62b98b5e
commit
451fdd0cfc
3 changed files with 159 additions and 5 deletions
|
@ -22,6 +22,7 @@ import { deleteMessages } from './methods/messages/delete-messages'
|
||||||
import { _findMessageInUpdate } from './methods/messages/find-in-update'
|
import { _findMessageInUpdate } from './methods/messages/find-in-update'
|
||||||
import { getHistory } from './methods/messages/get-history'
|
import { getHistory } from './methods/messages/get-history'
|
||||||
import { getMessages } from './methods/messages/get-messages'
|
import { getMessages } from './methods/messages/get-messages'
|
||||||
|
import { iterHistory } from './methods/messages/iter-history'
|
||||||
import { _parseEntities } from './methods/messages/parse-entities'
|
import { _parseEntities } from './methods/messages/parse-entities'
|
||||||
import { sendPhoto } from './methods/messages/send-photo'
|
import { sendPhoto } from './methods/messages/send-photo'
|
||||||
import { sendText } from './methods/messages/send-text'
|
import { sendText } from './methods/messages/send-text'
|
||||||
|
@ -440,7 +441,7 @@ export class TelegramClient extends BaseTelegramClient {
|
||||||
* Retrieve a chunk of the chat history.
|
* Retrieve a chunk of the chat history.
|
||||||
*
|
*
|
||||||
* You can get up to 100 messages with one call.
|
* You can get up to 100 messages with one call.
|
||||||
* For larger chunks, use {@link TelegramClient.iterHistory}.
|
* For larger chunks, use {@link iterHistory}.
|
||||||
*
|
*
|
||||||
* @param chatId Chat's marked ID, its username, phone or `"me"` or `"self"`.
|
* @param chatId Chat's marked ID, its username, phone or `"me"` or `"self"`.
|
||||||
* @param params Additional fetch parameters
|
* @param params Additional fetch parameters
|
||||||
|
@ -524,6 +525,63 @@ export class TelegramClient extends BaseTelegramClient {
|
||||||
): Promise<MaybeArray<Message>> {
|
): Promise<MaybeArray<Message>> {
|
||||||
return getMessages.apply(this, arguments)
|
return getMessages.apply(this, arguments)
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Iterate through a chat history sequentially.
|
||||||
|
*
|
||||||
|
* This method wraps {@link getHistory} to allow processing large
|
||||||
|
* groups of messages or entire chats.
|
||||||
|
*
|
||||||
|
* @param chatId Chat's marked ID, its username, phone or `"me"` or `"self"`.
|
||||||
|
* @param params Additional fetch parameters
|
||||||
|
*/
|
||||||
|
iterHistory(
|
||||||
|
chatId: InputPeerLike,
|
||||||
|
params?: {
|
||||||
|
/**
|
||||||
|
* Limits the number of messages to be retrieved.
|
||||||
|
*
|
||||||
|
* By default, no limit is applied and all messages
|
||||||
|
* are returned.
|
||||||
|
*/
|
||||||
|
limit?: number
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sequential number of the first message to be returned.
|
||||||
|
* Defaults to 0 (most recent message).
|
||||||
|
*
|
||||||
|
* Negative values are also accepted and are useful
|
||||||
|
* in case you set `offsetId` or `offsetDate`.
|
||||||
|
*/
|
||||||
|
offset?: number
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pass a message identifier as an offset to retrieve
|
||||||
|
* only older messages starting from that message
|
||||||
|
*/
|
||||||
|
offsetId?: number
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pass a date (`Date` or Unix time in ms) as an offset to retrieve
|
||||||
|
* only older messages starting from that date.
|
||||||
|
*/
|
||||||
|
offsetDate?: number | Date
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pass `true` to retrieve messages in reversed order (from older to recent)
|
||||||
|
*/
|
||||||
|
reverse?: boolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chunk size, which will be passed as `limit` parameter
|
||||||
|
* to {@link getHistory}. Usually you shouldn't care about this.
|
||||||
|
*
|
||||||
|
* Defaults to `100`
|
||||||
|
*/
|
||||||
|
chunkSize?: number
|
||||||
|
}
|
||||||
|
): AsyncIterableIterator<Message> {
|
||||||
|
return iterHistory.apply(this, arguments)
|
||||||
|
}
|
||||||
|
|
||||||
protected _parseEntities(
|
protected _parseEntities(
|
||||||
text?: string,
|
text?: string,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { TelegramClient } from '../../client'
|
import { TelegramClient } from '../../client'
|
||||||
import { InputPeerLike, Message, MtCuteTypeAssertionError } from '../../types'
|
import { InputPeerLike, Message, MtCuteArgumentError, MtCuteTypeAssertionError } from '../../types'
|
||||||
import { createUsersChatsIndex, normalizeToInputPeer } from '../../utils/peer-utils'
|
import { createUsersChatsIndex, normalizeToInputPeer } from '../../utils/peer-utils'
|
||||||
import { normalizeDate } from '../../utils/misc-utils'
|
import { normalizeDate } from '../../utils/misc-utils'
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ import { normalizeDate } from '../../utils/misc-utils'
|
||||||
* Retrieve a chunk of the chat history.
|
* Retrieve a chunk of the chat history.
|
||||||
*
|
*
|
||||||
* You can get up to 100 messages with one call.
|
* You can get up to 100 messages with one call.
|
||||||
* For larger chunks, use {@link TelegramClient.iterHistory}.
|
* For larger chunks, use {@link iterHistory}.
|
||||||
*
|
*
|
||||||
* @param chatId Chat's marked ID, its username, phone or `"me"` or `"self"`.
|
* @param chatId Chat's marked ID, its username, phone or `"me"` or `"self"`.
|
||||||
* @param params Additional fetch parameters
|
* @param params Additional fetch parameters
|
||||||
|
@ -53,7 +53,8 @@ export async function getHistory(
|
||||||
): Promise<Message[]> {
|
): Promise<Message[]> {
|
||||||
if (!params) params = {}
|
if (!params) params = {}
|
||||||
|
|
||||||
const offsetId = params.offsetId || (params.reverse ? 1 : 0)
|
const offsetId =
|
||||||
|
params.offsetId ?? (params.reverse && !params.offsetDate ? 1 : 0)
|
||||||
const limit = params.limit || 100
|
const limit = params.limit || 100
|
||||||
|
|
||||||
const peer = normalizeToInputPeer(await this.resolvePeer(chatId))
|
const peer = normalizeToInputPeer(await this.resolvePeer(chatId))
|
||||||
|
@ -81,5 +82,9 @@ export async function getHistory(
|
||||||
|
|
||||||
const { users, chats } = createUsersChatsIndex(res)
|
const { users, chats } = createUsersChatsIndex(res)
|
||||||
|
|
||||||
return res.messages.map((msg) => new Message(this, msg, users, chats))
|
const msgs = res.messages.map((msg) => new Message(this, msg, users, chats))
|
||||||
|
|
||||||
|
if (params.reverse) msgs.reverse()
|
||||||
|
|
||||||
|
return msgs
|
||||||
}
|
}
|
||||||
|
|
91
packages/client/src/methods/messages/iter-history.ts
Normal file
91
packages/client/src/methods/messages/iter-history.ts
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
import { TelegramClient } from '../../client'
|
||||||
|
import { InputPeerLike, Message } from '../../types'
|
||||||
|
import { normalizeToInputPeer } from '../../utils/peer-utils'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Iterate through a chat history sequentially.
|
||||||
|
*
|
||||||
|
* This method wraps {@link getHistory} to allow processing large
|
||||||
|
* groups of messages or entire chats.
|
||||||
|
*
|
||||||
|
* @param chatId Chat's marked ID, its username, phone or `"me"` or `"self"`.
|
||||||
|
* @param params Additional fetch parameters
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
export async function* iterHistory(
|
||||||
|
this: TelegramClient,
|
||||||
|
chatId: InputPeerLike,
|
||||||
|
params?: {
|
||||||
|
/**
|
||||||
|
* Limits the number of messages to be retrieved.
|
||||||
|
*
|
||||||
|
* By default, no limit is applied and all messages
|
||||||
|
* are returned.
|
||||||
|
*/
|
||||||
|
limit?: number
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sequential number of the first message to be returned.
|
||||||
|
* Defaults to 0 (most recent message).
|
||||||
|
*
|
||||||
|
* Negative values are also accepted and are useful
|
||||||
|
* in case you set `offsetId` or `offsetDate`.
|
||||||
|
*/
|
||||||
|
offset?: number
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pass a message identifier as an offset to retrieve
|
||||||
|
* only older messages starting from that message
|
||||||
|
*/
|
||||||
|
offsetId?: number
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pass a date (`Date` or Unix time in ms) as an offset to retrieve
|
||||||
|
* only older messages starting from that date.
|
||||||
|
*/
|
||||||
|
offsetDate?: number | Date
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pass `true` to retrieve messages in reversed order (from older to recent)
|
||||||
|
*/
|
||||||
|
reverse?: boolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chunk size, which will be passed as `limit` parameter
|
||||||
|
* to {@link getHistory}. Usually you shouldn't care about this.
|
||||||
|
*
|
||||||
|
* Defaults to `100`
|
||||||
|
*/
|
||||||
|
chunkSize?: number
|
||||||
|
}
|
||||||
|
): AsyncIterableIterator<Message> {
|
||||||
|
if (!params) params = {}
|
||||||
|
|
||||||
|
let offsetId =
|
||||||
|
params.offsetId ?? (params.reverse && !params.offsetDate ? 1 : 0)
|
||||||
|
let current = 0
|
||||||
|
const total = params.limit || Infinity
|
||||||
|
const limit = Math.min(params.chunkSize || 100, total)
|
||||||
|
|
||||||
|
// resolve peer once and pass an InputPeer afterwards
|
||||||
|
const peer = normalizeToInputPeer(await this.resolvePeer(chatId))
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
const messages = await this.getHistory(peer, {
|
||||||
|
limit: Math.min(limit, total - current),
|
||||||
|
offset: params.offset,
|
||||||
|
offsetId,
|
||||||
|
offsetDate: params.offsetDate,
|
||||||
|
reverse: params.reverse,
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!messages.length) break
|
||||||
|
|
||||||
|
offsetId = messages[messages.length - 1].id + (params.reverse ? 1 : 0)
|
||||||
|
|
||||||
|
yield* messages
|
||||||
|
current += messages.length
|
||||||
|
|
||||||
|
if (current >= total) break
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue