2021-04-08 22:56:40 +03:00
|
|
|
import { TelegramClient } from '../../client'
|
|
|
|
import { InputPeerLike, Message, MtCuteTypeAssertionError } from '../../types'
|
|
|
|
import { tl } from '@mtcute/tl'
|
|
|
|
import {
|
|
|
|
createUsersChatsIndex,
|
|
|
|
normalizeToInputPeer,
|
|
|
|
} from '../../utils/peer-utils'
|
|
|
|
import { SearchFilters } from '../../types'
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Search for messages inside a specific chat
|
|
|
|
*
|
|
|
|
* @param chatId Chat's marked ID, its username, phone or `"me"` or `"self"`.
|
|
|
|
* @param params Additional search parameters
|
|
|
|
* @internal
|
|
|
|
*/
|
|
|
|
export async function* searchMessages(
|
|
|
|
this: TelegramClient,
|
|
|
|
chatId: InputPeerLike,
|
|
|
|
params?: {
|
|
|
|
/**
|
|
|
|
* Text query string. Required for text-only messages,
|
|
|
|
* optional for media.
|
|
|
|
*
|
|
|
|
* Defaults to `""` (empty string)
|
|
|
|
*/
|
|
|
|
query?: string
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sequential number of the first message to be returned.
|
|
|
|
*
|
|
|
|
* Defaults to `0`.
|
|
|
|
*/
|
|
|
|
offset?: number
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Limits the number of messages to be retrieved.
|
|
|
|
*
|
|
|
|
* By default, no limit is applied and all messages are returned
|
|
|
|
*/
|
|
|
|
limit?: number
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Filter the results using some filter.
|
|
|
|
* Defaults to {@link SearchFilters.Empty} (i.e. will return all messages)
|
|
|
|
*
|
|
|
|
* @link SearchFilters
|
|
|
|
*/
|
|
|
|
filter?: tl.TypeMessagesFilter
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Search for messages sent by a specific user.
|
|
|
|
*
|
|
|
|
* Pass their marked ID, username, phone or `"me"` or `"self"`
|
|
|
|
*/
|
|
|
|
fromUser?: InputPeerLike
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Chunk size, which will be passed as `limit` parameter
|
|
|
|
* for `messages.search`. Usually you shouldn't care about this.
|
|
|
|
*
|
|
|
|
* Defaults to `100`
|
|
|
|
*/
|
|
|
|
chunkSize?: number
|
|
|
|
}
|
|
|
|
): AsyncIterableIterator<Message> {
|
|
|
|
if (!params) params = {}
|
|
|
|
|
|
|
|
let current = 0
|
|
|
|
let offset = params.offset || 0
|
|
|
|
|
|
|
|
const total = params.limit || Infinity
|
|
|
|
const limit = Math.min(params.chunkSize || 100, total)
|
|
|
|
|
|
|
|
const peer = normalizeToInputPeer(await this.resolvePeer(chatId))
|
|
|
|
const fromUser =
|
|
|
|
(params.fromUser
|
|
|
|
? normalizeToInputPeer(await this.resolvePeer(params.fromUser))
|
|
|
|
: null) || undefined
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
const res = await this.call({
|
|
|
|
_: 'messages.search',
|
|
|
|
peer,
|
|
|
|
q: params.query || '',
|
|
|
|
filter: params.filter || SearchFilters.Empty,
|
|
|
|
minDate: 0,
|
|
|
|
maxDate: 0,
|
|
|
|
offsetId: 0,
|
|
|
|
addOffset: offset,
|
2021-04-09 13:08:32 +03:00
|
|
|
limit: Math.min(limit, total - current),
|
2021-04-08 22:56:40 +03:00
|
|
|
minId: 0,
|
|
|
|
maxId: 0,
|
|
|
|
fromId: fromUser,
|
|
|
|
hash: 0,
|
|
|
|
})
|
|
|
|
|
|
|
|
if (res._ === 'messages.messagesNotModified')
|
|
|
|
throw new MtCuteTypeAssertionError(
|
|
|
|
'searchMessages',
|
|
|
|
'!messages.messagesNotModified',
|
|
|
|
res._
|
|
|
|
)
|
|
|
|
|
|
|
|
const { users, chats } = createUsersChatsIndex(res)
|
|
|
|
|
|
|
|
const msgs = res.messages.map(
|
|
|
|
(msg) => new Message(this, msg, users, chats)
|
|
|
|
)
|
|
|
|
|
|
|
|
if (!msgs.length) break
|
|
|
|
|
|
|
|
offset += msgs.length
|
|
|
|
yield* msgs
|
|
|
|
|
|
|
|
current += msgs.length
|
|
|
|
if (current >= total) break
|
|
|
|
}
|
|
|
|
}
|