2021-04-08 12:19:38 +03:00
|
|
|
import { tl } from '@mtcute/tl'
|
|
|
|
import { TelegramClient } from '../../client'
|
|
|
|
import { InputPeerLike, MtCuteNotFoundError } from '../../types'
|
|
|
|
import { getBasicPeerType, MAX_CHANNEL_ID } from '@mtcute/core'
|
|
|
|
import bigInt from 'big-integer'
|
2021-05-15 20:25:59 +03:00
|
|
|
import { normalizeToInputPeer } from '../../utils/peer-utils'
|
2021-05-22 18:58:17 +03:00
|
|
|
import { assertTypeIs } from '../../utils/type-assertion'
|
2021-04-08 12:19:38 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the `InputPeer` of a known peer id.
|
|
|
|
* Useful when an `InputPeer` is needed.
|
|
|
|
*
|
|
|
|
* @param peerId The peer identifier that you want to extract the `InputPeer` from.
|
|
|
|
* @internal
|
|
|
|
*/
|
|
|
|
export async function resolvePeer(
|
|
|
|
this: TelegramClient,
|
|
|
|
peerId: InputPeerLike
|
2021-05-15 20:25:59 +03:00
|
|
|
): Promise<tl.TypeInputPeer> {
|
2021-04-08 12:19:38 +03:00
|
|
|
// for convenience we also accept tl objects directly
|
2021-05-15 20:25:59 +03:00
|
|
|
if (typeof peerId === 'object') return normalizeToInputPeer(peerId)
|
2021-04-08 12:19:38 +03:00
|
|
|
|
|
|
|
if (typeof peerId === 'number') {
|
|
|
|
const fromStorage = await this.storage.getPeerById(peerId)
|
|
|
|
if (fromStorage) return fromStorage
|
|
|
|
}
|
|
|
|
|
|
|
|
if (typeof peerId === 'string') {
|
|
|
|
if (peerId === 'self' || peerId === 'me') return { _: 'inputPeerSelf' }
|
|
|
|
|
2021-05-22 18:58:17 +03:00
|
|
|
peerId = peerId.replace(/[@+\s()]/g, '')
|
2021-04-08 12:19:38 +03:00
|
|
|
if (peerId.match(/^\d+$/)) {
|
|
|
|
// phone number
|
|
|
|
const fromStorage = await this.storage.getPeerByPhone(peerId)
|
|
|
|
if (fromStorage) return fromStorage
|
|
|
|
|
2021-05-22 18:58:17 +03:00
|
|
|
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!,
|
|
|
|
}
|
|
|
|
|
2021-04-08 12:19:38 +03:00
|
|
|
throw new MtCuteNotFoundError(
|
|
|
|
`Could not find a peer by phone ${peerId}`
|
|
|
|
)
|
|
|
|
} else {
|
|
|
|
// username
|
2021-05-22 18:58:17 +03:00
|
|
|
const fromStorage = await this.storage.getPeerByUsername(peerId)
|
2021-04-08 12:19:38 +03:00
|
|
|
if (fromStorage) return fromStorage
|
|
|
|
|
2021-05-22 18:58:17 +03:00
|
|
|
const res = await this.call({
|
2021-04-08 12:19:38 +03:00
|
|
|
_: 'contacts.resolveUsername',
|
|
|
|
username: peerId,
|
|
|
|
})
|
|
|
|
|
2021-05-22 18:58:17 +03:00
|
|
|
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 {
|
2021-06-06 15:20:41 +03:00
|
|
|
const id =
|
|
|
|
res.peer._ === 'peerChannel'
|
|
|
|
? res.peer.channelId
|
|
|
|
: res.peer.chatId
|
2021-05-22 18:58:17 +03:00
|
|
|
|
|
|
|
const found = res.chats.find((it) => it.id === id)
|
|
|
|
if (found)
|
|
|
|
switch (found._) {
|
|
|
|
case 'channel':
|
|
|
|
case 'channelForbidden':
|
|
|
|
return {
|
|
|
|
_: 'inputPeerChannel',
|
|
|
|
channelId: found.id,
|
2021-06-06 15:20:41 +03:00
|
|
|
accessHash: found.accessHash!,
|
2021-05-22 18:58:17 +03:00
|
|
|
}
|
|
|
|
case 'chat':
|
|
|
|
case 'chatForbidden':
|
|
|
|
return {
|
|
|
|
_: 'inputPeerChat',
|
2021-06-06 15:20:41 +03:00
|
|
|
chatId: found.id,
|
2021-05-22 18:58:17 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-04-08 12:19:38 +03:00
|
|
|
|
|
|
|
throw new MtCuteNotFoundError(
|
|
|
|
`Could not find a peer by username ${peerId}`
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const peerType = getBasicPeerType(peerId)
|
|
|
|
|
2021-05-22 18:58:17 +03:00
|
|
|
// try fetching by id, with access_hash set to 0
|
2021-05-12 17:58:45 +03:00
|
|
|
switch (peerType) {
|
2021-05-22 18:58:17 +03:00
|
|
|
case 'user': {
|
|
|
|
const res = await this.call({
|
2021-05-12 17:58:45 +03:00
|
|
|
_: 'users.getUsers',
|
|
|
|
id: [
|
|
|
|
{
|
|
|
|
_: 'inputUser',
|
|
|
|
userId: peerId,
|
|
|
|
accessHash: bigInt.zero,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
})
|
2021-05-22 18:58:17 +03:00
|
|
|
|
|
|
|
const found = res.find((it) => it.id === peerId)
|
|
|
|
if (found && found._ === 'user')
|
|
|
|
return {
|
|
|
|
_: 'inputPeerUser',
|
|
|
|
userId: found.id,
|
|
|
|
accessHash: found.accessHash!,
|
|
|
|
}
|
|
|
|
|
2021-05-12 17:58:45 +03:00
|
|
|
break
|
2021-05-22 18:58:17 +03:00
|
|
|
}
|
|
|
|
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',
|
2021-06-06 15:20:41 +03:00
|
|
|
chatId: -peerId,
|
2021-05-22 18:58:17 +03:00
|
|
|
}
|
|
|
|
// break
|
|
|
|
}
|
|
|
|
case 'channel': {
|
|
|
|
const id = MAX_CHANNEL_ID - peerId
|
|
|
|
const res = await this.call({
|
2021-05-12 17:58:45 +03:00
|
|
|
_: 'channels.getChannels',
|
|
|
|
id: [
|
|
|
|
{
|
|
|
|
_: 'inputChannel',
|
|
|
|
channelId: MAX_CHANNEL_ID - peerId,
|
|
|
|
accessHash: bigInt.zero,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
})
|
2021-05-22 18:58:17 +03:00
|
|
|
|
|
|
|
const found = res.chats.find((it) => it.id === id)
|
2021-06-06 15:20:41 +03:00
|
|
|
if (
|
|
|
|
found &&
|
|
|
|
(found._ === 'channel' || found._ === 'channelForbidden')
|
|
|
|
)
|
2021-05-22 18:58:17 +03:00
|
|
|
return {
|
|
|
|
_: 'inputPeerChannel',
|
|
|
|
channelId: found.id,
|
|
|
|
accessHash: found.accessHash!,
|
|
|
|
}
|
|
|
|
|
2021-05-12 17:58:45 +03:00
|
|
|
break
|
2021-05-22 18:58:17 +03:00
|
|
|
}
|
2021-04-08 12:19:38 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
throw new MtCuteNotFoundError(`Could not find a peer by ID ${peerId}`)
|
|
|
|
}
|