feat(core): searchHashtag/iterHashtag methods
This commit is contained in:
parent
260de0db7f
commit
260e87a5f8
3 changed files with 173 additions and 0 deletions
|
@ -151,6 +151,7 @@ import { pinMessage } from './methods/messages/pin-message.js'
|
|||
import { readHistory } from './methods/messages/read-history.js'
|
||||
import { readReactions } from './methods/messages/read-reactions.js'
|
||||
import { searchGlobal, SearchGlobalOffset } from './methods/messages/search-global.js'
|
||||
import { iterSearchHashtag, searchHashtag, SearchHashtagOffset } from './methods/messages/search-hashtag.js'
|
||||
import { searchMessages, SearchMessagesOffset } from './methods/messages/search-messages.js'
|
||||
import { answerMedia, answerMediaGroup, answerText } from './methods/messages/send-answer.js'
|
||||
import { commentMedia, commentMediaGroup, commentText } from './methods/messages/send-comment.js'
|
||||
|
@ -3687,6 +3688,53 @@ export interface TelegramClient extends ITelegramClient {
|
|||
*/
|
||||
onlyChannels?: boolean
|
||||
}): Promise<ArrayPaginated<Message, SearchGlobalOffset>>
|
||||
|
||||
/**
|
||||
* Perform a global hashtag search, across the entire Telegram
|
||||
*
|
||||
* **Available**: 👤 users only
|
||||
*
|
||||
* @param hashtag Hashtag to search for
|
||||
* @param params Additional parameters
|
||||
*/
|
||||
searchHashtag(
|
||||
hashtag: string,
|
||||
params?: {
|
||||
/** Offset for the search */
|
||||
offset?: SearchHashtagOffset
|
||||
/** Limit the number of results */
|
||||
limit?: number
|
||||
},
|
||||
): Promise<ArrayPaginated<Message, SearchHashtagOffset>>
|
||||
/**
|
||||
* Perform a global hashtag search, across the entire Telegram
|
||||
*
|
||||
* Iterable version of {@link searchHashtag}
|
||||
*
|
||||
* **Available**: ✅ both users and bots
|
||||
*
|
||||
* @param hashtag Hashtag to search for
|
||||
* @param params Additional parameters
|
||||
*/
|
||||
iterSearchHashtag(
|
||||
hashtag: string,
|
||||
params?: Parameters<typeof searchHashtag>[2] & {
|
||||
/**
|
||||
* Limits the number of messages to be retrieved.
|
||||
*
|
||||
* @default `Infinity`, i.e. all messages are returned
|
||||
*/
|
||||
limit?: number
|
||||
|
||||
/**
|
||||
* Chunk size, which will be passed as `limit` parameter
|
||||
* for `messages.search`. Usually you shouldn't care about this.
|
||||
*
|
||||
* @default 100
|
||||
*/
|
||||
chunkSize?: number
|
||||
},
|
||||
): AsyncIterableIterator<Message>
|
||||
/**
|
||||
* Search for messages inside a specific chat
|
||||
*
|
||||
|
@ -5916,6 +5964,12 @@ TelegramClient.prototype.readReactions = function (...args) {
|
|||
TelegramClient.prototype.searchGlobal = function (...args) {
|
||||
return searchGlobal(this._client, ...args)
|
||||
}
|
||||
TelegramClient.prototype.searchHashtag = function (...args) {
|
||||
return searchHashtag(this._client, ...args)
|
||||
}
|
||||
TelegramClient.prototype.iterSearchHashtag = function (...args) {
|
||||
return iterSearchHashtag(this._client, ...args)
|
||||
}
|
||||
TelegramClient.prototype.searchMessages = function (...args) {
|
||||
return searchMessages(this._client, ...args)
|
||||
}
|
||||
|
|
|
@ -153,6 +153,9 @@ export { readHistory } from './methods/messages/read-history.js'
|
|||
export { readReactions } from './methods/messages/read-reactions.js'
|
||||
export type { SearchGlobalOffset } from './methods/messages/search-global.js'
|
||||
export { searchGlobal } from './methods/messages/search-global.js'
|
||||
export type { SearchHashtagOffset } from './methods/messages/search-hashtag.js'
|
||||
export { searchHashtag } from './methods/messages/search-hashtag.js'
|
||||
export { iterSearchHashtag } from './methods/messages/search-hashtag.js'
|
||||
export type { SearchMessagesOffset } from './methods/messages/search-messages.js'
|
||||
export { searchMessages } from './methods/messages/search-messages.js'
|
||||
export { answerText } from './methods/messages/send-answer.js'
|
||||
|
|
116
packages/core/src/highlevel/methods/messages/search-hashtag.ts
Normal file
116
packages/core/src/highlevel/methods/messages/search-hashtag.ts
Normal file
|
@ -0,0 +1,116 @@
|
|||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { assertTypeIsNot } from '../../../utils/type-assertions.js'
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { Message, PeersIndex } from '../../types/index.js'
|
||||
import { ArrayPaginated } from '../../types/utils.js'
|
||||
import { makeArrayPaginated } from '../../utils/misc-utils.js'
|
||||
|
||||
// @exported
|
||||
export interface SearchHashtagOffset {
|
||||
rate: number
|
||||
peer: tl.TypeInputPeer
|
||||
id: number
|
||||
}
|
||||
|
||||
const defaultOffset: SearchHashtagOffset = {
|
||||
rate: 0,
|
||||
peer: { _: 'inputPeerEmpty' },
|
||||
id: 0,
|
||||
}
|
||||
|
||||
// @available=user
|
||||
/**
|
||||
* Perform a global hashtag search, across the entire Telegram
|
||||
*
|
||||
* @param hashtag Hashtag to search for
|
||||
* @param params Additional parameters
|
||||
*/
|
||||
export async function searchHashtag(
|
||||
client: ITelegramClient,
|
||||
hashtag: string,
|
||||
params?: {
|
||||
/** Offset for the search */
|
||||
offset?: SearchHashtagOffset
|
||||
/** Limit the number of results */
|
||||
limit?: number
|
||||
},
|
||||
): Promise<ArrayPaginated<Message, SearchHashtagOffset>> {
|
||||
const { offset: { rate: offsetRate, peer: offsetPeer, id: offsetId } = defaultOffset, limit = 100 } = params ?? {}
|
||||
const res = await client.call({
|
||||
_: 'channels.searchPosts',
|
||||
hashtag,
|
||||
offsetId,
|
||||
offsetRate,
|
||||
offsetPeer,
|
||||
limit,
|
||||
})
|
||||
|
||||
assertTypeIsNot('searchHashtag', res, 'messages.messagesNotModified')
|
||||
|
||||
const peers = PeersIndex.from(res)
|
||||
const msgs = res.messages.filter((msg) => msg._ !== 'messageEmpty').map((msg) => new Message(msg, peers))
|
||||
const last = msgs[msgs.length - 1]
|
||||
|
||||
const next = last ?
|
||||
{
|
||||
rate: (res as tl.messages.RawMessagesSlice).nextRate ?? last.raw.date,
|
||||
peer: last.chat.inputPeer,
|
||||
id: last.id,
|
||||
} :
|
||||
undefined
|
||||
|
||||
return makeArrayPaginated(msgs, (res as tl.messages.RawMessagesSlice).count ?? msgs.length, next)
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a global hashtag search, across the entire Telegram
|
||||
*
|
||||
* Iterable version of {@link searchHashtag}
|
||||
*
|
||||
* @param hashtag Hashtag to search for
|
||||
* @param params Additional parameters
|
||||
*/
|
||||
export async function* iterSearchHashtag(
|
||||
client: ITelegramClient,
|
||||
hashtag: string,
|
||||
params?: Parameters<typeof searchHashtag>[2] & {
|
||||
/**
|
||||
* Limits the number of messages to be retrieved.
|
||||
*
|
||||
* @default `Infinity`, i.e. all messages are returned
|
||||
*/
|
||||
limit?: number
|
||||
|
||||
/**
|
||||
* Chunk size, which will be passed as `limit` parameter
|
||||
* for `messages.search`. Usually you shouldn't care about this.
|
||||
*
|
||||
* @default 100
|
||||
*/
|
||||
chunkSize?: number
|
||||
},
|
||||
): AsyncIterableIterator<Message> {
|
||||
if (!params) params = {}
|
||||
const { limit = Infinity, chunkSize = 100 } = params
|
||||
let { offset } = params
|
||||
let current = 0
|
||||
|
||||
for (;;) {
|
||||
const res = await searchHashtag(client, hashtag, {
|
||||
offset,
|
||||
limit: Math.min(chunkSize, limit - current),
|
||||
})
|
||||
|
||||
if (!res.length) return
|
||||
|
||||
for (const msg of res) {
|
||||
yield msg
|
||||
|
||||
if (++current >= limit) return
|
||||
}
|
||||
|
||||
if (!res.next) return
|
||||
offset = res.next
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue