feat(core): try fetching with zero hash in resolvePeer

closes #76
This commit is contained in:
alina 🌸 2024-11-23 19:03:32 +03:00
parent 4682359769
commit efc68b895d
Signed by: teidesu
SSH key fingerprint: SHA256:uNeCpw6aTSU4aIObXLvHfLkDa82HWH9EiOj9AXOIRpI

View file

@ -7,6 +7,7 @@ import type { ITelegramClient } from '../../client.types.js'
import { MtPeerNotFoundError } from '../../types/errors.js' import { MtPeerNotFoundError } from '../../types/errors.js'
import type { InputPeerLike } from '../../types/peers/index.js' import type { InputPeerLike } from '../../types/peers/index.js'
import { extractUsernames, toInputChannel, toInputPeer, toInputUser } from '../../utils/peer-utils.js' import { extractUsernames, toInputChannel, toInputPeer, toInputUser } from '../../utils/peer-utils.js'
import { _getChannelsBatched, _getUsersBatched } from '../chats/batched-queries.js'
export function _normalizePeerId(peerId: InputPeerLike): number | string | tl.TypeInputPeer { export function _normalizePeerId(peerId: InputPeerLike): number | string | tl.TypeInputPeer {
// for convenience we also accept tl and User/Chat objects directly // for convenience we also accept tl and User/Chat objects directly
@ -160,7 +161,30 @@ export async function resolvePeer(
// if it's not the case, we'll get an `PEER_ID_INVALID` error anyways // if it's not the case, we'll get an `PEER_ID_INVALID` error anyways
const [peerType, bareId] = parseMarkedPeerId(peerId) const [peerType, bareId] = parseMarkedPeerId(peerId)
if (!(peerType === 'chat' || client.storage.self.getCached(true)?.isBot)) { if (peerType === 'chat' || client.storage.self.getCached(true)?.isBot) {
// bots can use access_hash=0 in most of the cases
switch (peerType) {
case 'user':
return {
_: 'inputPeerUser',
userId: bareId,
accessHash: Long.ZERO,
}
case 'chat':
return {
_: 'inputPeerChat',
chatId: bareId,
}
case 'channel':
return {
_: 'inputPeerChannel',
channelId: bareId,
accessHash: Long.ZERO,
}
}
}
// users can only use access_hash=0 in some very limited cases, so first try resolving some other way
// we might have a min peer in cache, which we can try to resolve by its username/phone // we might have a min peer in cache, which we can try to resolve by its username/phone
const cached = await client.storage.peers.getCompleteById(peerId, true) const cached = await client.storage.peers.getCompleteById(peerId, true)
@ -187,28 +211,45 @@ export async function resolvePeer(
} }
} }
throw new MtPeerNotFoundError(`Peer ${peerId} is not found in local cache`) // finally let's try resolving by access_hash=0
}
switch (peerType) { switch (peerType) {
case 'user': case 'user': {
const res = await _getUsersBatched(client, {
_: 'inputUser',
userId: bareId,
accessHash: Long.ZERO,
})
if (res != null && res._ === 'user' && res.accessHash != null) {
return { return {
_: 'inputPeerUser', _: 'inputPeerUser',
userId: bareId, userId: bareId,
accessHash: res.accessHash,
}
}
break
}
case 'channel': {
const res = await _getChannelsBatched(client, {
_: 'inputChannel',
channelId: bareId,
accessHash: Long.ZERO, accessHash: Long.ZERO,
} })
case 'chat':
return { if (res != null && res._ === 'channel' && res.accessHash != null) {
_: 'inputPeerChat',
chatId: bareId,
}
case 'channel':
return { return {
_: 'inputPeerChannel', _: 'inputPeerChannel',
channelId: bareId, channelId: bareId,
accessHash: Long.ZERO, accessHash: res.accessHash,
} }
} }
break
}
}
// we couldn't resolve the peer by any means, so throw an error
throw new MtPeerNotFoundError(`Peer ${peerId} is not found in local cache`)
} }
/** /**