feat(client): resolvePeerMany method
This commit is contained in:
parent
46973c4830
commit
8b3caeb3d0
8 changed files with 147 additions and 30 deletions
|
@ -14,6 +14,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@mtcute/tl": "^0.0.0",
|
"@mtcute/tl": "^0.0.0",
|
||||||
"@mtcute/core": "^0.0.0",
|
"@mtcute/core": "^0.0.0",
|
||||||
"@mtcute/file-id": "^0.0.0"
|
"@mtcute/file-id": "^0.0.0",
|
||||||
|
"eager-async-pool": "^1.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -129,6 +129,7 @@ import { getMe } from './methods/users/get-me'
|
||||||
import { getProfilePhotos } from './methods/users/get-profile-photos'
|
import { getProfilePhotos } from './methods/users/get-profile-photos'
|
||||||
import { getUsers } from './methods/users/get-users'
|
import { getUsers } from './methods/users/get-users'
|
||||||
import { iterProfilePhotos } from './methods/users/iter-profile-photos'
|
import { iterProfilePhotos } from './methods/users/iter-profile-photos'
|
||||||
|
import { resolvePeerMany } from './methods/users/resolve-peer-many'
|
||||||
import { resolvePeer } from './methods/users/resolve-peer'
|
import { resolvePeer } from './methods/users/resolve-peer'
|
||||||
import { setOffline } from './methods/users/set-offline'
|
import { setOffline } from './methods/users/set-offline'
|
||||||
import { setProfilePhoto } from './methods/users/set-profile-photo'
|
import { setProfilePhoto } from './methods/users/set-profile-photo'
|
||||||
|
@ -2646,6 +2647,34 @@ export interface TelegramClient extends BaseTelegramClient {
|
||||||
maxId?: tl.Long
|
maxId?: tl.Long
|
||||||
}
|
}
|
||||||
): AsyncIterableIterator<Photo>
|
): AsyncIterableIterator<Photo>
|
||||||
|
/**
|
||||||
|
* Get multiple `InputPeer`s at once,
|
||||||
|
* while also normalizing and removing
|
||||||
|
* peers that can't be normalized to that type.
|
||||||
|
* Uses `async-eager-pool` internally, with a
|
||||||
|
* limit of 10.
|
||||||
|
*
|
||||||
|
* @param peerIds Peer Ids
|
||||||
|
* @param normalizer Normalization function
|
||||||
|
*/
|
||||||
|
resolvePeerMany<
|
||||||
|
T extends tl.TypeInputPeer | tl.TypeInputUser | tl.TypeInputChannel
|
||||||
|
>(
|
||||||
|
peerIds: InputPeerLike[],
|
||||||
|
normalizer: (
|
||||||
|
obj: tl.TypeInputPeer | tl.TypeInputUser | tl.TypeInputChannel
|
||||||
|
) => T | null
|
||||||
|
): Promise<T[]>
|
||||||
|
/**
|
||||||
|
* Get multiple `InputPeer`s at once.
|
||||||
|
* Uses `async-eager-pool` internally, with a
|
||||||
|
* limit of 10.
|
||||||
|
*
|
||||||
|
* @param peerIds Peer Ids
|
||||||
|
*/
|
||||||
|
resolvePeerMany(
|
||||||
|
peerIds: InputPeerLike[]
|
||||||
|
): Promise<(tl.TypeInputPeer | tl.TypeInputUser | tl.TypeInputChannel)[]>
|
||||||
/**
|
/**
|
||||||
* Get the `InputPeer` of a known peer id.
|
* Get the `InputPeer` of a known peer id.
|
||||||
* Useful when an `InputPeer` is needed.
|
* Useful when an `InputPeer` is needed.
|
||||||
|
@ -2867,6 +2896,7 @@ export class TelegramClient extends BaseTelegramClient {
|
||||||
getProfilePhotos = getProfilePhotos
|
getProfilePhotos = getProfilePhotos
|
||||||
getUsers = getUsers
|
getUsers = getUsers
|
||||||
iterProfilePhotos = iterProfilePhotos
|
iterProfilePhotos = iterProfilePhotos
|
||||||
|
resolvePeerMany = resolvePeerMany
|
||||||
resolvePeer = resolvePeer
|
resolvePeer = resolvePeer
|
||||||
setOffline = setOffline
|
setOffline = setOffline
|
||||||
setProfilePhoto = setProfilePhoto
|
setProfilePhoto = setProfilePhoto
|
||||||
|
|
|
@ -46,11 +46,10 @@ export async function addChatMembers(
|
||||||
const updates = await this.call({
|
const updates = await this.call({
|
||||||
_: 'channels.inviteToChannel',
|
_: 'channels.inviteToChannel',
|
||||||
channel: normalizeToInputChannel(chat)!,
|
channel: normalizeToInputChannel(chat)!,
|
||||||
users: await Promise.all(
|
users: await this.resolvePeerMany(
|
||||||
(users as InputPeerLike[]).map((u) =>
|
users as InputPeerLike[],
|
||||||
this.resolvePeer(u).then(normalizeToInputUser)
|
normalizeToInputUser
|
||||||
)
|
),
|
||||||
).then((res) => res.filter(Boolean)) as tl.TypeInputUser[],
|
|
||||||
fwdLimit: forwardCount,
|
fwdLimit: forwardCount,
|
||||||
})
|
})
|
||||||
this._handleUpdate(updates)
|
this._handleUpdate(updates)
|
||||||
|
|
|
@ -23,10 +23,10 @@ export async function createGroup(
|
||||||
): Promise<Chat> {
|
): Promise<Chat> {
|
||||||
if (!Array.isArray(users)) users = [users]
|
if (!Array.isArray(users)) users = [users]
|
||||||
|
|
||||||
const peers = (await Promise.all(
|
const peers = await this.resolvePeerMany(
|
||||||
(users as InputPeerLike[])
|
users as InputPeerLike[],
|
||||||
.map(u => this.resolvePeer(u).then(normalizeToInputUser))
|
normalizeToInputUser
|
||||||
)).filter(Boolean) as tl.TypeInputUser[]
|
)
|
||||||
|
|
||||||
const res = await this.call({
|
const res = await this.call({
|
||||||
_: 'messages.createChat',
|
_: 'messages.createChat',
|
||||||
|
|
|
@ -97,11 +97,10 @@ export async function* getChatEventLog(
|
||||||
const chunkSize = Math.min(params.chunkSize ?? 100, total)
|
const chunkSize = Math.min(params.chunkSize ?? 100, total)
|
||||||
|
|
||||||
const admins: tl.TypeInputUser[] | undefined = params.users
|
const admins: tl.TypeInputUser[] | undefined = params.users
|
||||||
? ((await Promise.all(
|
? await this.resolvePeerMany(
|
||||||
params.users
|
params.users,
|
||||||
.map((u) => this.resolvePeer(u).then(normalizeToInputUser))
|
normalizeToInputUser
|
||||||
.filter(Boolean)
|
)
|
||||||
)) as tl.TypeInputUser[])
|
|
||||||
: undefined
|
: undefined
|
||||||
|
|
||||||
let serverFilter:
|
let serverFilter:
|
||||||
|
|
|
@ -40,13 +40,10 @@ export async function deleteContacts(
|
||||||
const single = !Array.isArray(userIds)
|
const single = !Array.isArray(userIds)
|
||||||
if (single) userIds = [userIds as InputPeerLike]
|
if (single) userIds = [userIds as InputPeerLike]
|
||||||
|
|
||||||
const inputPeers = ((
|
const inputPeers = await this.resolvePeerMany(
|
||||||
await Promise.all(
|
userIds as InputPeerLike[],
|
||||||
(userIds as InputPeerLike[]).map((it) =>
|
normalizeToInputUser
|
||||||
this.resolvePeer(it).then(normalizeToInputUser)
|
)
|
||||||
)
|
|
||||||
)
|
|
||||||
).filter(Boolean) as unknown) as tl.TypeInputUser[]
|
|
||||||
|
|
||||||
if (single && !inputPeers.length)
|
if (single && !inputPeers.length)
|
||||||
throw new MtCuteInvalidPeerTypeError(
|
throw new MtCuteInvalidPeerTypeError(
|
||||||
|
|
|
@ -17,7 +17,9 @@ export async function getUsers(
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get information about multiple users.
|
* Get information about multiple users.
|
||||||
* You can retrieve up to 200 users at once
|
* You can retrieve up to 200 users at once.
|
||||||
|
*
|
||||||
|
* Note that order is not guaranteed.
|
||||||
*
|
*
|
||||||
* @param ids Users' identifiers. Can be ID, username, phone number, `"me"`, `"self"` or TL object
|
* @param ids Users' identifiers. Can be ID, username, phone number, `"me"`, `"self"` or TL object
|
||||||
* @internal
|
* @internal
|
||||||
|
@ -35,13 +37,10 @@ export async function getUsers(
|
||||||
const isArray = Array.isArray(ids)
|
const isArray = Array.isArray(ids)
|
||||||
if (!isArray) ids = [ids as InputPeerLike]
|
if (!isArray) ids = [ids as InputPeerLike]
|
||||||
|
|
||||||
const inputPeers = ((
|
const inputPeers = await this.resolvePeerMany(
|
||||||
await Promise.all(
|
ids as InputPeerLike[],
|
||||||
(ids as InputPeerLike[]).map((it) =>
|
normalizeToInputUser
|
||||||
this.resolvePeer(it).then(normalizeToInputUser)
|
)
|
||||||
)
|
|
||||||
)
|
|
||||||
).filter(Boolean) as unknown) as tl.TypeInputUser[]
|
|
||||||
|
|
||||||
let res = await this.call({
|
let res = await this.call({
|
||||||
_: 'users.getUsers',
|
_: 'users.getUsers',
|
||||||
|
|
92
packages/client/src/methods/users/resolve-peer-many.ts
Normal file
92
packages/client/src/methods/users/resolve-peer-many.ts
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
import { tl } from '@mtcute/tl'
|
||||||
|
import { TelegramClient } from '../../client'
|
||||||
|
import { InputPeerLike } from '../../types'
|
||||||
|
import { asyncPool } from 'eager-async-pool'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get multiple `InputPeer`s at once,
|
||||||
|
* while also normalizing and removing
|
||||||
|
* peers that can't be normalized to that type.
|
||||||
|
* Uses `async-eager-pool` internally, with a
|
||||||
|
* limit of 10.
|
||||||
|
*
|
||||||
|
* @param peerIds Peer Ids
|
||||||
|
* @param normalizer Normalization function
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
export async function resolvePeerMany<
|
||||||
|
T extends tl.TypeInputPeer | tl.TypeInputUser | tl.TypeInputChannel
|
||||||
|
>(
|
||||||
|
this: TelegramClient,
|
||||||
|
peerIds: InputPeerLike[],
|
||||||
|
normalizer: (
|
||||||
|
obj: tl.TypeInputPeer | tl.TypeInputUser | tl.TypeInputChannel
|
||||||
|
) => T | null
|
||||||
|
): Promise<T[]>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get multiple `InputPeer`s at once.
|
||||||
|
* Uses `async-eager-pool` internally, with a
|
||||||
|
* limit of 10.
|
||||||
|
*
|
||||||
|
* @param peerIds Peer Ids
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
export async function resolvePeerMany(
|
||||||
|
this: TelegramClient,
|
||||||
|
peerIds: InputPeerLike[]
|
||||||
|
): Promise<(tl.TypeInputPeer | tl.TypeInputUser | tl.TypeInputChannel)[]>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
export async function resolvePeerMany(
|
||||||
|
this: TelegramClient,
|
||||||
|
peerIds: InputPeerLike[],
|
||||||
|
normalizer?: (
|
||||||
|
obj: tl.TypeInputPeer | tl.TypeInputUser | tl.TypeInputChannel
|
||||||
|
) => tl.TypeInputPeer | tl.TypeInputUser | tl.TypeInputChannel | null
|
||||||
|
): Promise<(tl.TypeInputPeer | tl.TypeInputUser | tl.TypeInputChannel)[]> {
|
||||||
|
const ret: (
|
||||||
|
| tl.TypeInputPeer
|
||||||
|
| tl.TypeInputUser
|
||||||
|
| tl.TypeInputChannel
|
||||||
|
)[] = []
|
||||||
|
|
||||||
|
if (peerIds.length < 10) {
|
||||||
|
// no point in using async pool for <10 peers
|
||||||
|
const res = await Promise.all(peerIds.map((it) => this.resolvePeer(it)))
|
||||||
|
|
||||||
|
if (!normalizer) return res
|
||||||
|
|
||||||
|
for (const value of res) {
|
||||||
|
const norm = normalizer(value)
|
||||||
|
if (norm) {
|
||||||
|
ret.push(norm)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for await (const { error, value } of asyncPool(
|
||||||
|
(it) => this.resolvePeer(it),
|
||||||
|
peerIds,
|
||||||
|
{
|
||||||
|
limit: 10,
|
||||||
|
}
|
||||||
|
)) {
|
||||||
|
if (error) {
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
if (!value) continue
|
||||||
|
|
||||||
|
if (!normalizer) {
|
||||||
|
ret.push(value)
|
||||||
|
} else {
|
||||||
|
const norm = normalizer(value)
|
||||||
|
if (norm) {
|
||||||
|
ret.push(norm)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
Loading…
Reference in a new issue