From 649f86f3edfc46a3535139d1fa2544e171a8f7a1 Mon Sep 17 00:00:00 2001 From: teidesu Date: Sat, 22 May 2021 18:58:17 +0300 Subject: [PATCH] fix(client): avoid secondary db calls in resolvePeer --- .../client/src/methods/users/resolve-peer.ts | 119 +++++++++++++++--- 1 file changed, 100 insertions(+), 19 deletions(-) diff --git a/packages/client/src/methods/users/resolve-peer.ts b/packages/client/src/methods/users/resolve-peer.ts index 922aa4f3..713e8e4c 100644 --- a/packages/client/src/methods/users/resolve-peer.ts +++ b/packages/client/src/methods/users/resolve-peer.ts @@ -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 fromStorage = await this.storage.getPeerById(peerId) - if (fromStorage) return fromStorage + const found = res.chats.find((it) => it.id === id) + if (found && (found._ === 'channel' || found._ === 'channelForbidden')) + return { + _: 'inputPeerChannel', + channelId: found.id, + accessHash: found.accessHash!, + } + + break + } + } throw new MtCuteNotFoundError(`Could not find a peer by ID ${peerId}`) }