feat(client): searchMessages method
also added an object for search filters
This commit is contained in:
parent
451fdd0cfc
commit
3a2537cd1a
4 changed files with 228 additions and 0 deletions
|
@ -24,6 +24,7 @@ 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 { iterHistory } from './methods/messages/iter-history'
|
||||||
import { _parseEntities } from './methods/messages/parse-entities'
|
import { _parseEntities } from './methods/messages/parse-entities'
|
||||||
|
import { searchMessages } from './methods/messages/search-messages'
|
||||||
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'
|
||||||
import {
|
import {
|
||||||
|
@ -590,6 +591,63 @@ export class TelegramClient extends BaseTelegramClient {
|
||||||
): Promise<[string, tl.TypeMessageEntity[] | undefined]> {
|
): Promise<[string, tl.TypeMessageEntity[] | undefined]> {
|
||||||
return _parseEntities.apply(this, arguments)
|
return _parseEntities.apply(this, arguments)
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
searchMessages(
|
||||||
|
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> {
|
||||||
|
return searchMessages.apply(this, arguments)
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Send a single photo
|
* Send a single photo
|
||||||
*
|
*
|
||||||
|
|
119
packages/client/src/methods/messages/search-messages.ts
Normal file
119
packages/client/src/methods/messages/search-messages.ts
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
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,
|
||||||
|
limit,
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,2 +1,3 @@
|
||||||
export * from './message-entity'
|
export * from './message-entity'
|
||||||
export * from './message'
|
export * from './message'
|
||||||
|
export * from './search-filters'
|
||||||
|
|
50
packages/client/src/types/messages/search-filters.ts
Normal file
50
packages/client/src/types/messages/search-filters.ts
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
import { tl } from '@mtcute/tl'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search filters to be used in {@link TelegramClient.searchMessages}
|
||||||
|
* and {@link TelegramClient.searchGlobal}.
|
||||||
|
*
|
||||||
|
* Note that due to Telegram API limitations, you can't combine filters,
|
||||||
|
* and can only use a limited pre-defined set.
|
||||||
|
*
|
||||||
|
* This object simply exports static TL objects for convenience,
|
||||||
|
* if it does not expose something, simply pass a TL object
|
||||||
|
* directly.
|
||||||
|
*
|
||||||
|
* - `Empty`: Search for all messages (used by default)
|
||||||
|
* - `Photo`: Search for photos
|
||||||
|
* - `Video`: Search for videos
|
||||||
|
* - `PhotoAndVideo`: Search for photos and videos
|
||||||
|
* - `Document`: Search for documents (generic files, not including audio, video, etc.)
|
||||||
|
* - `Url`: Search for messages containing URLs and text links
|
||||||
|
* - `Gif`: Search for messages containing GIFs
|
||||||
|
* - `Voice`: Search for messages containing voice notes
|
||||||
|
* - `Audio`: Search for messages containing audio files
|
||||||
|
* - `ChatPhotoChange`: Search for chat photo changes
|
||||||
|
* - `Call`: Search for calls
|
||||||
|
* - `Round`: Search for round messages (aka video notes)
|
||||||
|
* - `RoundAndVoice`: Search for round messages (aka video notes) and voice notes
|
||||||
|
* - `MyMention`: Search for mentions of yourself
|
||||||
|
* - `Location`: Search for geolocations
|
||||||
|
* - `Contact`: Search for contacts
|
||||||
|
* - `Pinned`: Search for pinned messages
|
||||||
|
*/
|
||||||
|
export const SearchFilters = {
|
||||||
|
Empty: { _: 'inputMessagesFilterEmpty' } as tl.TypeMessagesFilter,
|
||||||
|
Photo: { _: 'inputMessagesFilterPhotos' } as tl.TypeMessagesFilter,
|
||||||
|
Video: { _: 'inputMessagesFilterVideo' } as tl.TypeMessagesFilter,
|
||||||
|
PhotoAndVideo: { _: 'inputMessagesFilterPhotoVideo' } as tl.TypeMessagesFilter,
|
||||||
|
Document: { _: 'inputMessagesFilterDocument' } as tl.TypeMessagesFilter,
|
||||||
|
Url: { _: 'inputMessagesFilterUrl' } as tl.TypeMessagesFilter,
|
||||||
|
Gif: { _: 'inputMessagesFilterGif' } as tl.TypeMessagesFilter,
|
||||||
|
Voice: { _: 'inputMessagesFilterVoice' } as tl.TypeMessagesFilter,
|
||||||
|
Audio: { _: 'inputMessagesFilterMusic' } as tl.TypeMessagesFilter,
|
||||||
|
ChatPhotoChange: { _: 'inputMessagesFilterChatPhotos' } as tl.TypeMessagesFilter,
|
||||||
|
Call: { _: 'inputMessagesFilterPhoneCalls' } as tl.TypeMessagesFilter,
|
||||||
|
Round: { _: 'inputMessagesFilterRoundVideo' } as tl.TypeMessagesFilter,
|
||||||
|
RoundAndVoice: { _: 'inputMessagesFilterRoundVoice' } as tl.TypeMessagesFilter,
|
||||||
|
MyMention: { _: 'inputMessagesFilterMyMentions' } as tl.TypeMessagesFilter,
|
||||||
|
Location: { _: 'inputMessagesFilterGeo' } as tl.TypeMessagesFilter,
|
||||||
|
Contact: { _: 'inputMessagesFilterContacts' } as tl.TypeMessagesFilter,
|
||||||
|
Pinned: { _: 'inputMessagesFilterPinned' } as tl.TypeMessagesFilter,
|
||||||
|
} as const
|
Loading…
Reference in a new issue