feat(core): isPeerAvailable
method
This commit is contained in:
parent
baa8d287c6
commit
c92292249b
4 changed files with 128 additions and 23 deletions
|
@ -264,6 +264,7 @@ import { getMyUsername } from './methods/users/get-my-username.js'
|
|||
import { getProfilePhoto } from './methods/users/get-profile-photo.js'
|
||||
import { getProfilePhotos } from './methods/users/get-profile-photos.js'
|
||||
import { getUsers } from './methods/users/get-users.js'
|
||||
import { isPeerAvailable } from './methods/users/is-peer-available.js'
|
||||
import { iterProfilePhotos } from './methods/users/iter-profile-photos.js'
|
||||
import { resolvePeerMany } from './methods/users/resolve-peer-many.js'
|
||||
import { resolveChannel, resolvePeer, resolveUser } from './methods/users/resolve-peer.js'
|
||||
|
@ -5536,6 +5537,27 @@ export interface TelegramClient extends ITelegramClient {
|
|||
* @param ids Users' identifiers. Can be ID, username, phone number, `"me"`, `"self"` or TL object
|
||||
*/
|
||||
getUsers(ids: MaybeArray<InputPeerLike>): Promise<(User | null)[]>
|
||||
/**
|
||||
* Check whether a given peer ID can be used to actually
|
||||
* interact with the Telegram API.
|
||||
* This method checks the internal peers cache for the given
|
||||
* input peer, and returns `true` if it is available there.
|
||||
*
|
||||
* You can think of this method as a stripped down version of
|
||||
* {@link resolvePeer}, which only returns `true` or `false`.
|
||||
*
|
||||
* > **Note:** This method works offline and never sends any requests.
|
||||
* > This means that when passing a username or phone number, it will
|
||||
* > only return `true` if the user with that username/phone number
|
||||
* > is cached in the storage, and will not try to resolve the peer by calling the API,
|
||||
* > which *may* lead to false negatives.
|
||||
*
|
||||
* **Available**: ✅ both users and bots
|
||||
*
|
||||
* @returns
|
||||
*/
|
||||
isPeerAvailable(
|
||||
peerId: InputPeerLike): Promise<boolean>
|
||||
/**
|
||||
* Iterate over profile photos
|
||||
*
|
||||
|
@ -6529,6 +6551,9 @@ TelegramClient.prototype.getProfilePhotos = function (...args) {
|
|||
TelegramClient.prototype.getUsers = function (...args) {
|
||||
return getUsers(this._client, ...args)
|
||||
}
|
||||
TelegramClient.prototype.isPeerAvailable = function (...args) {
|
||||
return isPeerAvailable(this._client, ...args)
|
||||
}
|
||||
TelegramClient.prototype.iterProfilePhotos = function (...args) {
|
||||
return iterProfilePhotos(this._client, ...args)
|
||||
}
|
||||
|
|
|
@ -263,6 +263,7 @@ export { getMyUsername } from './methods/users/get-my-username.js'
|
|||
export { getProfilePhoto } from './methods/users/get-profile-photo.js'
|
||||
export { getProfilePhotos } from './methods/users/get-profile-photos.js'
|
||||
export { getUsers } from './methods/users/get-users.js'
|
||||
export { isPeerAvailable } from './methods/users/is-peer-available.js'
|
||||
export { iterProfilePhotos } from './methods/users/iter-profile-photos.js'
|
||||
export { resolvePeerMany } from './methods/users/resolve-peer-many.js'
|
||||
export { resolvePeer } from './methods/users/resolve-peer.js'
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
import { parseMarkedPeerId } from '../../../utils/peer-utils.js'
|
||||
import type { ITelegramClient } from '../../client.types'
|
||||
import type { InputPeerLike } from '../../types'
|
||||
|
||||
import { _normalizePeerId } from './resolve-peer.js'
|
||||
|
||||
/**
|
||||
* Check whether a given peer ID can be used to actually
|
||||
* interact with the Telegram API.
|
||||
* This method checks the internal peers cache for the given
|
||||
* input peer, and returns `true` if it is available there.
|
||||
*
|
||||
* You can think of this method as a stripped down version of
|
||||
* {@link resolvePeer}, which only returns `true` or `false`.
|
||||
*
|
||||
* > **Note:** This method works offline and never sends any requests.
|
||||
* > This means that when passing a username or phone number, it will
|
||||
* > only return `true` if the user with that username/phone number
|
||||
* > is cached in the storage, and will not try to resolve the peer by calling the API,
|
||||
* > which *may* lead to false negatives.
|
||||
*
|
||||
* @returns
|
||||
*/
|
||||
export async function isPeerAvailable(
|
||||
client: ITelegramClient,
|
||||
peerId: InputPeerLike,
|
||||
): Promise<boolean> {
|
||||
peerId = _normalizePeerId(peerId)
|
||||
|
||||
if (typeof peerId === 'object') {
|
||||
// InputPeer (actual one, not mtcute.*)
|
||||
return true
|
||||
}
|
||||
|
||||
if (typeof peerId === 'number') {
|
||||
const fromStorage = await client.storage.peers.getById(peerId)
|
||||
if (fromStorage) return true
|
||||
|
||||
// in some cases, the server allows bots to use access_hash=0.
|
||||
const [peerType] = parseMarkedPeerId(peerId)
|
||||
|
||||
if (peerType === 'chat' || client.storage.self.getCached(true)?.isBot) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
if (typeof peerId === 'string') {
|
||||
if (peerId === 'self' || peerId === 'me') {
|
||||
// inputPeerSelf is always available
|
||||
return true
|
||||
}
|
||||
|
||||
peerId = peerId.replace(/[@+\s()]/g, '')
|
||||
|
||||
if (peerId.match(/^\d+$/)) {
|
||||
// phone number
|
||||
const fromStorage = await client.storage.peers.getByPhone(peerId)
|
||||
if (fromStorage) return true
|
||||
} else {
|
||||
// username
|
||||
const fromStorage = await client.storage.peers.getByUsername(peerId)
|
||||
if (fromStorage) return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
|
@ -8,20 +8,8 @@ import { MtPeerNotFoundError } from '../../types/errors.js'
|
|||
import type { InputPeerLike } from '../../types/peers/index.js'
|
||||
import { toInputChannel, toInputPeer, toInputUser } from '../../utils/peer-utils.js'
|
||||
|
||||
// @available=both
|
||||
/**
|
||||
* Get the `InputPeer` of a known peer id.
|
||||
* Useful when an `InputPeer` is needed in Raw API.
|
||||
*
|
||||
* @param peerId The peer identifier that you want to extract the `InputPeer` from.
|
||||
* @param force Whether to force re-fetch the peer from the server (only for usernames and phone numbers)
|
||||
*/
|
||||
export async function resolvePeer(
|
||||
client: ITelegramClient,
|
||||
peerId: InputPeerLike,
|
||||
force = false,
|
||||
): Promise<tl.TypeInputPeer> {
|
||||
// for convenience we also accept tl and User/Chat objects directly
|
||||
export function _normalizePeerId(peerId: InputPeerLike): number | string | tl.TypeInputPeer {
|
||||
// for convenience we also accept tl and User/Chat objects directly
|
||||
if (typeof peerId === 'object') {
|
||||
if (tl.isAnyPeer(peerId)) {
|
||||
peerId = getMarkedPeerId(peerId)
|
||||
|
@ -36,16 +24,36 @@ export async function resolvePeer(
|
|||
if (typeof peerId === 'object') {
|
||||
switch (peerId._) {
|
||||
case 'mtcute.dummyInputPeerMinUser':
|
||||
peerId = peerId.userId
|
||||
break
|
||||
return peerId.userId
|
||||
case 'mtcute.dummyInputPeerMinChannel':
|
||||
peerId = toggleChannelIdMark(peerId.channelId)
|
||||
break
|
||||
return toggleChannelIdMark(peerId.channelId)
|
||||
default:
|
||||
return peerId
|
||||
}
|
||||
}
|
||||
|
||||
return peerId
|
||||
}
|
||||
|
||||
// @available=both
|
||||
/**
|
||||
* Get the `InputPeer` of a known peer id.
|
||||
* Useful when an `InputPeer` is needed in Raw API.
|
||||
*
|
||||
* @param peerId The peer identifier that you want to extract the `InputPeer` from.
|
||||
* @param force Whether to force re-fetch the peer from the server (only for usernames and phone numbers)
|
||||
*/
|
||||
export async function resolvePeer(
|
||||
client: ITelegramClient,
|
||||
peerId: InputPeerLike,
|
||||
force = false,
|
||||
): Promise<tl.TypeInputPeer> {
|
||||
peerId = _normalizePeerId(peerId)
|
||||
if (typeof peerId === 'object') {
|
||||
// InputPeer (actual one, not mtcute.*)
|
||||
return peerId
|
||||
}
|
||||
|
||||
if (typeof peerId === 'number' && !force) {
|
||||
const fromStorage = await client.storage.peers.getById(peerId)
|
||||
if (fromStorage) return fromStorage
|
||||
|
@ -152,7 +160,7 @@ export async function resolvePeer(
|
|||
// if it's not the case, we'll get an `PEER_ID_INVALID` error anyways
|
||||
const [peerType, bareId] = parseMarkedPeerId(peerId)
|
||||
|
||||
if (peerType !== 'chat' && !client.storage.self.getCached(true)?.isBot) {
|
||||
if (!(peerType === 'chat' || client.storage.self.getCached(true)?.isBot)) {
|
||||
throw new MtPeerNotFoundError(`Peer ${peerId} is not found in local cache`)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue