feat(core): added findDialogs method
This commit is contained in:
parent
cc71f41a9a
commit
f7e883fe2c
3 changed files with 141 additions and 1 deletions
|
@ -89,6 +89,7 @@ import { importContacts } from './methods/contacts/import-contacts.js'
|
|||
import { createFolder } from './methods/dialogs/create-folder.js'
|
||||
import { deleteFolder } from './methods/dialogs/delete-folder.js'
|
||||
import { editFolder } from './methods/dialogs/edit-folder.js'
|
||||
import { findDialogs } from './methods/dialogs/find-dialogs.js'
|
||||
import { findFolder } from './methods/dialogs/find-folder.js'
|
||||
import { getFolders } from './methods/dialogs/get-folders.js'
|
||||
import { getPeerDialogs } from './methods/dialogs/get-peer-dialogs.js'
|
||||
|
@ -1039,6 +1040,18 @@ export interface TelegramClient extends ITelegramClient {
|
|||
*/
|
||||
timeout?: number
|
||||
|
||||
/**
|
||||
* Whether to "fire and forget" this request,
|
||||
* in which case the promise will resolve as soon
|
||||
* as the request is sent with an empty response.
|
||||
*
|
||||
* Useful for interacting with bots that don't correctly
|
||||
* answer to callback queries and the request always times out.
|
||||
*
|
||||
* **Note**: any errors will be silently ignored.
|
||||
*/
|
||||
fireAndForget?: boolean
|
||||
|
||||
/**
|
||||
* Whether this is a "play game" button
|
||||
*/
|
||||
|
@ -2156,6 +2169,18 @@ export interface TelegramClient extends ITelegramClient {
|
|||
/** Modification to be applied to this folder */
|
||||
modification: Partial<Omit<tl.RawDialogFilter, 'id' | '_'>>
|
||||
}): Promise<tl.RawDialogFilter>
|
||||
|
||||
/**
|
||||
* Try to find a dialog (dialogs) with a given peer (peers) by their ID, username or phone number.
|
||||
*
|
||||
* This might be an expensive call, as it will potentially iterate over all
|
||||
* dialogs to find the one with the given peer
|
||||
*
|
||||
* **Available**: 👤 users only
|
||||
*
|
||||
* @throws {MtPeerNotFoundError} If a dialog with any of the given peers was not found
|
||||
*/
|
||||
findDialogs(peers: MaybeArray<string | number>): Promise<Dialog[]>
|
||||
/**
|
||||
* Find a folder by its parameter.
|
||||
*
|
||||
|
@ -5242,6 +5267,8 @@ export interface TelegramClient extends ITelegramClient {
|
|||
* while also normalizing and removing
|
||||
* peers that can't be normalized to that type.
|
||||
*
|
||||
* If a peer was not found, it will be skipped.
|
||||
*
|
||||
* Uses async pool internally, with a concurrent limit of 8
|
||||
*
|
||||
* @param peerIds Peer Ids
|
||||
|
@ -5254,11 +5281,13 @@ export interface TelegramClient extends ITelegramClient {
|
|||
/**
|
||||
* Get multiple `InputPeer`s at once.
|
||||
*
|
||||
* If a peer was not found, `null` will be returned instead
|
||||
*
|
||||
* Uses async pool internally, with a concurrent limit of 8
|
||||
*
|
||||
* @param peerIds Peer Ids
|
||||
*/
|
||||
resolvePeerMany(peerIds: InputPeerLike[]): Promise<tl.TypeInputPeer[]>
|
||||
resolvePeerMany(peerIds: InputPeerLike[]): Promise<(tl.TypeInputPeer | null)[]>
|
||||
|
||||
/**
|
||||
* Get the `InputPeer` of a known peer id.
|
||||
|
@ -5692,6 +5721,9 @@ TelegramClient.prototype.deleteFolder = function (...args) {
|
|||
TelegramClient.prototype.editFolder = function (...args) {
|
||||
return editFolder(this._client, ...args)
|
||||
}
|
||||
TelegramClient.prototype.findDialogs = function (...args) {
|
||||
return findDialogs(this._client, ...args)
|
||||
}
|
||||
TelegramClient.prototype.findFolder = function (...args) {
|
||||
return findFolder(this._client, ...args)
|
||||
}
|
||||
|
|
|
@ -81,6 +81,7 @@ export { importContacts } from './methods/contacts/import-contacts.js'
|
|||
export { createFolder } from './methods/dialogs/create-folder.js'
|
||||
export { deleteFolder } from './methods/dialogs/delete-folder.js'
|
||||
export { editFolder } from './methods/dialogs/edit-folder.js'
|
||||
export { findDialogs } from './methods/dialogs/find-dialogs.js'
|
||||
export { findFolder } from './methods/dialogs/find-folder.js'
|
||||
export { getFolders } from './methods/dialogs/get-folders.js'
|
||||
export { getPeerDialogs } from './methods/dialogs/get-peer-dialogs.js'
|
||||
|
|
107
packages/core/src/highlevel/methods/dialogs/find-dialogs.ts
Normal file
107
packages/core/src/highlevel/methods/dialogs/find-dialogs.ts
Normal file
|
@ -0,0 +1,107 @@
|
|||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { MaybeArray } from '../../../types/utils.js'
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { MtPeerNotFoundError } from '../../types/errors.js'
|
||||
import { Dialog } from '../../types/messages/dialog.js'
|
||||
import { resolvePeerMany } from '../users/resolve-peer-many.js'
|
||||
import { getPeerDialogs } from './get-peer-dialogs.js'
|
||||
import { iterDialogs } from './iter-dialogs.js'
|
||||
|
||||
// @available=user
|
||||
/**
|
||||
* Try to find a dialog (dialogs) with a given peer (peers) by their ID, username or phone number.
|
||||
*
|
||||
* This might be an expensive call, as it will potentially iterate over all
|
||||
* dialogs to find the one with the given peer
|
||||
*
|
||||
* @throws {MtPeerNotFoundError} If a dialog with any of the given peers was not found
|
||||
*/
|
||||
export async function findDialogs(client: ITelegramClient, peers: MaybeArray<string | number>): Promise<Dialog[]> {
|
||||
if (!Array.isArray(peers)) peers = [peers]
|
||||
const resolved = await resolvePeerMany(client, peers)
|
||||
|
||||
// now we need to split `peers` into two parts: ids that we could resolve and those we couldn't
|
||||
// those that we couldn't we'll iterate over all dialogs and try to find them by username/id
|
||||
// those that we could we'll use getPeerDialogs
|
||||
|
||||
// id -> idx
|
||||
const notFoundIds = new Map<number, number>()
|
||||
// username -> idx
|
||||
const notFoundUsernames = new Map<string, number>()
|
||||
let notFoundCount = 0
|
||||
|
||||
const foundInputPeers: tl.TypeInputPeer[] = []
|
||||
const foundIdxToOriginalIdx = new Map<number, number>()
|
||||
|
||||
for (let i = 0; i < peers.length; i++) {
|
||||
const input = peers[i]
|
||||
const resolvedPeer = resolved[i]
|
||||
|
||||
if (!resolvedPeer) {
|
||||
if (typeof input === 'number') {
|
||||
notFoundIds.set(input, i)
|
||||
} else {
|
||||
notFoundUsernames.set(input, i)
|
||||
}
|
||||
|
||||
notFoundCount += 1
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
foundInputPeers.push(resolvedPeer)
|
||||
foundIdxToOriginalIdx.set(foundInputPeers.length - 1, i)
|
||||
}
|
||||
|
||||
const dialogs = await getPeerDialogs(client, foundInputPeers)
|
||||
|
||||
if (foundInputPeers.length === peers.length) {
|
||||
return dialogs
|
||||
}
|
||||
|
||||
const ret = new Array<Dialog>(peers.length)
|
||||
|
||||
// populate found dialogs
|
||||
for (const [idx, origIdx] of foundIdxToOriginalIdx) {
|
||||
ret[origIdx] = dialogs[idx]
|
||||
}
|
||||
|
||||
// now we need to iterate over all dialogs and try to find the rest
|
||||
for await (const dialog of iterDialogs(client, {
|
||||
archived: 'keep',
|
||||
})) {
|
||||
const chat = dialog.chat
|
||||
|
||||
const idxById = notFoundIds.get(chat.id)
|
||||
|
||||
if (idxById !== undefined) {
|
||||
ret[idxById] = dialog
|
||||
notFoundIds.delete(chat.id)
|
||||
notFoundCount -= 1
|
||||
}
|
||||
|
||||
if (notFoundCount === 0) break
|
||||
|
||||
if (!chat.username) continue
|
||||
|
||||
const idxByUsername = notFoundUsernames.get(chat.username)
|
||||
|
||||
if (idxByUsername !== undefined) {
|
||||
ret[idxByUsername] = dialog
|
||||
notFoundUsernames.delete(chat.username)
|
||||
notFoundCount -= 1
|
||||
}
|
||||
|
||||
if (notFoundCount === 0) break
|
||||
}
|
||||
|
||||
// if we still have some dialogs that we couldn't find, fail
|
||||
|
||||
if (notFoundCount > 0) {
|
||||
const notFound = [...notFoundIds.keys(), ...notFoundUsernames.keys()]
|
||||
throw new MtPeerNotFoundError(`Could not find dialogs with peers: ${notFound.join(', ')}`)
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
Loading…
Reference in a new issue