fix(client): avoid secondary db calls in resolvePeer
This commit is contained in:
parent
126ed3016d
commit
649f86f3ed
1 changed files with 100 additions and 19 deletions
|
@ -4,6 +4,7 @@ import { InputPeerLike, MtCuteNotFoundError } from '../../types'
|
|||
import { getBasicPeerType, MAX_CHANNEL_ID } from '@mtcute/core'
|
||||
import bigInt from 'big-integer'
|
||||
import { normalizeToInputPeer } from '../../utils/peer-utils'
|
||||
import { assertTypeIs } from '../../utils/type-assertion'
|
||||
|
||||
/**
|
||||
* Get the `InputPeer` of a known peer id.
|
||||
|
@ -27,27 +28,73 @@ export async function resolvePeer(
|
|||
if (typeof peerId === 'string') {
|
||||
if (peerId === 'self' || peerId === 'me') return { _: 'inputPeerSelf' }
|
||||
|
||||
peerId = peerId.replace(/[@+\s]/g, '')
|
||||
peerId = peerId.replace(/[@+\s()]/g, '')
|
||||
if (peerId.match(/^\d+$/)) {
|
||||
// phone number
|
||||
const fromStorage = await this.storage.getPeerByPhone(peerId)
|
||||
if (fromStorage) return fromStorage
|
||||
|
||||
const res = await this.call({
|
||||
_: 'contacts.getContacts',
|
||||
hash: 0,
|
||||
})
|
||||
|
||||
assertTypeIs('contacts.getContacts', res, 'contacts.contacts')
|
||||
|
||||
const found = res.users.find(
|
||||
(it) => (it as tl.RawUser).phone === peerId
|
||||
)
|
||||
if (found && found._ === 'user')
|
||||
return {
|
||||
_: 'inputPeerUser',
|
||||
userId: found.id,
|
||||
accessHash: found.accessHash!,
|
||||
}
|
||||
|
||||
throw new MtCuteNotFoundError(
|
||||
`Could not find a peer by phone ${peerId}`
|
||||
)
|
||||
} else {
|
||||
// username
|
||||
let fromStorage = await this.storage.getPeerByUsername(peerId)
|
||||
const fromStorage = await this.storage.getPeerByUsername(peerId)
|
||||
if (fromStorage) return fromStorage
|
||||
|
||||
await this.call({
|
||||
const res = await this.call({
|
||||
_: 'contacts.resolveUsername',
|
||||
username: peerId,
|
||||
})
|
||||
|
||||
fromStorage = await this.storage.getPeerByUsername(peerId)
|
||||
if (fromStorage) return fromStorage
|
||||
if (res.peer._ === 'peerUser') {
|
||||
const id = res.peer.userId
|
||||
|
||||
const found = res.users.find((it) => it.id === id)
|
||||
if (found && found._ === 'user')
|
||||
return {
|
||||
_: 'inputPeerUser',
|
||||
userId: found.id,
|
||||
accessHash: found.accessHash!,
|
||||
}
|
||||
} else {
|
||||
const id = res.peer._ === 'peerChannel' ? res.peer.channelId : res.peer.chatId
|
||||
|
||||
const found = res.chats.find((it) => it.id === id)
|
||||
if (found)
|
||||
switch (found._) {
|
||||
case 'channel':
|
||||
case 'channelForbidden':
|
||||
return {
|
||||
_: 'inputPeerChannel',
|
||||
channelId: found.id,
|
||||
accessHash: found.accessHash!
|
||||
}
|
||||
case 'chat':
|
||||
case 'chatForbidden':
|
||||
return {
|
||||
_: 'inputPeerChat',
|
||||
chatId: found.id
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new MtCuteNotFoundError(
|
||||
`Could not find a peer by username ${peerId}`
|
||||
|
@ -57,9 +104,10 @@ export async function resolvePeer(
|
|||
|
||||
const peerType = getBasicPeerType(peerId)
|
||||
|
||||
// try fetching by id, with access_hash set to 0
|
||||
switch (peerType) {
|
||||
case 'user':
|
||||
await this.call({
|
||||
case 'user': {
|
||||
const res = await this.call({
|
||||
_: 'users.getUsers',
|
||||
id: [
|
||||
{
|
||||
|
@ -69,15 +117,41 @@ export async function resolvePeer(
|
|||
},
|
||||
],
|
||||
})
|
||||
|
||||
const found = res.find((it) => it.id === peerId)
|
||||
if (found && found._ === 'user')
|
||||
return {
|
||||
_: 'inputPeerUser',
|
||||
userId: found.id,
|
||||
accessHash: found.accessHash!,
|
||||
}
|
||||
|
||||
break
|
||||
case 'chat':
|
||||
await this.call({
|
||||
_: 'messages.getChats',
|
||||
id: [-peerId],
|
||||
})
|
||||
break
|
||||
case 'channel':
|
||||
await this.call({
|
||||
}
|
||||
case 'chat': {
|
||||
// do we really need to make a call?
|
||||
// const id = -peerId
|
||||
// const res = await this.call({
|
||||
// _: 'messages.getChats',
|
||||
// id: [id],
|
||||
// })
|
||||
//
|
||||
// const found = res.chats.find((it) => it.id === id)
|
||||
// if (found && (found._ === 'chat' || found._ === 'chatForbidden'))
|
||||
// return {
|
||||
// _: 'inputPeerChat',
|
||||
// chatId: found.id
|
||||
// }
|
||||
|
||||
return {
|
||||
_: 'inputPeerChat',
|
||||
chatId: -peerId
|
||||
}
|
||||
// break
|
||||
}
|
||||
case 'channel': {
|
||||
const id = MAX_CHANNEL_ID - peerId
|
||||
const res = await this.call({
|
||||
_: 'channels.getChannels',
|
||||
id: [
|
||||
{
|
||||
|
@ -87,11 +161,18 @@ export async function resolvePeer(
|
|||
},
|
||||
],
|
||||
})
|
||||
break
|
||||
|
||||
const found = res.chats.find((it) => it.id === id)
|
||||
if (found && (found._ === 'channel' || found._ === 'channelForbidden'))
|
||||
return {
|
||||
_: 'inputPeerChannel',
|
||||
channelId: found.id,
|
||||
accessHash: found.accessHash!,
|
||||
}
|
||||
|
||||
const fromStorage = await this.storage.getPeerById(peerId)
|
||||
if (fromStorage) return fromStorage
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
throw new MtCuteNotFoundError(`Could not find a peer by ID ${peerId}`)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue