refactor!: merged client into core + fixed dispatcher for new storage
This commit is contained in:
parent
eca99a7535
commit
c8e026dc03
524 changed files with 6262 additions and 5215 deletions
|
@ -160,7 +160,7 @@ module.exports = {
|
|||
'simple-import-sort/imports': [
|
||||
'error',
|
||||
{
|
||||
groups: [['^[a-z]'], ['^@mtcute'], ['^@/'], ['^~/'], ['^\\.']],
|
||||
groups: [['^[a-z]'], ['^@?mtcute'], ['^@/'], ['^~/'], ['^\\.']],
|
||||
},
|
||||
],
|
||||
'simple-import-sort/exports': 'error',
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "mtcute",
|
||||
"name": "mtcute-workspace",
|
||||
"private": true,
|
||||
"version": "0.6.0",
|
||||
"description": "Type-safe library for MTProto (Telegram API) for browser and NodeJS",
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
# @mtcute/client
|
||||
|
||||
📖 [API Reference](https://ref.mtcute.dev/modules/_mtcute_client.html)
|
||||
|
||||
High-level Telegram client implementation over the `@mtcute/core` base library.
|
||||
|
||||
## Features
|
||||
- **Updates handling**: Implements proper updates handling, including ordering and gap recovery ([learn more](https://core.telegram.org/api/updates))
|
||||
- **Wrapper classes**: Easy-to-use classes that wrap the complex TL objects and provide a clean interface
|
||||
- **High-level methods**: Methods that wrap the low-level API calls and provide a clean interface
|
||||
- **Tree-shaking**: Only import the methods you need, and the rest will not be included into the bundle
|
||||
- **Web support**: Works in the browser with no additional configuration
|
||||
|
||||
## Usage
|
||||
|
||||
```ts
|
||||
import { TelegramClient } from '@mtcute/client'
|
||||
|
||||
const tg = new TelegramClient({
|
||||
apiId: 12345,
|
||||
apiHash: '0123456789abcdef0123456789abcdef',
|
||||
// ... + supports all options from @mtcute/core ...
|
||||
})
|
||||
|
||||
tg.start({
|
||||
phone: '+1234567890',
|
||||
password: () => prompt('Enter password'),
|
||||
code: () => prompt('Enter code'),
|
||||
}, (user) => {
|
||||
console.log(`Logged in as ${user.displayName}`)
|
||||
})
|
||||
```
|
||||
|
||||
> **Note**: for web, prefer BaseTelegramClient over TelegramClient,
|
||||
> as it is tree-shakeable – [learn more](https://mtcute.dev/guide/topics/treeshaking.html)
|
|
@ -1,3 +0,0 @@
|
|||
module.exports = {
|
||||
esmOnlyDirectives: true,
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
{
|
||||
"name": "@mtcute/client",
|
||||
"private": true,
|
||||
"version": "0.6.0",
|
||||
"description": "High-level API over @mtcute/core",
|
||||
"author": "Alina Sireneva <alina@tei.su>",
|
||||
"license": "MIT",
|
||||
"main": "src/index.ts",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "pnpm run -w build-package client",
|
||||
"gen-client": "node ./scripts/generate-client.cjs",
|
||||
"gen-updates": "node ./scripts/generate-updates.cjs"
|
||||
},
|
||||
"distOnlyFields": {
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./esm/index.js",
|
||||
"require": "./cjs/index.js"
|
||||
},
|
||||
"./methods/*": {
|
||||
"import": "./esm/methods/*",
|
||||
"require": "./cjs/methods/*"
|
||||
},
|
||||
"./utils.js": {
|
||||
"import": "./esm/utils/index.js",
|
||||
"require": "./cjs/utils/index.js"
|
||||
}
|
||||
}
|
||||
},
|
||||
"browser": {
|
||||
"./src/methods/files/_platform.js": "./src/methods/files/_platform.web.js",
|
||||
"./src/methods/files/download-file.js": "./src/methods/files/download-file.web.js",
|
||||
"./src/utils/platform/storage.js": "./src/utils/platform/storage.web.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@mtcute/core": "workspace:^",
|
||||
"@mtcute/file-id": "workspace:^"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@mtcute/test": "workspace:^"
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
export * from './client.js'
|
||||
export * from './types/index.js'
|
||||
export * from './utils/peer-utils.js'
|
||||
export { createDummyUpdate } from './utils/updates-utils.js'
|
||||
export * from '@mtcute/core'
|
|
@ -1,111 +0,0 @@
|
|||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
|
||||
import { BaseTelegramClientOptions, IMtStorageProvider } from '@mtcute/core'
|
||||
// @copy
|
||||
import { MemoryStorage } from '@mtcute/core/src/storage/providers/memory/index.js'
|
||||
|
||||
import { TelegramClient } from '../client.js'
|
||||
// @copy
|
||||
import { Conversation } from '../types/conversation.js'
|
||||
// @copy
|
||||
import { _defaultStorageFactory } from '../utils/platform/storage.js'
|
||||
// @copy
|
||||
import {
|
||||
enableUpdatesProcessing,
|
||||
makeParsedUpdateHandler,
|
||||
ParsedUpdateHandlerParams,
|
||||
UpdatesManagerParams,
|
||||
} from './updates/index.js'
|
||||
|
||||
// @extension
|
||||
interface TelegramClientExt {
|
||||
_disableUpdatesManager: boolean
|
||||
}
|
||||
|
||||
// @copy
|
||||
interface TelegramClientOptions extends Omit<BaseTelegramClientOptions, 'storage'> {
|
||||
/**
|
||||
* Storage to use for this client.
|
||||
*
|
||||
* If a string is passed, it will be used as:
|
||||
* - a path to a JSON file for Node.js
|
||||
* - IndexedDB database name for browsers
|
||||
*
|
||||
* If omitted, {@link MemoryStorage} is used
|
||||
*/
|
||||
storage?: string | IMtStorageProvider
|
||||
|
||||
/**
|
||||
* Parameters for updates manager.
|
||||
*/
|
||||
updates?: Omit<ParsedUpdateHandlerParams & UpdatesManagerParams, 'onUpdate' | 'onRawUpdate'>
|
||||
|
||||
/**
|
||||
* **ADVANCED**
|
||||
*
|
||||
* If set to `true`, updates manager will not be created,
|
||||
* and only raw TL Updates will be emitted.
|
||||
*
|
||||
* Unlike {@link TelegramClientOptions.disableUpdates}, this
|
||||
* does not prevent the updates from being sent by the server,
|
||||
* but disables proper handling of them (see [Working with Updates](https://core.telegram.org/api/updates))
|
||||
*
|
||||
* This may be useful in some cases when you require more control over
|
||||
* the updates or to minimize additional overhead from properly handling them
|
||||
* for some very particular use cases.
|
||||
*
|
||||
* The updates **will not** be dispatched the normal way, instead
|
||||
* you should manually add a handler using `client.network.setUpdateHandler`.
|
||||
*/
|
||||
disableUpdatesManager?: boolean
|
||||
|
||||
/**
|
||||
* If `true`, the updates that were handled by some {@link Conversation}
|
||||
* will not be dispatched any further.
|
||||
*
|
||||
* @default true
|
||||
*/
|
||||
skipConversationUpdates?: boolean
|
||||
}
|
||||
|
||||
// @initialize=super
|
||||
/** @internal */
|
||||
function _initializeClientSuper(this: TelegramClient, opts: TelegramClientOptions) {
|
||||
if (typeof opts.storage === 'string') {
|
||||
opts.storage = _defaultStorageFactory(opts.storage)
|
||||
} else if (!opts.storage) {
|
||||
opts.storage = new MemoryStorage()
|
||||
}
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||
// @ts-expect-error codegen
|
||||
super(opts)
|
||||
/* eslint-enable @typescript-eslint/no-unsafe-call */
|
||||
}
|
||||
|
||||
// @initialize
|
||||
/** @internal */
|
||||
function _initializeClient(this: TelegramClient, opts: TelegramClientOptions) {
|
||||
this._disableUpdatesManager = opts.disableUpdatesManager ?? false
|
||||
const skipConversationUpdates = opts.skipConversationUpdates ?? true
|
||||
|
||||
if (!opts.disableUpdates && !opts.disableUpdatesManager) {
|
||||
const { messageGroupingInterval, ...managerParams } = opts.updates ?? {}
|
||||
|
||||
enableUpdatesProcessing(this, {
|
||||
...managerParams,
|
||||
onUpdate: makeParsedUpdateHandler({
|
||||
messageGroupingInterval,
|
||||
onUpdate: (update) => {
|
||||
if (Conversation.handleUpdate(this, update) && skipConversationUpdates) return
|
||||
|
||||
this.emit('update', update)
|
||||
this.emit(update.name, update.data)
|
||||
},
|
||||
onRawUpdate: (update, peers) => {
|
||||
this.emit('raw_update', update, peers)
|
||||
},
|
||||
}),
|
||||
})
|
||||
}
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
/* eslint-disable no-inner-declarations */
|
||||
import { BaseTelegramClient, MtUnsupportedError, tl } from '@mtcute/core'
|
||||
import { assertTypeIs } from '@mtcute/core/utils.js'
|
||||
|
||||
import { User } from '../../types/peers/user.js'
|
||||
|
||||
/** @internal */
|
||||
export async function _onAuthorization(
|
||||
client: BaseTelegramClient,
|
||||
auth: tl.auth.TypeAuthorization,
|
||||
): Promise<User> {
|
||||
if (auth._ === 'auth.authorizationSignUpRequired') {
|
||||
throw new MtUnsupportedError(
|
||||
'Signup is no longer supported by Telegram for non-official clients. Please use your mobile device to sign up.',
|
||||
)
|
||||
}
|
||||
|
||||
assertTypeIs('_onAuthorization (@ auth.authorization -> user)', auth.user, 'user')
|
||||
|
||||
// todo: selfUsername
|
||||
await client.notifyLoggedIn(auth)
|
||||
|
||||
// telegram ignores invokeWithoutUpdates for auth methods
|
||||
if (client.network.params.disableUpdates) client.network.resetSessions()
|
||||
|
||||
return new User(auth.user)
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given peer/input peer is referring to the current user
|
||||
*/
|
||||
export function isSelfPeer(
|
||||
client: BaseTelegramClient,
|
||||
peer: tl.TypeInputPeer | tl.TypePeer | tl.TypeInputUser,
|
||||
): boolean {
|
||||
const state = client.storage.self.getCached()
|
||||
if (!state) return false
|
||||
|
||||
switch (peer._) {
|
||||
case 'inputPeerSelf':
|
||||
case 'inputUserSelf':
|
||||
return true
|
||||
case 'inputPeerUser':
|
||||
case 'inputPeerUserFromMessage':
|
||||
case 'inputUser':
|
||||
case 'inputUserFromMessage':
|
||||
case 'peerUser':
|
||||
return peer.userId === state.userId
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
import { BaseTelegramClient, getMarkedPeerId, tl } from '@mtcute/core'
|
||||
|
||||
/** @internal */
|
||||
export function _getPeerChainId(client: BaseTelegramClient, peer: tl.TypeInputPeer, prefix = 'peer') {
|
||||
const id = peer._ === 'inputPeerSelf' ? client.storage.self.getCached()!.userId : getMarkedPeerId(peer)
|
||||
|
||||
return `${prefix}:${id}`
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,42 +0,0 @@
|
|||
import { tl } from '@mtcute/core'
|
||||
|
||||
export function messageToUpdate(message: tl.TypeMessage): tl.TypeUpdate {
|
||||
switch (message.peerId!._) {
|
||||
case 'peerUser':
|
||||
case 'peerChat':
|
||||
return {
|
||||
_: 'updateNewMessage',
|
||||
message,
|
||||
pts: 0,
|
||||
ptsCount: 0,
|
||||
}
|
||||
case 'peerChannel':
|
||||
return {
|
||||
_: 'updateNewChannelMessage',
|
||||
message,
|
||||
pts: 0,
|
||||
ptsCount: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function extractChannelIdFromUpdate(upd: tl.TypeUpdate): number | undefined {
|
||||
// holy shit
|
||||
let res = 0
|
||||
|
||||
if ('channelId' in upd) {
|
||||
res = upd.channelId
|
||||
} else if (
|
||||
'message' in upd &&
|
||||
typeof upd.message !== 'string' &&
|
||||
'peerId' in upd.message &&
|
||||
upd.message.peerId &&
|
||||
'channelId' in upd.message.peerId
|
||||
) {
|
||||
res = upd.message.peerId.channelId
|
||||
}
|
||||
|
||||
if (res === 0) return undefined
|
||||
|
||||
return res
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
/** @internal */
|
||||
export const _defaultStorageFactory = (name: string) => {
|
||||
// todo: move sqlite to core?
|
||||
throw new Error('Not implemented')
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
import { MtTypeAssertionError, tl } from '@mtcute/core'
|
||||
|
||||
// dummy updates which are used for methods that return messages.affectedHistory.
|
||||
// that is not an update, but it carries info about pts, and we need to handle it
|
||||
|
||||
/**
|
||||
* Create a dummy `updates` container with given updates.
|
||||
*/
|
||||
export function createDummyUpdatesContainer(updates: tl.TypeUpdate[], seq = 0): tl.TypeUpdates {
|
||||
return {
|
||||
_: 'updates',
|
||||
seq,
|
||||
date: 0,
|
||||
chats: [],
|
||||
users: [],
|
||||
updates,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a dummy update from PTS and PTS count.
|
||||
*
|
||||
* @param pts PTS
|
||||
* @param ptsCount PTS count
|
||||
* @param channelId Channel ID (bare), if applicable
|
||||
*/
|
||||
export function createDummyUpdate(pts: number, ptsCount: number, channelId = 0): tl.TypeUpdates {
|
||||
return createDummyUpdatesContainer([
|
||||
{
|
||||
_: 'mtcute.dummyUpdate',
|
||||
channelId,
|
||||
pts,
|
||||
ptsCount,
|
||||
},
|
||||
])
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function assertIsUpdatesGroup(
|
||||
ctx: string,
|
||||
upd: tl.TypeUpdates,
|
||||
): asserts upd is tl.RawUpdates | tl.RawUpdatesCombined {
|
||||
switch (upd._) {
|
||||
case 'updates':
|
||||
case 'updatesCombined':
|
||||
return
|
||||
}
|
||||
throw new MtTypeAssertionError(ctx, 'updates | updatesCombined', upd._)
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist/esm",
|
||||
"rootDir": "./src"
|
||||
},
|
||||
"include": [
|
||||
"./src",
|
||||
],
|
||||
"references": [
|
||||
{ "path": "../core" },
|
||||
{ "path": "../test" }
|
||||
]
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
module.exports = {
|
||||
extends: ['../../.config/typedoc/config.base.cjs'],
|
||||
entryPoints: [
|
||||
'./src/index.ts',
|
||||
'./src/utils/index.ts',
|
||||
'./src/methods/updates/index.ts',
|
||||
],
|
||||
entryPointStrategy: 'expand',
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
// this file only exists as a hint to IDEs that we can use @mtcute/core/utils instead of @mtcute/core/src/utils.
|
||||
// it is not present in the built package, just a DX improvement
|
||||
|
||||
export * from './src/utils/index.js'
|
|
@ -1,5 +1,6 @@
|
|||
module.exports = ({ path, transformFile, packageDir, outDir }) => ({
|
||||
esmOnlyDirectives: true,
|
||||
esmImportDirectives: true,
|
||||
final() {
|
||||
const version = require(path.join(packageDir, 'package.json')).version
|
||||
const replaceVersion = (content) => content.replace('%VERSION%', version)
|
||||
|
|
|
@ -2,13 +2,15 @@
|
|||
"name": "@mtcute/core",
|
||||
"private": true,
|
||||
"version": "0.6.0",
|
||||
"description": "Core functions and base MTProto client",
|
||||
"description": "Type-safe library for MTProto (Telegram API)",
|
||||
"author": "Alina Sireneva <alina@tei.su>",
|
||||
"license": "MIT",
|
||||
"main": "src/index.ts",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "pnpm run -w build-package core"
|
||||
"build": "pnpm run -w build-package mtcute",
|
||||
"gen-client": "node ./scripts/generate-client.cjs",
|
||||
"gen-updates": "node ./scripts/generate-updates.cjs"
|
||||
},
|
||||
"browser": {
|
||||
"./src/utils/platform/crypto.js": "./src/utils/platform/crypto.web.js",
|
||||
|
@ -16,6 +18,11 @@
|
|||
"./src/utils/platform/logging.js": "./src/utils/platform/logging.web.js",
|
||||
"./src/utils/platform/random.js": "./src/utils/platform/random.web.js",
|
||||
"./src/utils/platform/exit-hook.js": "./src/utils/platform/exit-hook.web.js",
|
||||
"./src/highlevel/worker/platform/connect.js": "./src/highlevel/worker/platform/connect.web.js",
|
||||
"./src/highlevel/worker/platform/register.js": "./src/highlevel/worker/platform/register.web.js",
|
||||
"./src/highlevel/methods/files/_platform.js": "./src/highlevel/methods/files/_platform.web.js",
|
||||
"./src/highlevel/methods/files/download-file.js": "./src/highlevel/methods/files/download-file.web.js",
|
||||
"./src/highlevel/utils/platform/storage.js": "./src/highlevel/utils/platform/storage.web.js",
|
||||
"./src/storage/json-file.js": false
|
||||
},
|
||||
"distOnlyFields": {
|
||||
|
@ -39,6 +46,14 @@
|
|||
"./storage/*": {
|
||||
"import": "./esm/storage/*",
|
||||
"require": "./cjs/storage/*"
|
||||
},
|
||||
"./highlevel/*": {
|
||||
"import": "./esm/highlevel/*",
|
||||
"require": "./cjs/highlevel/*"
|
||||
},
|
||||
"./methods/*": {
|
||||
"import": "./esm/highlevel/methods/*",
|
||||
"require": "./cjs/highlevel/methods/*"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -46,13 +61,13 @@
|
|||
"@mtcute/tl": "workspace:^",
|
||||
"@mtcute/tl-runtime": "workspace:^",
|
||||
"@mtcute/wasm": "workspace:^",
|
||||
"@mtcute/file-id": "workspace:^",
|
||||
"@types/events": "3.0.0",
|
||||
"events": "3.2.0",
|
||||
"long": "5.2.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/ws": "8.5.4",
|
||||
"node-forge": "1.3.1",
|
||||
"@mtcute/test": "workspace:^",
|
||||
"ws": "8.13.0"
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ function findMethodAvailability(method) {
|
|||
return entry.available ?? null
|
||||
}
|
||||
|
||||
const targetDir = path.join(__dirname, '../src')
|
||||
const targetDir = path.join(__dirname, '../src/highlevel')
|
||||
|
||||
async function* getFiles(dir) {
|
||||
const dirents = await fs.promises.readdir(dir, { withFileTypes: true })
|
||||
|
@ -315,7 +315,7 @@ async function addSingleMethod(state, fileName) {
|
|||
|
||||
const firstArg = stmt.parameters[0]
|
||||
|
||||
if (isExported && (!firstArg || firstArg.type.getText() !== 'BaseTelegramClient')) {
|
||||
if (isExported && (!firstArg || firstArg.type.getText() !== 'ITelegramClient')) {
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -421,7 +421,8 @@ async function addSingleMethod(state, fileName) {
|
|||
}
|
||||
|
||||
async function main() {
|
||||
const output = fs.createWriteStream(path.join(__dirname, '../src/client.ts'))
|
||||
const targetFile = path.join(__dirname, '../src/highlevel/client.ts')
|
||||
const output = fs.createWriteStream(targetFile)
|
||||
const state = {
|
||||
imports: {},
|
||||
fields: [],
|
||||
|
@ -435,7 +436,7 @@ async function main() {
|
|||
files: {},
|
||||
}
|
||||
|
||||
for await (const file of getFiles(path.join(__dirname, '../src/methods'))) {
|
||||
for await (const file of getFiles(path.join(__dirname, '../src/highlevel/methods'))) {
|
||||
if (!file.startsWith('.') && file.endsWith('.ts') && !file.endsWith('.web.ts') && !file.endsWith('.test.ts')) {
|
||||
await addSingleMethod(state, file)
|
||||
}
|
||||
|
@ -444,7 +445,9 @@ async function main() {
|
|||
output.write(
|
||||
'/* eslint-disable @typescript-eslint/no-unsafe-declaration-merging, @typescript-eslint/unified-signatures */\n' +
|
||||
'/* eslint-disable @typescript-eslint/no-unsafe-argument */\n' +
|
||||
'/* THIS FILE WAS AUTO-GENERATED */\n',
|
||||
'/* THIS FILE WAS AUTO-GENERATED */\n' +
|
||||
"import EventEmitter from 'events'\n" +
|
||||
"import Long from 'long'\n",
|
||||
)
|
||||
Object.entries(state.imports).forEach(([module, items]) => {
|
||||
items = [...items]
|
||||
|
@ -458,7 +461,7 @@ async function main() {
|
|||
output.write(`// from ${from}\n${code}\n`)
|
||||
})
|
||||
|
||||
output.write('\nexport interface TelegramClient extends BaseTelegramClient {\n')
|
||||
output.write('\nexport interface TelegramClient extends ITelegramClient {\n')
|
||||
|
||||
output.write(`/**
|
||||
* Register a raw update handler
|
||||
|
@ -547,7 +550,7 @@ on(name: string, handler: (...args: any[]) => void): this\n`)
|
|||
`<${func.typeParameters.map((it) => it.getFullText()).join(', ')}>` :
|
||||
''
|
||||
const rawParams = (func.parameters || []).filter(
|
||||
(it) => !it.type || it.type.getText() !== 'BaseTelegramClient',
|
||||
(it) => !it.type || it.type.getText() !== 'ITelegramClient',
|
||||
)
|
||||
const parameters = rawParams
|
||||
.map((it) => {
|
||||
|
@ -648,8 +651,8 @@ on(name: string, handler: (...args: any[]) => void): this\n`)
|
|||
if (hasOverloads) {
|
||||
classProtoDecls.push('// @ts-expect-error this kinda breaks typings for overloads, idc')
|
||||
}
|
||||
classProtoDecls.push(` return ${origName}(this, ...args);`)
|
||||
classProtoDecls.push('}\n')
|
||||
classProtoDecls.push(` return ${origName}(this._client, ...args);`)
|
||||
classProtoDecls.push('}')
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -657,11 +660,13 @@ on(name: string, handler: (...args: any[]) => void): this\n`)
|
|||
output.write('}\n')
|
||||
|
||||
output.write('\nexport type { TelegramClientOptions }\n')
|
||||
output.write('\nexport class TelegramClient extends BaseTelegramClient {\n')
|
||||
output.write('\nexport class TelegramClient extends EventEmitter implements ITelegramClient {\n')
|
||||
|
||||
output.write(' _client: ITelegramClient\n')
|
||||
state.fields.forEach(({ code }) => output.write(`protected ${code}\n`))
|
||||
|
||||
output.write('constructor(opts: TelegramClientOptions) {\n')
|
||||
output.write(' super()\n')
|
||||
state.init.forEach((code) => {
|
||||
output.write(code + '\n')
|
||||
})
|
||||
|
@ -670,10 +675,45 @@ on(name: string, handler: (...args: any[]) => void): this\n`)
|
|||
classContents.forEach((line) => output.write(line + '\n'))
|
||||
output.write('}\n')
|
||||
classProtoDecls.forEach((line) => output.write(line + '\n'))
|
||||
// proxied methods
|
||||
;[
|
||||
'prepare',
|
||||
'connect',
|
||||
'close',
|
||||
'notifyLoggedIn',
|
||||
'notifyLoggedOut',
|
||||
'notifyChannelOpened',
|
||||
'notifyChannelClosed',
|
||||
'call',
|
||||
'importSession',
|
||||
'exportSession',
|
||||
'onError',
|
||||
'emitError',
|
||||
'handleClientUpdate',
|
||||
'getApiCrenetials',
|
||||
'getPoolSize',
|
||||
'getPrimaryDcId',
|
||||
'computeSrpParams',
|
||||
'computeNewPasswordHash',
|
||||
].forEach((name) => {
|
||||
output.write(
|
||||
`TelegramClient.prototype.${name} = function(...args) {\n` +
|
||||
` return this._client.${name}(...args)\n` +
|
||||
'}\n',
|
||||
)
|
||||
})
|
||||
// disabled methods - they are used internally and we don't want to expose them
|
||||
// if the user *really* needs them, they can use `client._client` to access the underlying client
|
||||
;['onServerUpdate', 'onUpdate'].forEach((name) => {
|
||||
output.write(
|
||||
`TelegramClient.prototype.${name} = function() {\n` +
|
||||
` throw new Error('${name} is not available for TelegramClient, use .on() methods instead')\n` +
|
||||
'}\n',
|
||||
)
|
||||
})
|
||||
state.impls.forEach(({ name, code }) => output.write(`TelegramClient.prototype.${name} = ${code}\n`))
|
||||
|
||||
// format the resulting file with prettier
|
||||
const targetFile = path.join(__dirname, '../src/client.ts')
|
||||
const prettierConfig = await prettier.resolveConfig(targetFile)
|
||||
let fullSource = await fs.promises.readFile(targetFile, 'utf-8')
|
||||
fullSource = await prettier.format(fullSource, {
|
|
@ -1,4 +1,3 @@
|
|||
/* eslint-disable no-restricted-globals */
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const prettier = require('prettier')
|
||||
|
@ -90,7 +89,7 @@ function toSentence(type, stype = 'inline') {
|
|||
}
|
||||
|
||||
function generateParsedUpdate() {
|
||||
replaceSections('types/updates/index.ts', {
|
||||
replaceSections('highlevel/types/updates/index.ts', {
|
||||
codegen:
|
||||
'export type ParsedUpdate =\n' +
|
||||
types.map((typ) => ` | { name: '${typ.typeName}'; data: ${typ.updateType} }\n`).join(''),
|
|
@ -1,354 +0,0 @@
|
|||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import EventEmitter from 'events'
|
||||
|
||||
import { tl } from '@mtcute/tl'
|
||||
import { __tlReaderMap as defaultReaderMap } from '@mtcute/tl/binary/reader.js'
|
||||
import { __tlWriterMap as defaultWriterMap } from '@mtcute/tl/binary/writer.js'
|
||||
import { TlReaderMap, TlWriterMap } from '@mtcute/tl-runtime'
|
||||
|
||||
import { BaseTelegramClientOptions } from './base-client.types.js'
|
||||
import { ConfigManager } from './network/config-manager.js'
|
||||
import { SessionConnection } from './network/index.js'
|
||||
import { NetworkManager, RpcCallOptions } from './network/network-manager.js'
|
||||
import { StorageManager } from './storage/storage.js'
|
||||
import { MustEqual } from './types/index.js'
|
||||
import {
|
||||
ControllablePromise,
|
||||
createControllablePromise,
|
||||
DcOptions,
|
||||
defaultCryptoProviderFactory,
|
||||
defaultProductionDc,
|
||||
defaultProductionIpv6Dc,
|
||||
defaultTestDc,
|
||||
defaultTestIpv6Dc,
|
||||
ICryptoProvider,
|
||||
LogManager,
|
||||
readStringSession,
|
||||
StringSessionData,
|
||||
writeStringSession,
|
||||
} from './utils/index.js'
|
||||
|
||||
/**
|
||||
* Basic Telegram client that only implements the bare minimum
|
||||
* to make RPC calls and receive low-level updates.
|
||||
*/
|
||||
export class BaseTelegramClient extends EventEmitter {
|
||||
/**
|
||||
* Crypto provider taken from {@link BaseTelegramClientOptions.crypto}
|
||||
*/
|
||||
readonly crypto: ICryptoProvider
|
||||
|
||||
/** Storage manager */
|
||||
readonly storage: StorageManager
|
||||
|
||||
/**
|
||||
* "Test mode" taken from {@link BaseTelegramClientOptions.testMode}
|
||||
*/
|
||||
protected readonly _testMode: boolean
|
||||
|
||||
/**
|
||||
* Primary DCs taken from {@link BaseTelegramClientOptions.defaultDcs},
|
||||
* loaded from session or changed by other means (like redirecting).
|
||||
*/
|
||||
protected _defaultDcs: DcOptions
|
||||
|
||||
private _niceStacks: boolean
|
||||
/** TL layer used by the client */
|
||||
readonly _layer: number
|
||||
/** TL readers map used by the client */
|
||||
readonly _readerMap: TlReaderMap
|
||||
/** TL writers map used by the client */
|
||||
readonly _writerMap: TlWriterMap
|
||||
|
||||
readonly _config = new ConfigManager(() => this.call({ _: 'help.getConfig' }))
|
||||
|
||||
// not really connected, but rather "connect() was called"
|
||||
private _connected: ControllablePromise<void> | boolean = false
|
||||
|
||||
_emitError: (err: unknown, connection?: SessionConnection) => void = console.error.bind(console)
|
||||
|
||||
private _importFrom?: StringSessionData
|
||||
private _importForce?: boolean
|
||||
|
||||
readonly log = new LogManager('client')
|
||||
readonly network: NetworkManager
|
||||
|
||||
constructor(readonly params: BaseTelegramClientOptions) {
|
||||
super()
|
||||
|
||||
if (params.logLevel !== undefined) {
|
||||
this.log.level = params.logLevel
|
||||
}
|
||||
|
||||
this.crypto = (params.crypto ?? defaultCryptoProviderFactory)()
|
||||
this._testMode = Boolean(params.testMode)
|
||||
|
||||
let dc = params.defaultDcs
|
||||
|
||||
if (!dc) {
|
||||
if (params.testMode) {
|
||||
dc = params.useIpv6 ? defaultTestIpv6Dc : defaultTestDc
|
||||
} else {
|
||||
dc = params.useIpv6 ? defaultProductionIpv6Dc : defaultProductionDc
|
||||
}
|
||||
}
|
||||
|
||||
this._defaultDcs = dc
|
||||
this._niceStacks = params.niceStacks ?? true
|
||||
|
||||
this._layer = params.overrideLayer ?? tl.LAYER
|
||||
this._readerMap = params.readerMap ?? defaultReaderMap
|
||||
this._writerMap = params.writerMap ?? defaultWriterMap
|
||||
|
||||
this.storage = new StorageManager({
|
||||
provider: params.storage,
|
||||
log: this.log,
|
||||
readerMap: this._readerMap,
|
||||
writerMap: this._writerMap,
|
||||
...params.storageOptions,
|
||||
})
|
||||
|
||||
this.network = new NetworkManager(
|
||||
{
|
||||
apiId: params.apiId,
|
||||
crypto: this.crypto,
|
||||
disableUpdates: params.disableUpdates ?? false,
|
||||
initConnectionOptions: params.initConnectionOptions,
|
||||
layer: this._layer,
|
||||
log: this.log,
|
||||
readerMap: this._readerMap,
|
||||
writerMap: this._writerMap,
|
||||
reconnectionStrategy: params.reconnectionStrategy,
|
||||
storage: this.storage,
|
||||
testMode: Boolean(params.testMode),
|
||||
transport: params.transport,
|
||||
_emitError: this._emitError.bind(this),
|
||||
floodSleepThreshold: params.floodSleepThreshold ?? 10000,
|
||||
maxRetryCount: params.maxRetryCount ?? 5,
|
||||
isPremium: false,
|
||||
useIpv6: Boolean(params.useIpv6),
|
||||
enableErrorReporting: params.enableErrorReporting ?? false,
|
||||
onUsable: () => this.emit('usable'),
|
||||
...params.network,
|
||||
},
|
||||
this._config,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the connection to the primary DC.
|
||||
*
|
||||
* You shouldn't usually call this method directly as it is called
|
||||
* implicitly the first time you call {@link call}.
|
||||
*/
|
||||
async connect(): Promise<void> {
|
||||
if (this._connected) {
|
||||
// avoid double-connect
|
||||
await this._connected
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
const promise = (this._connected = createControllablePromise())
|
||||
|
||||
await this.crypto.initialize?.()
|
||||
await this.storage.load()
|
||||
|
||||
const primaryDc = await this.storage.dcs.fetch()
|
||||
if (primaryDc !== null) this._defaultDcs = primaryDc
|
||||
|
||||
const self = await this.storage.self.fetch()
|
||||
this.log.prefix = `[USER ${self?.userId ?? 'n/a'}] `
|
||||
|
||||
const defaultDcAuthKey = await this.storage.provider.authKeys.get(this._defaultDcs.main.id)
|
||||
|
||||
if ((this._importForce || !defaultDcAuthKey) && this._importFrom) {
|
||||
const data = this._importFrom
|
||||
|
||||
if (data.testMode !== this._testMode) {
|
||||
throw new Error(
|
||||
'This session string is not for the current backend. ' +
|
||||
`Session is ${data.testMode ? 'test' : 'prod'}, but the client is ${
|
||||
this._testMode ? 'test' : 'prod'
|
||||
}`,
|
||||
)
|
||||
}
|
||||
|
||||
this._defaultDcs = data.primaryDcs
|
||||
await this.storage.dcs.store(data.primaryDcs)
|
||||
|
||||
if (data.self) {
|
||||
await this.storage.self.store(data.self)
|
||||
}
|
||||
|
||||
await this.storage.provider.authKeys.set(data.primaryDcs.main.id, data.authKey)
|
||||
|
||||
await this.storage.save()
|
||||
}
|
||||
|
||||
this.emit('before_connect')
|
||||
|
||||
this.network
|
||||
.connect(this._defaultDcs)
|
||||
.then(() => {
|
||||
promise.resolve()
|
||||
this._connected = true
|
||||
})
|
||||
.catch((err: Error) => this._emitError(err))
|
||||
}
|
||||
|
||||
/**
|
||||
* Close all connections and finalize the client.
|
||||
*/
|
||||
async close(): Promise<void> {
|
||||
this.emit('before_close')
|
||||
|
||||
this._config.destroy()
|
||||
this.network.destroy()
|
||||
|
||||
await this.storage.save()
|
||||
await this.storage.destroy?.()
|
||||
|
||||
this.emit('closed')
|
||||
}
|
||||
|
||||
/**
|
||||
* Make an RPC call to the primary DC.
|
||||
* This method handles DC migration, flood waits and retries automatically.
|
||||
*
|
||||
* If you want more low-level control, use
|
||||
* `primaryConnection.sendForResult()` (which is what this method wraps)
|
||||
*
|
||||
* This method is still quite low-level and you shouldn't use this
|
||||
* when using high-level API provided by `@mtcute/client`.
|
||||
*
|
||||
* @param message RPC method to call
|
||||
* @param params Additional call parameters
|
||||
*/
|
||||
async call<T extends tl.RpcMethod>(
|
||||
message: MustEqual<T, tl.RpcMethod>,
|
||||
params?: RpcCallOptions,
|
||||
): Promise<tl.RpcCallReturn[T['_']]> {
|
||||
if (this._connected !== true) {
|
||||
await this.connect()
|
||||
}
|
||||
|
||||
const stack = this._niceStacks ? new Error().stack : undefined
|
||||
|
||||
const res = await this.network.call(message, params, stack)
|
||||
|
||||
await this.storage.peers.updatePeersFrom(res)
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
||||
return res
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Proxy that will call all methods with given call parameters
|
||||
* (see {@link RpcCallOptions}})
|
||||
*
|
||||
* This is useful when you don't call `call()` directly, but rather
|
||||
* use high-level API provided by `@mtcute/client`, for example:
|
||||
*
|
||||
* ```ts
|
||||
* const client = new TelegramClient(...)
|
||||
*
|
||||
* const someone = await client
|
||||
* .withCallParams({ timeout: 500 })
|
||||
* .getUsers(...)
|
||||
* ```
|
||||
*/
|
||||
withCallParams(params: RpcCallOptions): this {
|
||||
return new Proxy(this, {
|
||||
get(target, prop, receiver) {
|
||||
if (prop === 'call') {
|
||||
return (message: tl.RpcMethod, paramsCustom?: RpcCallOptions) =>
|
||||
target.call(message, {
|
||||
...params,
|
||||
...paramsCustom,
|
||||
})
|
||||
}
|
||||
|
||||
return Reflect.get(target, prop, receiver)
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Shorthand for `withCallParams({ abortSignal })`
|
||||
*/
|
||||
withAbortSignal(signal: AbortSignal): this {
|
||||
return this.withCallParams({ abortSignal: signal })
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an error handler for the client
|
||||
*
|
||||
* @param handler
|
||||
* Error handler. Called with one or two parameters.
|
||||
* The first one is always the error, and the second is
|
||||
* the connection in which the error has occurred, in case
|
||||
* this was connection-related error.
|
||||
*/
|
||||
onError(handler: (err: unknown, connection?: SessionConnection) => void): void {
|
||||
this._emitError = handler
|
||||
}
|
||||
|
||||
async notifyLoggedIn(auth: tl.auth.RawAuthorization): Promise<void> {
|
||||
this.network.notifyLoggedIn(auth)
|
||||
this.log.prefix = `[USER ${auth.user.id}] `
|
||||
await this.storage.self.store({
|
||||
userId: auth.user.id,
|
||||
isBot: auth.user._ === 'user' && auth.user.bot!,
|
||||
})
|
||||
this.emit('logged_in', auth)
|
||||
}
|
||||
|
||||
/**
|
||||
* Export current session to a single *LONG* string, containing
|
||||
* all the needed information.
|
||||
*
|
||||
* > **Warning!** Anyone with this string will be able
|
||||
* > to authorize as you and do anything. Treat this
|
||||
* > as your password, and never give it away!
|
||||
* >
|
||||
* > In case you have accidentally leaked this string,
|
||||
* > make sure to revoke this session in account settings:
|
||||
* > "Privacy & Security" > "Active sessions" >
|
||||
* > find the one containing `mtcute` > Revoke,
|
||||
* > or, in case this is a bot, revoke bot token
|
||||
* > with [@BotFather](//t.me/botfather)
|
||||
*/
|
||||
async exportSession(): Promise<string> {
|
||||
const primaryDcs = (await this.storage.dcs.fetch()) ?? this._defaultDcs
|
||||
|
||||
const authKey = await this.storage.provider.authKeys.get(primaryDcs.main.id)
|
||||
if (!authKey) throw new Error('Auth key is not ready yet')
|
||||
|
||||
return writeStringSession(this._writerMap, {
|
||||
version: 2,
|
||||
self: await this.storage.self.fetch(),
|
||||
testMode: this._testMode,
|
||||
primaryDcs,
|
||||
authKey,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Request the session to be imported from the given session string.
|
||||
*
|
||||
* Note that the session will not be imported right away,
|
||||
* instead, it will be imported once `connect()` is called
|
||||
*
|
||||
* Also note that the session will only be imported in case
|
||||
* the storage is missing authorization (i.e. does not contain
|
||||
* auth key for the primary DC), otherwise it will be ignored (unless `force`).
|
||||
*
|
||||
* @param session Session string to import
|
||||
* @param force Whether to overwrite existing session
|
||||
*/
|
||||
importSession(session: string | StringSessionData, force = false): void {
|
||||
this._importFrom = typeof session === 'string' ? readStringSession(this._readerMap, session) : session
|
||||
this._importForce = force
|
||||
}
|
||||
}
|
|
@ -1,177 +0,0 @@
|
|||
import { tl } from '@mtcute/tl'
|
||||
import { TlReaderMap, TlWriterMap } from '@mtcute/tl-runtime'
|
||||
|
||||
import { NetworkManagerExtraParams, ReconnectionStrategy, TransportFactory } from './network/index.js'
|
||||
import { PersistentConnectionParams } from './network/persistent-connection.js'
|
||||
import { IMtStorageProvider } from './storage/provider.js'
|
||||
import { StorageManagerExtraOptions } from './storage/storage.js'
|
||||
import { CryptoProviderFactory, DcOptions } from './utils/index.js'
|
||||
|
||||
/** Options for {@link BaseTelegramClient} */
|
||||
export interface BaseTelegramClientOptions {
|
||||
/**
|
||||
* API ID from my.telegram.org
|
||||
*/
|
||||
apiId: number
|
||||
/**
|
||||
* API hash from my.telegram.org
|
||||
*/
|
||||
apiHash: string
|
||||
|
||||
/**
|
||||
* Storage to use for this client.
|
||||
*/
|
||||
storage: IMtStorageProvider
|
||||
|
||||
/** Additional options for the storage manager */
|
||||
storageOptions?: StorageManagerExtraOptions
|
||||
|
||||
/**
|
||||
* Cryptography provider factory to allow delegating
|
||||
* crypto to native addon, worker, etc.
|
||||
*/
|
||||
crypto?: CryptoProviderFactory
|
||||
|
||||
/**
|
||||
* Whether to use IPv6 datacenters
|
||||
* (IPv6 will be preferred when choosing a DC by id)
|
||||
* (default: false)
|
||||
*/
|
||||
useIpv6?: boolean
|
||||
|
||||
/**
|
||||
* Primary DC to use for initial connection.
|
||||
* This does not mean this will be the only DC used,
|
||||
* nor that this DC will actually be primary, this only
|
||||
* determines the first DC the library will try to connect to.
|
||||
* Can be used to connect to other networks (like test DCs).
|
||||
*
|
||||
* When session already contains primary DC, this parameter is ignored.
|
||||
*
|
||||
* @default Production DC 2.
|
||||
*/
|
||||
defaultDcs?: DcOptions
|
||||
|
||||
/**
|
||||
* Whether to connect to test servers.
|
||||
*
|
||||
* If passed, {@link defaultDc} defaults to Test DC 2.
|
||||
*
|
||||
* **Must** be passed if using test servers, even if
|
||||
* you passed custom {@link defaultDc}
|
||||
*/
|
||||
testMode?: boolean
|
||||
|
||||
/**
|
||||
* Additional options for initConnection call.
|
||||
* `apiId` and `query` are not available and will be ignored.
|
||||
* Omitted values will be filled with defaults
|
||||
*/
|
||||
initConnectionOptions?: Partial<Omit<tl.RawInitConnectionRequest, 'apiId' | 'query'>>
|
||||
|
||||
/**
|
||||
* Transport factory to use in the client.
|
||||
*
|
||||
* @default platform-specific transport: WebSocket on the web, TCP in node
|
||||
*/
|
||||
transport?: TransportFactory
|
||||
|
||||
/**
|
||||
* Reconnection strategy.
|
||||
*
|
||||
* @default simple reconnection strategy: first 0ms, then up to 5s (increasing by 1s)
|
||||
*/
|
||||
reconnectionStrategy?: ReconnectionStrategy<PersistentConnectionParams>
|
||||
|
||||
/**
|
||||
* Maximum duration of a flood_wait that will be waited automatically.
|
||||
* Flood waits above this threshold will throw a FloodWaitError.
|
||||
* Set to 0 to disable. Can be overridden with `throwFlood` parameter in call() params
|
||||
*
|
||||
* @default 10000
|
||||
*/
|
||||
floodSleepThreshold?: number
|
||||
|
||||
/**
|
||||
* Maximum number of retries when calling RPC methods.
|
||||
* Call is retried when InternalError or FloodWaitError is encountered.
|
||||
* Can be set to Infinity.
|
||||
*
|
||||
* @default 5
|
||||
*/
|
||||
maxRetryCount?: number
|
||||
|
||||
/**
|
||||
* If true, every single API call will be wrapped with `tl.invokeWithoutUpdates`,
|
||||
* effectively disabling the server-sent events for the clients.
|
||||
* May be useful in some cases.
|
||||
*
|
||||
* Note that this only wraps calls made with `.call()` within the primary
|
||||
* connection. Additional connections and direct `.sendForResult()` calls
|
||||
* must be wrapped manually.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
disableUpdates?: boolean
|
||||
|
||||
/**
|
||||
* mtcute can send all unknown RPC errors to [danog](https://github.com/danog)'s
|
||||
* [error reporting service](https://rpc.pwrtelegram.xyz/).
|
||||
*
|
||||
* This is fully anonymous (except maybe IP) and is only used to improve the library
|
||||
* and developer experience for everyone working with MTProto. This is fully opt-in,
|
||||
* and if you're too paranoid, you can disable it by manually passing `enableErrorReporting: false` to the client.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
enableErrorReporting?: boolean
|
||||
|
||||
/**
|
||||
* If true, RPC errors will have a stack trace of the initial `.call()`
|
||||
* or `.sendForResult()` call position, which drastically improves
|
||||
* debugging experience.<br>
|
||||
* If false, they will have a stack trace of mtcute internals.
|
||||
*
|
||||
* Internally this creates a stack capture before every RPC call
|
||||
* and stores it until the result is received. This might
|
||||
* use a lot more memory than normal, thus can be disabled here.
|
||||
*
|
||||
* @default true
|
||||
*/
|
||||
niceStacks?: boolean
|
||||
|
||||
/**
|
||||
* Extra parameters for {@link NetworkManager}
|
||||
*/
|
||||
network?: NetworkManagerExtraParams
|
||||
|
||||
/**
|
||||
* Set logging level for the client.
|
||||
*
|
||||
* See static members of {@link LogManager} for possible values.
|
||||
*/
|
||||
logLevel?: number
|
||||
|
||||
/**
|
||||
* **EXPERT USE ONLY!**
|
||||
*
|
||||
* Override TL layer used for the connection.
|
||||
*
|
||||
* **Does not** change the schema used.
|
||||
*/
|
||||
overrideLayer?: number
|
||||
|
||||
/**
|
||||
* **EXPERT USE ONLY**
|
||||
*
|
||||
* Override reader map used for the connection.
|
||||
*/
|
||||
readerMap?: TlReaderMap
|
||||
|
||||
/**
|
||||
* **EXPERT USE ONLY**
|
||||
*
|
||||
* Override writer map used for the connection.
|
||||
*/
|
||||
writerMap?: TlWriterMap
|
||||
}
|
287
packages/core/src/highlevel/base.ts
Normal file
287
packages/core/src/highlevel/base.ts
Normal file
|
@ -0,0 +1,287 @@
|
|||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { MtClient, MtClientOptions } from '../network/client.js'
|
||||
import { ConnectionKind, RpcCallOptions } from '../network/network-manager.js'
|
||||
import { StorageManagerExtraOptions } from '../storage/storage.js'
|
||||
import { MtArgumentError } from '../types/errors.js'
|
||||
import { MustEqual } from '../types/utils.js'
|
||||
import { asyncResettable, computeNewPasswordHash, computeSrpParams, readStringSession, StringSessionData, writeStringSession } from '../utils/index.js'
|
||||
import { LogManager } from '../utils/logger.js'
|
||||
import { ITelegramClient } from './client.types.js'
|
||||
import { ITelegramStorageProvider } from './storage/provider.js'
|
||||
import { TelegramStorageManager, TelegramStorageManagerExtraOptions } from './storage/storage.js'
|
||||
import { UpdatesManager } from './updates/manager.js'
|
||||
import { RawUpdateHandler, UpdatesManagerParams } from './updates/types.js'
|
||||
|
||||
export interface BaseTelegramClientOptions extends MtClientOptions {
|
||||
storage: ITelegramStorageProvider
|
||||
storageOptions?: StorageManagerExtraOptions & TelegramStorageManagerExtraOptions
|
||||
updates?: UpdatesManagerParams | false
|
||||
}
|
||||
|
||||
export class BaseTelegramClient implements ITelegramClient {
|
||||
readonly updates?: UpdatesManager
|
||||
private _serverUpdatesHandler: (updates: tl.TypeUpdates) => void = () => {}
|
||||
|
||||
constructor(readonly params: BaseTelegramClientOptions) {
|
||||
if (!params.disableUpdates && params.updates !== false) {
|
||||
this.updates = new UpdatesManager(this, params.updates)
|
||||
this._serverUpdatesHandler = this.updates.handleUpdate.bind(this.updates)
|
||||
}
|
||||
|
||||
this.mt.on('update', (update) => {
|
||||
this._serverUpdatesHandler(update)
|
||||
})
|
||||
}
|
||||
|
||||
readonly log = this.params.logger ?? new LogManager('client')
|
||||
readonly mt = new MtClient({
|
||||
...this.params,
|
||||
logger: this.log.create('mtproto'),
|
||||
})
|
||||
readonly crypto = this.mt.crypto
|
||||
readonly storage = new TelegramStorageManager(this.mt.storage, {
|
||||
provider: this.params.storage,
|
||||
...this.params.storageOptions,
|
||||
})
|
||||
|
||||
private _prepare = asyncResettable(async () => {
|
||||
await this.mt.prepare()
|
||||
|
||||
const self = await this.storage.self.fetch()
|
||||
this.log.prefix = `[USER ${self?.userId ?? 'n/a'}] `
|
||||
this.mt.network.setIsPremium(self?.isPremium ?? false)
|
||||
|
||||
await this.updates?.prepare()
|
||||
})
|
||||
|
||||
/**
|
||||
* **ADVANCED**
|
||||
*
|
||||
* Do all the preparations, but don't connect just yet.
|
||||
* Useful when you want to do some preparations before
|
||||
* connecting, like setting up session.
|
||||
*
|
||||
* Call {@link connect} to actually connect.
|
||||
*/
|
||||
prepare() {
|
||||
return this._prepare.run()
|
||||
}
|
||||
|
||||
// used in a hot path, avoid extra function calls
|
||||
private _connected = false
|
||||
private _connect = asyncResettable(async () => {
|
||||
await this._prepare.run()
|
||||
await this.mt.connect()
|
||||
this._connected = true
|
||||
})
|
||||
|
||||
/**
|
||||
* Initialize the connection to the primary DC.
|
||||
*
|
||||
* You shouldn't usually call this method directly as it is called
|
||||
* implicitly the first time you call {@link call}.
|
||||
*/
|
||||
async connect(): Promise<void> {
|
||||
return this._connect.run()
|
||||
}
|
||||
|
||||
get isConnected(): boolean {
|
||||
return this._connected
|
||||
}
|
||||
|
||||
async close(): Promise<void> {
|
||||
await this.mt.close()
|
||||
this.updates?.stopLoop()
|
||||
this._prepare.reset()
|
||||
this._connect.reset()
|
||||
this._connected = false
|
||||
}
|
||||
|
||||
async notifyLoggedIn(auth: tl.auth.TypeAuthorization | tl.RawUser): Promise<tl.RawUser> {
|
||||
const user = this.mt.network.notifyLoggedIn(auth)
|
||||
|
||||
this.log.prefix = `[USER ${user.id}] `
|
||||
const self = await this.storage.self.storeFrom(user)
|
||||
|
||||
this.updates?.notifyLoggedIn(self)
|
||||
|
||||
return user
|
||||
}
|
||||
|
||||
async notifyLoggedOut(): Promise<void> {
|
||||
this.mt.network.notifyLoggedOut()
|
||||
|
||||
this.log.prefix = '[USER n/a] '
|
||||
await this.storage.self.store(null)
|
||||
}
|
||||
|
||||
async notifyChannelOpened(channelId: number, pts?: number): Promise<boolean> {
|
||||
return this.updates?.notifyChannelOpened(channelId, pts) ?? false
|
||||
}
|
||||
|
||||
async notifyChannelClosed(channelId: number): Promise<boolean> {
|
||||
return this.updates?.notifyChannelClosed(channelId) ?? false
|
||||
}
|
||||
|
||||
/**
|
||||
* Make an RPC call
|
||||
*
|
||||
* This method is still quite low-level and you shouldn't use this
|
||||
* when using high-level API provided by `@mtcute/client`.
|
||||
*
|
||||
* @param message RPC method to call
|
||||
* @param params Additional call parameters
|
||||
*/
|
||||
async call<T extends tl.RpcMethod>(
|
||||
message: MustEqual<T, tl.RpcMethod>,
|
||||
params?: RpcCallOptions,
|
||||
): Promise<tl.RpcCallReturn[T['_']]> {
|
||||
if (!this._connected) {
|
||||
await this._connect.run()
|
||||
}
|
||||
|
||||
const res = await this.mt.call(message, params)
|
||||
|
||||
await this.storage.peers.updatePeersFrom(res)
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
||||
return res
|
||||
}
|
||||
|
||||
/**
|
||||
* Import the session from the given session string.
|
||||
*
|
||||
* Note that the session will only be imported in case
|
||||
* the storage is missing authorization (i.e. does not contain
|
||||
* auth key for the primary DC), otherwise it will be ignored (unless `force`).
|
||||
*
|
||||
* @param session Session string to import
|
||||
* @param force Whether to overwrite existing session
|
||||
*/
|
||||
async importSession(session: string | StringSessionData, force = false): Promise<void> {
|
||||
await this.prepare()
|
||||
|
||||
const defaultDcAuthKey = await this.mt.storage.provider.authKeys.get(this.mt._defaultDcs.main.id)
|
||||
|
||||
if (defaultDcAuthKey && !force) return
|
||||
|
||||
const data = typeof session === 'string' ? readStringSession(this.mt._readerMap, session) : session
|
||||
|
||||
if (data.testMode && !this.params.testMode) {
|
||||
throw new Error(
|
||||
'This session string is not for the current backend. ' +
|
||||
`Session is ${data.testMode ? 'test' : 'prod'}, ` +
|
||||
`but the client is ${this.params.testMode ? 'test' : 'prod'}`,
|
||||
)
|
||||
}
|
||||
|
||||
this.mt._defaultDcs = data.primaryDcs
|
||||
await this.mt.storage.dcs.store(data.primaryDcs)
|
||||
|
||||
if (data.self) {
|
||||
await this.storage.self.store(data.self)
|
||||
}
|
||||
|
||||
await this.mt.storage.provider.authKeys.set(data.primaryDcs.main.id, data.authKey)
|
||||
|
||||
await this.mt.storage.save()
|
||||
}
|
||||
|
||||
/**
|
||||
* Export current session to a single *LONG* string, containing
|
||||
* all the needed information.
|
||||
*
|
||||
* > **Warning!** Anyone with this string will be able
|
||||
* > to authorize as you and do anything. Treat this
|
||||
* > as your password, and never give it away!
|
||||
* >
|
||||
* > In case you have accidentally leaked this string,
|
||||
* > make sure to revoke this session in account settings:
|
||||
* > "Privacy & Security" > "Active sessions" >
|
||||
* > find the one containing `mtcute` > Revoke,
|
||||
* > or, in case this is a bot, revoke bot token
|
||||
* > with [@BotFather](//t.me/botfather)
|
||||
*/
|
||||
async exportSession(): Promise<string> {
|
||||
await this._prepare.run()
|
||||
|
||||
const primaryDcs = (await this.mt.storage.dcs.fetch()) ?? this.mt._defaultDcs
|
||||
|
||||
const authKey = await this.mt.storage.provider.authKeys.get(primaryDcs.main.id)
|
||||
if (!authKey) throw new Error('Auth key is not ready yet')
|
||||
|
||||
return writeStringSession(this.mt._writerMap, {
|
||||
version: 2,
|
||||
self: await this.storage.self.fetch(),
|
||||
testMode: Boolean(this.params.testMode),
|
||||
primaryDcs,
|
||||
authKey,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an error handler for the client
|
||||
*
|
||||
* @param handler Error handler.
|
||||
*/
|
||||
onError(handler: (err: unknown) => void): void {
|
||||
this.mt.onError(handler)
|
||||
}
|
||||
|
||||
emitError(err: unknown): void {
|
||||
this.mt.emitError(err)
|
||||
}
|
||||
|
||||
handleClientUpdate(updates: tl.TypeUpdates, noDispatch?: boolean): void {
|
||||
this.updates?.handleClientUpdate(updates, noDispatch)
|
||||
}
|
||||
|
||||
onServerUpdate(handler: (update: tl.TypeUpdates) => void): void {
|
||||
this._serverUpdatesHandler = handler
|
||||
}
|
||||
|
||||
onUpdate(handler: RawUpdateHandler): void {
|
||||
if (!this.updates) {
|
||||
throw new MtArgumentError('Updates manager is disabled')
|
||||
}
|
||||
|
||||
this.updates.setHandler(handler)
|
||||
}
|
||||
|
||||
async getApiCrenetials() {
|
||||
return {
|
||||
id: this.params.apiId,
|
||||
hash: this.params.apiHash,
|
||||
}
|
||||
}
|
||||
|
||||
async getPoolSize(kind: ConnectionKind, dcId?: number): Promise<number> {
|
||||
if (!this._connected) {
|
||||
await this._connect.run()
|
||||
}
|
||||
|
||||
return this.mt.network.getPoolSize(kind, dcId)
|
||||
}
|
||||
|
||||
async getPrimaryDcId(): Promise<number> {
|
||||
if (!this._connected) {
|
||||
await this._connect.run()
|
||||
}
|
||||
|
||||
return this.mt.network.getPrimaryDcId()
|
||||
}
|
||||
|
||||
computeSrpParams(
|
||||
request: tl.account.RawPassword,
|
||||
password: string,
|
||||
): Promise<tl.RawInputCheckPasswordSRP> {
|
||||
return computeSrpParams(this.crypto, request, password)
|
||||
}
|
||||
computeNewPasswordHash(
|
||||
algo: tl.TypePasswordKdfAlgo,
|
||||
password: string,
|
||||
): Promise<Uint8Array> {
|
||||
return computeNewPasswordHash(this.crypto, algo, password)
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
53
packages/core/src/highlevel/client.types.ts
Normal file
53
packages/core/src/highlevel/client.types.ts
Normal file
|
@ -0,0 +1,53 @@
|
|||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import type { ConnectionKind, RpcCallOptions } from '../network/index.js'
|
||||
import type { MustEqual, PublicPart } from '../types/utils.js'
|
||||
import type { Logger } from '../utils/logger.js'
|
||||
import type { StringSessionData } from '../utils/string-session.js'
|
||||
import type { TelegramStorageManager } from './storage/storage.js'
|
||||
import type { RawUpdateHandler } from './updates/types.js'
|
||||
|
||||
// NB: when adding new methods, don't forget to add them to:
|
||||
// - worker/port.ts
|
||||
// - generate-client script
|
||||
|
||||
export interface ITelegramClient {
|
||||
readonly log: Logger
|
||||
readonly storage: PublicPart<TelegramStorageManager>
|
||||
|
||||
prepare(): Promise<void>
|
||||
connect(): Promise<void>
|
||||
close(): Promise<void>
|
||||
notifyLoggedIn(auth: tl.auth.TypeAuthorization | tl.RawUser): Promise<tl.RawUser>
|
||||
notifyLoggedOut(): Promise<void>
|
||||
notifyChannelOpened(channelId: number, pts?: number): Promise<boolean>
|
||||
notifyChannelClosed(channelId: number): Promise<boolean>
|
||||
call<T extends tl.RpcMethod>(
|
||||
message: MustEqual<T, tl.RpcMethod>,
|
||||
params?: RpcCallOptions,
|
||||
): Promise<tl.RpcCallReturn[T['_']]>
|
||||
importSession(session: string | StringSessionData, force?: boolean): Promise<void>
|
||||
exportSession(): Promise<string>
|
||||
onError(handler: (err: unknown) => void): void
|
||||
emitError(err: unknown): void
|
||||
handleClientUpdate(updates: tl.TypeUpdates, noDispatch?: boolean): void
|
||||
|
||||
onServerUpdate(handler: (update: tl.TypeUpdates) => void): void
|
||||
onUpdate(handler: RawUpdateHandler): void
|
||||
|
||||
getApiCrenetials(): Promise<{ id: number; hash: string }>
|
||||
// todo - this is only used for file dl/ul, which should probably be moved
|
||||
// to the client to allow moving the thing to worker
|
||||
// or at least load this once at startup (and then these methods can be made sync)
|
||||
getPoolSize(kind: ConnectionKind, dcId?: number): Promise<number>
|
||||
getPrimaryDcId(): Promise<number>
|
||||
|
||||
computeSrpParams(
|
||||
request: tl.account.RawPassword,
|
||||
password: string,
|
||||
): Promise<tl.RawInputCheckPasswordSRP>
|
||||
computeNewPasswordHash(
|
||||
algo: tl.TypePasswordKdfAlgo,
|
||||
password: string,
|
||||
): Promise<Uint8Array>
|
||||
}
|
6
packages/core/src/highlevel/index.ts
Normal file
6
packages/core/src/highlevel/index.ts
Normal file
|
@ -0,0 +1,6 @@
|
|||
export * from './base.js'
|
||||
export * from './client.js'
|
||||
export * from './client.types.js'
|
||||
export * from './storage/index.js'
|
||||
export * from './types/index.js'
|
||||
export * from './updates/index.js'
|
|
@ -57,7 +57,7 @@ Example:
|
|||
|
||||
```typescript
|
||||
// @initialize
|
||||
function _initializeAwesomeExtension(client: BaseTelegramClient) {
|
||||
function _initializeAwesomeExtension(client: ITelegramClient) {
|
||||
this._field1 = 42
|
||||
this._field2 = 'uwu'
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ Example:
|
|||
// @exported
|
||||
export type FooOrBar = Foo | Bar
|
||||
|
||||
export function getFooOrBar(client: BaseTelegramClient): FooOrBar {
|
||||
export function getFooOrBar(client: ITelegramClient): FooOrBar {
|
||||
return new Foo()
|
||||
}
|
||||
```
|
|
@ -1,19 +1,18 @@
|
|||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
// @copy
|
||||
import {
|
||||
BaseTelegramClient,
|
||||
BaseTelegramClientOptions,
|
||||
IMtStorageProvider,
|
||||
Long,
|
||||
MaybeArray,
|
||||
MaybeAsync,
|
||||
PartialExcept,
|
||||
PartialOnly,
|
||||
tl,
|
||||
} from '@mtcute/core'
|
||||
|
||||
// @copy
|
||||
import { tdFileId } from '@mtcute/file-id'
|
||||
// @copy
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
// @copy
|
||||
import { MaybeArray, MaybeAsync, PartialExcept, PartialOnly } from '../../types/index.js'
|
||||
// @copy
|
||||
import { StringSessionData } from '../../utils/string-session.js'
|
||||
// @copy
|
||||
import { BaseTelegramClient, BaseTelegramClientOptions } from '../base.js'
|
||||
// @copy
|
||||
import { ITelegramClient } from '../client.types.js'
|
||||
// @copy
|
||||
import {
|
||||
AllStories,
|
97
packages/core/src/highlevel/methods/_init.ts
Normal file
97
packages/core/src/highlevel/methods/_init.ts
Normal file
|
@ -0,0 +1,97 @@
|
|||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
|
||||
// @copy
|
||||
import { MemoryStorage } from '../../storage/providers/memory/index.js'
|
||||
import { BaseTelegramClient, BaseTelegramClientOptions } from '../base.js'
|
||||
import { TelegramClient } from '../client.js'
|
||||
import { ITelegramClient } from '../client.types.js'
|
||||
// @copy
|
||||
import { ITelegramStorageProvider } from '../storage/provider.js'
|
||||
// @copy
|
||||
import { Conversation } from '../types/conversation.js'
|
||||
// @copy
|
||||
import { makeParsedUpdateHandler, ParsedUpdateHandlerParams } from '../updates/parsed.js'
|
||||
// @copy
|
||||
import { _defaultStorageFactory } from '../utils/platform/storage.js'
|
||||
|
||||
// @copy
|
||||
type TelegramClientOptions = ((Omit<BaseTelegramClientOptions, 'storage'> & {
|
||||
/**
|
||||
* Storage to use for this client.
|
||||
*
|
||||
* If a string is passed, it will be used as:
|
||||
* - a path to a JSON file for Node.js
|
||||
* - IndexedDB database name for browsers
|
||||
*
|
||||
* If omitted, {@link MemoryStorage} is used
|
||||
*/
|
||||
storage?: string | ITelegramStorageProvider
|
||||
}) | ({ client: ITelegramClient })) & {
|
||||
updates?: Omit<ParsedUpdateHandlerParams, 'onUpdate'>
|
||||
/**
|
||||
* If `true`, the updates that were handled by some {@link Conversation}
|
||||
* will not be dispatched any further.
|
||||
*
|
||||
* @default true
|
||||
*/
|
||||
skipConversationUpdates?: boolean
|
||||
}
|
||||
|
||||
// // @initialize=super
|
||||
// /** @internal */
|
||||
// function _initializeClientSuper(this: TelegramClient, opts: TelegramClientOptions) {
|
||||
// if (typeof opts.storage === 'string') {
|
||||
// opts.storage = _defaultStorageFactory(opts.storage)
|
||||
// } else if (!opts.storage) {
|
||||
// opts.storage = new MemoryStorage()
|
||||
// }
|
||||
|
||||
// /* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||
// // @ts-expect-error codegen
|
||||
// super(opts)
|
||||
// /* eslint-enable @typescript-eslint/no-unsafe-call */
|
||||
// }
|
||||
|
||||
// @initialize
|
||||
/** @internal */
|
||||
function _initializeClient(this: TelegramClient, opts: TelegramClientOptions) {
|
||||
if ('client' in opts) {
|
||||
this._client = opts.client
|
||||
} else {
|
||||
let storage: ITelegramStorageProvider
|
||||
|
||||
if (typeof opts.storage === 'string') {
|
||||
storage = _defaultStorageFactory(opts.storage)
|
||||
} else if (!opts.storage) {
|
||||
storage = new MemoryStorage()
|
||||
} else {
|
||||
storage = opts.storage
|
||||
}
|
||||
|
||||
this._client = new BaseTelegramClient({
|
||||
...opts,
|
||||
storage,
|
||||
})
|
||||
}
|
||||
|
||||
// @ts-expect-error codegen
|
||||
this.log = this._client.log
|
||||
// @ts-expect-error codegen
|
||||
this.storage = this._client.storage
|
||||
|
||||
const skipConversationUpdates = opts.skipConversationUpdates ?? true
|
||||
const { messageGroupingInterval } = opts.updates ?? {}
|
||||
|
||||
this._client.onUpdate(makeParsedUpdateHandler({
|
||||
messageGroupingInterval,
|
||||
onUpdate: (update) => {
|
||||
if (Conversation.handleUpdate(this._client, update) && skipConversationUpdates) return
|
||||
|
||||
this.emit('update', update)
|
||||
this.emit(update.name, update.data)
|
||||
},
|
||||
onRawUpdate: (update, peers) => {
|
||||
this.emit('raw_update', update, peers)
|
||||
},
|
||||
}))
|
||||
}
|
|
@ -1,8 +1,6 @@
|
|||
import { BaseTelegramClient } from '@mtcute/core'
|
||||
import { computeSrpParams } from '@mtcute/core/utils.js'
|
||||
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { User } from '../../types/index.js'
|
||||
import { _onAuthorization } from './_state.js'
|
||||
import { _onAuthorization } from './utils.js'
|
||||
|
||||
/**
|
||||
* Check your Two-Step verification password and log in
|
||||
|
@ -11,11 +9,10 @@ import { _onAuthorization } from './_state.js'
|
|||
* @returns The authorized user
|
||||
* @throws BadRequestError In case the password is invalid
|
||||
*/
|
||||
export async function checkPassword(client: BaseTelegramClient, password: string): Promise<User> {
|
||||
export async function checkPassword(client: ITelegramClient, password: string): Promise<User> {
|
||||
const res = await client.call({
|
||||
_: 'auth.checkPassword',
|
||||
password: await computeSrpParams(
|
||||
client.crypto,
|
||||
password: await client.computeSrpParams(
|
||||
await client.call({
|
||||
_: 'account.getPassword',
|
||||
}),
|
|
@ -1,11 +1,11 @@
|
|||
import { BaseTelegramClient } from '@mtcute/core'
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
|
||||
/**
|
||||
* Get your Two-Step Verification password hint.
|
||||
*
|
||||
* @returns The password hint as a string, if any
|
||||
*/
|
||||
export function getPasswordHint(client: BaseTelegramClient): Promise<string | null> {
|
||||
export function getPasswordHint(client: ITelegramClient): Promise<string | null> {
|
||||
return client
|
||||
.call({
|
||||
_: 'account.getPassword',
|
|
@ -1,4 +1,4 @@
|
|||
import { BaseTelegramClient } from '@mtcute/core'
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
|
||||
/**
|
||||
* Log out from Telegram account and optionally reset the session storage.
|
||||
|
@ -8,15 +8,9 @@ import { BaseTelegramClient } from '@mtcute/core'
|
|||
*
|
||||
* @returns On success, `true` is returned
|
||||
*/
|
||||
export async function logOut(client: BaseTelegramClient): Promise<true> {
|
||||
export async function logOut(client: ITelegramClient): Promise<true> {
|
||||
await client.call({ _: 'auth.logOut' })
|
||||
|
||||
await client.storage.self.store(null)
|
||||
// authState.selfUsername = null todo
|
||||
|
||||
client.emit('logged_out')
|
||||
|
||||
await client.storage.clear()
|
||||
await client.notifyLoggedOut()
|
||||
|
||||
return true
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
import { BaseTelegramClient } from '@mtcute/core'
|
||||
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { User } from '../../types/index.js'
|
||||
import { _onAuthorization } from './_state.js'
|
||||
import { _onAuthorization } from './utils.js'
|
||||
|
||||
/**
|
||||
* Recover your password with a recovery code and log in.
|
||||
|
@ -10,7 +9,7 @@ import { _onAuthorization } from './_state.js'
|
|||
* @throws BadRequestError In case the code is invalid
|
||||
*/
|
||||
export async function recoverPassword(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
params: {
|
||||
/** The recovery code sent via email */
|
||||
recoveryCode: string
|
|
@ -1,7 +1,6 @@
|
|||
import { BaseTelegramClient } from '@mtcute/core'
|
||||
import { assertTypeIs } from '@mtcute/core/utils.js'
|
||||
|
||||
import { SentCode } from '../../types/index.js'
|
||||
import { assertTypeIs } from '../../../utils/type-assertions.js'
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { SentCode } from '../../types/auth/sent-code.js'
|
||||
import { normalizePhoneNumber } from '../../utils/misc-utils.js'
|
||||
|
||||
/**
|
||||
|
@ -11,7 +10,7 @@ import { normalizePhoneNumber } from '../../utils/misc-utils.js'
|
|||
* {@link SentCode} object returned by {@link sendCode}
|
||||
*/
|
||||
export async function resendCode(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
params: {
|
||||
/** Phone number in international format */
|
||||
phone: string
|
|
@ -1,6 +1,4 @@
|
|||
import { BaseTelegramClient } from '@mtcute/core'
|
||||
|
||||
import { TelegramClient } from '../../index.js'
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { User } from '../../types/index.js'
|
||||
import { start } from './start.js'
|
||||
|
||||
|
@ -14,22 +12,13 @@ import { start } from './start.js'
|
|||
*
|
||||
* @param params Parameters to be passed to {@link start}
|
||||
* @param then Function to be called after {@link start} returns
|
||||
* @manual=noemit
|
||||
*/
|
||||
export function run(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
params: Parameters<typeof start>[1],
|
||||
then?: (user: User) => void | Promise<void>,
|
||||
): void {
|
||||
start(client, params)
|
||||
.then(then)
|
||||
.catch((err) => client._emitError(err))
|
||||
}
|
||||
|
||||
// @manual-impl=run
|
||||
/** @internal */
|
||||
function _run(this: TelegramClient, params: Parameters<typeof start>[1], then?: (user: User) => void | Promise<void>) {
|
||||
this.start(params)
|
||||
.then(then)
|
||||
.catch((err) => this._emitError(err))
|
||||
.catch((err) => client.emitError(err))
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
import { BaseTelegramClient } from '@mtcute/core'
|
||||
import { assertTypeIs } from '@mtcute/core/utils.js'
|
||||
|
||||
import { SentCode } from '../../types/index.js'
|
||||
import { assertTypeIs } from '../../../utils/type-assertions.js'
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { SentCode } from '../../types/auth/sent-code.js'
|
||||
import { normalizePhoneNumber } from '../../utils/misc-utils.js'
|
||||
|
||||
/**
|
||||
|
@ -10,7 +9,7 @@ import { normalizePhoneNumber } from '../../utils/misc-utils.js'
|
|||
* @returns An object containing information about the sent confirmation code
|
||||
*/
|
||||
export async function sendCode(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
params: {
|
||||
/** Phone number in international format */
|
||||
phone: string
|
||||
|
@ -18,11 +17,13 @@ export async function sendCode(
|
|||
): Promise<SentCode> {
|
||||
const phone = normalizePhoneNumber(params.phone)
|
||||
|
||||
const { id, hash } = await client.getApiCrenetials()
|
||||
|
||||
const res = await client.call({
|
||||
_: 'auth.sendCode',
|
||||
phoneNumber: phone,
|
||||
apiId: client.params.apiId,
|
||||
apiHash: client.params.apiHash,
|
||||
apiId: id,
|
||||
apiHash: hash,
|
||||
settings: { _: 'codeSettings' },
|
||||
})
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
import { BaseTelegramClient } from '@mtcute/core'
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
|
||||
/**
|
||||
* Send a code to email needed to recover your password
|
||||
*
|
||||
* @returns String containing email pattern to which the recovery code was sent
|
||||
*/
|
||||
export function sendRecoveryCode(client: BaseTelegramClient): Promise<string> {
|
||||
export function sendRecoveryCode(client: ITelegramClient): Promise<string> {
|
||||
return client
|
||||
.call({
|
||||
_: 'auth.requestPasswordRecovery',
|
|
@ -1,7 +1,6 @@
|
|||
import { BaseTelegramClient } from '@mtcute/core'
|
||||
|
||||
import { User } from '../../types/index.js'
|
||||
import { _onAuthorization } from './_state.js'
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { User } from '../../types/peers/user.js'
|
||||
import { _onAuthorization } from './utils.js'
|
||||
|
||||
/**
|
||||
* Authorize a bot using its token issued by [@BotFather](//t.me/BotFather)
|
||||
|
@ -10,12 +9,14 @@ import { _onAuthorization } from './_state.js'
|
|||
* @returns Bot's {@link User} object
|
||||
* @throws BadRequestError In case the bot token is invalid
|
||||
*/
|
||||
export async function signInBot(client: BaseTelegramClient, token: string): Promise<User> {
|
||||
export async function signInBot(client: ITelegramClient, token: string): Promise<User> {
|
||||
const { id, hash } = await client.getApiCrenetials()
|
||||
|
||||
const res = await client.call({
|
||||
_: 'auth.importBotAuthorization',
|
||||
flags: 0,
|
||||
apiId: client.params.apiId,
|
||||
apiHash: client.params.apiHash,
|
||||
apiId: id,
|
||||
apiHash: hash,
|
||||
botAuthToken: token,
|
||||
})
|
||||
|
|
@ -1,8 +1,7 @@
|
|||
import { BaseTelegramClient } from '@mtcute/core'
|
||||
|
||||
import { User } from '../../types/index.js'
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { User } from '../../types/peers/user.js'
|
||||
import { normalizePhoneNumber } from '../../utils/misc-utils.js'
|
||||
import { _onAuthorization } from './_state.js'
|
||||
import { _onAuthorization } from './utils.js'
|
||||
|
||||
/**
|
||||
* Authorize a user in Telegram with a valid confirmation code.
|
||||
|
@ -12,7 +11,7 @@ import { _onAuthorization } from './_state.js'
|
|||
* @throws SessionPasswordNeededError In case a password is needed to sign in
|
||||
*/
|
||||
export async function signIn(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
params: {
|
||||
/** Phone number in international format */
|
||||
phone: string
|
|
@ -1,5 +1,5 @@
|
|||
import { BaseTelegramClient, MtArgumentError } from '@mtcute/core'
|
||||
|
||||
import { MtArgumentError } from '../../../types/errors.js'
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { User } from '../../types/index.js'
|
||||
import { logOut } from './log-out.js'
|
||||
import { start } from './start.js'
|
||||
|
@ -15,7 +15,7 @@ import { start } from './start.js'
|
|||
* @param params Additional parameters
|
||||
*/
|
||||
export async function startTest(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
params?: {
|
||||
/**
|
||||
* Whether to log out if current session is logged in.
|
||||
|
@ -63,7 +63,7 @@ export async function startTest(
|
|||
throw new MtArgumentError(`${phone} has invalid DC ID (${id})`)
|
||||
}
|
||||
} else {
|
||||
let dcId = client.network.getPrimaryDcId()
|
||||
let dcId = await client.getPrimaryDcId()
|
||||
|
||||
if (params.dcId) {
|
||||
if (!availableDcs.find((dc) => dc.id === params!.dcId)) {
|
|
@ -1,8 +1,13 @@
|
|||
/* eslint-disable no-console */
|
||||
import { BaseTelegramClient, MaybeAsync, MtArgumentError, tl } from '@mtcute/core'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import type { TelegramClient } from '../../client.js'
|
||||
import { MaybeDynamic, SentCode, User } from '../../types/index.js'
|
||||
import { MtArgumentError } from '../../../types/errors.js'
|
||||
import { MaybeAsync } from '../../../types/utils.js'
|
||||
import { StringSessionData } from '../../../utils/string-session.js'
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { SentCode } from '../../types/auth/sent-code.js'
|
||||
import { User } from '../../types/peers/user.js'
|
||||
import { MaybeDynamic } from '../../types/utils.js'
|
||||
import { normalizePhoneNumber, resolveMaybeDynamic } from '../../utils/misc-utils.js'
|
||||
import { getMe } from '../users/get-me.js'
|
||||
import { checkPassword } from './check-password.js'
|
||||
|
@ -11,7 +16,6 @@ import { sendCode } from './send-code.js'
|
|||
import { signIn } from './sign-in.js'
|
||||
import { signInBot } from './sign-in-bot.js'
|
||||
|
||||
// @manual
|
||||
// @available=both
|
||||
/**
|
||||
* Start the client in an interactive and declarative manner,
|
||||
|
@ -27,7 +31,7 @@ import { signInBot } from './sign-in-bot.js'
|
|||
* you'll probably need to use other auth methods.
|
||||
*/
|
||||
export async function start(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
params: {
|
||||
/**
|
||||
* String session exported using {@link TelegramClient.exportSession}.
|
||||
|
@ -37,7 +41,7 @@ export async function start(
|
|||
* Note that passed session will be ignored in case storage already
|
||||
* contains authorization.
|
||||
*/
|
||||
session?: string
|
||||
session?: string | StringSessionData
|
||||
|
||||
/**
|
||||
* Whether to overwrite existing session.
|
||||
|
@ -93,7 +97,7 @@ export async function start(
|
|||
},
|
||||
): Promise<User> {
|
||||
if (params.session) {
|
||||
client.importSession(params.session, params.sessionForce)
|
||||
await client.importSession(params.session, params.sessionForce)
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -103,7 +107,7 @@ export async function start(
|
|||
|
||||
client.log.info('Logged in as %s (ID: %s, username: %s, bot: %s)', me.displayName, me.id, me.username, me.isBot)
|
||||
|
||||
client.network.setIsPremium(me.isPremium)
|
||||
await client.notifyLoggedIn(me.raw)
|
||||
|
||||
return me
|
||||
} catch (e) {
|
||||
|
@ -211,15 +215,3 @@ export async function start(
|
|||
|
||||
throw new MtArgumentError('Failed to log in with provided credentials')
|
||||
}
|
||||
|
||||
// @manual-impl=start
|
||||
/** @internal */
|
||||
async function _start(this: TelegramClient, params: Parameters<typeof start>[1]) {
|
||||
const user = await start(this, params)
|
||||
|
||||
if (!this.network.params.disableUpdates && !this._disableUpdatesManager) {
|
||||
await this.startUpdatesLoop()
|
||||
}
|
||||
|
||||
return user
|
||||
}
|
39
packages/core/src/highlevel/methods/auth/utils.ts
Normal file
39
packages/core/src/highlevel/methods/auth/utils.ts
Normal file
|
@ -0,0 +1,39 @@
|
|||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { User } from '../../types/peers/user.js'
|
||||
|
||||
/** @internal */
|
||||
export async function _onAuthorization(
|
||||
client: ITelegramClient,
|
||||
auth: tl.auth.TypeAuthorization,
|
||||
): Promise<User> {
|
||||
const user = await client.notifyLoggedIn(auth)
|
||||
|
||||
return new User(user)
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given peer/input peer is referring to the current user
|
||||
*/
|
||||
export function isSelfPeer(
|
||||
client: ITelegramClient,
|
||||
peer: tl.TypeInputPeer | tl.TypePeer | tl.TypeInputUser,
|
||||
): boolean {
|
||||
const state = client.storage.self.getCached()
|
||||
if (!state) return false
|
||||
|
||||
switch (peer._) {
|
||||
case 'inputPeerSelf':
|
||||
case 'inputUserSelf':
|
||||
return true
|
||||
case 'inputPeerUser':
|
||||
case 'inputPeerUserFromMessage':
|
||||
case 'inputUser':
|
||||
case 'inputUserFromMessage':
|
||||
case 'peerUser':
|
||||
return peer.userId === state.userId
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
import { BaseTelegramClient, Long } from '@mtcute/core'
|
||||
import { assertTrue } from '@mtcute/core/utils.js'
|
||||
import Long from 'long'
|
||||
|
||||
import { assertTrue } from '../../../utils/type-assertions.js'
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { CallbackQuery } from '../../types/updates/callback-query.js'
|
||||
|
||||
/**
|
||||
|
@ -10,7 +11,7 @@ import { CallbackQuery } from '../../types/updates/callback-query.js'
|
|||
* @param params Parameters of the answer
|
||||
*/
|
||||
export async function answerCallbackQuery(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
queryId: Long | CallbackQuery,
|
||||
params?: {
|
||||
/**
|
|
@ -1,5 +1,8 @@
|
|||
import { BaseTelegramClient, Long, tl } from '@mtcute/core'
|
||||
import Long from 'long'
|
||||
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { BotInline, InputInlineResult } from '../../types/bots/index.js'
|
||||
import { InlineQuery } from '../../types/updates/inline-query.js'
|
||||
|
||||
|
@ -11,7 +14,7 @@ import { InlineQuery } from '../../types/updates/inline-query.js'
|
|||
* @param params Additional parameters
|
||||
*/
|
||||
export async function answerInlineQuery(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
queryId: tl.Long | InlineQuery,
|
||||
results: InputInlineResult[],
|
||||
params?: {
|
|
@ -1,6 +1,9 @@
|
|||
import { BaseTelegramClient, Long, tl } from '@mtcute/core'
|
||||
import { assertTrue } from '@mtcute/core/utils.js'
|
||||
import Long from 'long'
|
||||
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { assertTrue } from '../../../utils/type-assertions.js'
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import type { PreCheckoutQuery } from '../../types/updates/pre-checkout-query.js'
|
||||
|
||||
/**
|
||||
|
@ -9,7 +12,7 @@ import type { PreCheckoutQuery } from '../../types/updates/pre-checkout-query.js
|
|||
* @param queryId Pre-checkout query ID
|
||||
*/
|
||||
export async function answerPreCheckoutQuery(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
queryId: tl.Long | PreCheckoutQuery,
|
||||
params?: {
|
||||
/** If pre-checkout is rejected, error message to show to the user */
|
|
@ -1,5 +1,6 @@
|
|||
import { BaseTelegramClient, tl } from '@mtcute/core'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { BotCommands } from '../../types/index.js'
|
||||
import { _normalizeCommandScope } from './normalize-command-scope.js'
|
||||
|
||||
|
@ -11,7 +12,7 @@ import { _normalizeCommandScope } from './normalize-command-scope.js'
|
|||
* Learn more about scopes in the [Bot API docs](https://core.telegram.org/bots/api#botcommandscope)
|
||||
*/
|
||||
export async function deleteMyCommands(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
params?: {
|
||||
/**
|
||||
* Scope of the commands.
|
|
@ -1,5 +1,6 @@
|
|||
import { BaseTelegramClient, tl } from '@mtcute/core'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { InputPeerLike } from '../../types/index.js'
|
||||
import { toInputUser } from '../../utils/peer-utils.js'
|
||||
import { resolvePeer } from '../users/resolve-peer.js'
|
||||
|
@ -8,7 +9,7 @@ import { resolvePeer } from '../users/resolve-peer.js'
|
|||
* Gets information about a bot the current uzer owns (or the current bot)
|
||||
*/
|
||||
export async function getBotInfo(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
params: {
|
||||
/**
|
||||
* When called by a user, a bot the user owns must be specified.
|
|
@ -1,5 +1,6 @@
|
|||
import { BaseTelegramClient, tl } from '@mtcute/core'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { InputPeerLike } from '../../types/index.js'
|
||||
import { toInputUser } from '../../utils/peer-utils.js'
|
||||
import { resolvePeer } from '../users/resolve-peer.js'
|
||||
|
@ -7,7 +8,7 @@ import { resolvePeer } from '../users/resolve-peer.js'
|
|||
/**
|
||||
* Fetches the menu button set for the given user.
|
||||
*/
|
||||
export async function getBotMenuButton(client: BaseTelegramClient, user: InputPeerLike): Promise<tl.TypeBotMenuButton> {
|
||||
export async function getBotMenuButton(client: ITelegramClient, user: InputPeerLike): Promise<tl.TypeBotMenuButton> {
|
||||
return await client.call({
|
||||
_: 'bots.getBotMenuButton',
|
||||
userId: toInputUser(await resolvePeer(client, user), user),
|
|
@ -1,6 +1,7 @@
|
|||
import { BaseTelegramClient, tl } from '@mtcute/core'
|
||||
import { computeSrpParams, utf8EncodeToBuffer } from '@mtcute/core/utils.js'
|
||||
import { tl } from '@mtcute/tl'
|
||||
import { utf8EncodeToBuffer } from '@mtcute/tl-runtime'
|
||||
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { InputMessageId, normalizeInputMessageId } from '../../types/index.js'
|
||||
import { resolvePeer } from '../users/resolve-peer.js'
|
||||
|
||||
|
@ -11,7 +12,7 @@ import { resolvePeer } from '../users/resolve-peer.js'
|
|||
* @param params
|
||||
*/
|
||||
export async function getCallbackAnswer(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
params: InputMessageId & {
|
||||
/** Data contained in the button */
|
||||
data: string | Uint8Array
|
||||
|
@ -44,7 +45,7 @@ export async function getCallbackAnswer(
|
|||
|
||||
if (params?.password) {
|
||||
const pwd = await client.call({ _: 'account.getPassword' })
|
||||
password = await computeSrpParams(client.crypto, pwd, params.password)
|
||||
password = await client.computeSrpParams(pwd, params.password)
|
||||
}
|
||||
|
||||
return await client.call(
|
|
@ -1,5 +1,6 @@
|
|||
import { BaseTelegramClient, tl } from '@mtcute/core'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { GameHighScore, InputMessageId, InputPeerLike, normalizeInputMessageId, PeersIndex } from '../../types/index.js'
|
||||
import { normalizeInlineId } from '../../utils/inline-utils.js'
|
||||
import { toInputUser } from '../../utils/peer-utils.js'
|
||||
|
@ -9,7 +10,7 @@ import { resolvePeer } from '../users/resolve-peer.js'
|
|||
* Get high scores of a game
|
||||
*/
|
||||
export async function getGameHighScores(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
params: InputMessageId & {
|
||||
/** ID of the user to find high scores for */
|
||||
userId?: InputPeerLike
|
||||
|
@ -47,7 +48,7 @@ export async function getGameHighScores(
|
|||
* @param userId ID of the user to find high scores for
|
||||
*/
|
||||
export async function getInlineGameHighScores(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
messageId: string | tl.TypeInputBotInlineMessageID,
|
||||
userId?: InputPeerLike,
|
||||
): Promise<GameHighScore[]> {
|
|
@ -1,5 +1,6 @@
|
|||
import { BaseTelegramClient, tl } from '@mtcute/core'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { BotCommands } from '../../types/index.js'
|
||||
import { _normalizeCommandScope } from './normalize-command-scope.js'
|
||||
|
||||
|
@ -10,7 +11,7 @@ import { _normalizeCommandScope } from './normalize-command-scope.js'
|
|||
* Learn more about scopes in the [Bot API docs](https://core.telegram.org/bots/api#botcommandscope)
|
||||
*/
|
||||
export async function getMyCommands(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
params?: {
|
||||
/**
|
||||
* Scope of the commands.
|
|
@ -1,12 +1,14 @@
|
|||
import { assertNever, BaseTelegramClient, tl } from '@mtcute/core'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { assertNever } from '../../../types/utils.js'
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { BotCommands } from '../../types/index.js'
|
||||
import { toInputUser } from '../../utils/peer-utils.js'
|
||||
import { resolvePeer } from '../users/resolve-peer.js'
|
||||
|
||||
/** @internal */
|
||||
export async function _normalizeCommandScope(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
scope: tl.TypeBotCommandScope | BotCommands.IntermediateScope,
|
||||
): Promise<tl.TypeBotCommandScope> {
|
||||
if (tl.isAnyBotCommandScope(scope)) return scope
|
|
@ -1,6 +1,5 @@
|
|||
import { BaseTelegramClient } from '@mtcute/core'
|
||||
import { assertTrue } from '@mtcute/core/utils.js'
|
||||
|
||||
import { assertTrue } from '../../../utils/type-assertions.js'
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { InputPeerLike } from '../../types/index.js'
|
||||
import { toInputUser } from '../../utils/peer-utils.js'
|
||||
import { resolvePeer } from '../users/resolve-peer.js'
|
||||
|
@ -9,7 +8,7 @@ import { resolvePeer } from '../users/resolve-peer.js'
|
|||
* Sets information about a bot the current uzer owns (or the current bot)
|
||||
*/
|
||||
export async function setBotInfo(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
params: {
|
||||
/**
|
||||
* When called by a user, a bot the user owns must be specified.
|
|
@ -1,6 +1,7 @@
|
|||
import { BaseTelegramClient, tl } from '@mtcute/core'
|
||||
import { assertTrue } from '@mtcute/core/utils.js'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { assertTrue } from '../../../utils/type-assertions.js'
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { InputPeerLike } from '../../types/index.js'
|
||||
import { toInputUser } from '../../utils/peer-utils.js'
|
||||
import { resolvePeer } from '../users/resolve-peer.js'
|
||||
|
@ -9,7 +10,7 @@ import { resolvePeer } from '../users/resolve-peer.js'
|
|||
* Sets a menu button for the given user.
|
||||
*/
|
||||
export async function setBotMenuButton(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
user: InputPeerLike,
|
||||
button: tl.TypeBotMenuButton,
|
||||
): Promise<void> {
|
|
@ -1,6 +1,7 @@
|
|||
import { BaseTelegramClient, tl } from '@mtcute/core'
|
||||
import { assertTrue } from '@mtcute/core/utils.js'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { assertTrue } from '../../../utils/type-assertions.js'
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { InputMessageId, InputPeerLike, Message, normalizeInputMessageId } from '../../types/index.js'
|
||||
import { normalizeInlineId } from '../../utils/inline-utils.js'
|
||||
import { toInputUser } from '../../utils/peer-utils.js'
|
||||
|
@ -14,7 +15,7 @@ import { resolvePeer } from '../users/resolve-peer.js'
|
|||
* @returns The modified message
|
||||
*/
|
||||
export async function setGameScore(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
params: InputMessageId & {
|
||||
/** ID of the user who has scored */
|
||||
userId: InputPeerLike
|
||||
|
@ -67,7 +68,7 @@ export async function setGameScore(
|
|||
* @param params
|
||||
*/
|
||||
export async function setInlineGameScore(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
params: {
|
||||
/** ID of the inline message */
|
||||
messageId: string | tl.TypeInputBotInlineMessageID
|
|
@ -1,6 +1,7 @@
|
|||
import { BaseTelegramClient, tl } from '@mtcute/core'
|
||||
import { assertTrue } from '@mtcute/core/utils.js'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { assertTrue } from '../../../utils/type-assertions.js'
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { BotCommands } from '../../types/index.js'
|
||||
import { _normalizeCommandScope } from './normalize-command-scope.js'
|
||||
|
||||
|
@ -10,7 +11,7 @@ import { _normalizeCommandScope } from './normalize-command-scope.js'
|
|||
* Learn more about scopes in the [Bot API docs](https://core.telegram.org/bots/api#botcommandscope)
|
||||
*/
|
||||
export async function setMyCommands(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
params: {
|
||||
/**
|
||||
* New list of bot commands for the given scope.
|
|
@ -1,11 +1,13 @@
|
|||
import { BaseTelegramClient, tl } from '@mtcute/core'
|
||||
import { assertTrue } from '@mtcute/core/utils.js'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { assertTrue } from '../../../utils/type-assertions.js'
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
|
||||
/**
|
||||
* Sets the default chat permissions for the bot in the supergroup or channel.
|
||||
*/
|
||||
export async function setMyDefaultRights(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
params: {
|
||||
/** Whether to target groups or channels. */
|
||||
target: 'channel' | 'group'
|
|
@ -1,5 +1,5 @@
|
|||
import { BaseTelegramClient, MaybeArray } from '@mtcute/core'
|
||||
|
||||
import { MaybeArray } from '../../../types/utils.js'
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { InputPeerLike, MtInvalidPeerTypeError } from '../../types/index.js'
|
||||
import { isInputPeerChannel, isInputPeerChat, toInputChannel, toInputUser } from '../../utils/peer-utils.js'
|
||||
import { resolvePeer } from '../users/resolve-peer.js'
|
||||
|
@ -12,7 +12,7 @@ import { resolvePeerMany } from '../users/resolve-peer-many.js'
|
|||
* @param users ID(s) of the user(s) to add
|
||||
*/
|
||||
export async function addChatMembers(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
chatId: InputPeerLike,
|
||||
users: MaybeArray<InputPeerLike>,
|
||||
params: {
|
||||
|
@ -41,7 +41,7 @@ export async function addChatMembers(
|
|||
userId: p,
|
||||
fwdLimit: forwardCount,
|
||||
})
|
||||
client.network.handleUpdate(updates)
|
||||
client.handleClientUpdate(updates)
|
||||
}
|
||||
} else if (isInputPeerChannel(chat)) {
|
||||
const updates = await client.call({
|
||||
|
@ -49,7 +49,6 @@ export async function addChatMembers(
|
|||
channel: toInputChannel(chat),
|
||||
users: await resolvePeerMany(client, users, toInputUser),
|
||||
})
|
||||
|
||||
client.network.handleUpdate(updates)
|
||||
client.handleClientUpdate(updates)
|
||||
} else throw new MtInvalidPeerTypeError(chatId, 'chat or channel')
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
import { BaseTelegramClient, MaybeArray } from '@mtcute/core'
|
||||
|
||||
import { MaybeArray } from '../../../types/utils.js'
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { InputPeerLike } from '../../types/index.js'
|
||||
import { resolvePeerMany } from '../users/resolve-peer-many.js'
|
||||
|
||||
|
@ -8,7 +8,7 @@ import { resolvePeerMany } from '../users/resolve-peer-many.js'
|
|||
*
|
||||
* @param chats Chat ID(s), username(s), phone number(s), `"me"` or `"self"`
|
||||
*/
|
||||
export async function archiveChats(client: BaseTelegramClient, chats: MaybeArray<InputPeerLike>): Promise<void> {
|
||||
export async function archiveChats(client: ITelegramClient, chats: MaybeArray<InputPeerLike>): Promise<void> {
|
||||
if (!Array.isArray(chats)) chats = [chats]
|
||||
|
||||
const resolvedPeers = await resolvePeerMany(client, chats)
|
||||
|
@ -21,5 +21,5 @@ export async function archiveChats(client: BaseTelegramClient, chats: MaybeArray
|
|||
folderId: 1,
|
||||
})),
|
||||
})
|
||||
client.network.handleUpdate(updates)
|
||||
client.handleClientUpdate(updates)
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
import { BaseTelegramClient } from '@mtcute/core'
|
||||
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { InputPeerLike, Message, MtInvalidPeerTypeError } from '../../types/index.js'
|
||||
import { isInputPeerChannel, isInputPeerChat, toInputChannel, toInputUser } from '../../utils/peer-utils.js'
|
||||
import { _findMessageInUpdate } from '../messages/find-in-update.js'
|
||||
|
@ -16,7 +15,7 @@ import { resolvePeer } from '../users/resolve-peer.js'
|
|||
* @returns Service message about removed user, if one was generated.
|
||||
*/
|
||||
export async function banChatMember(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
params: {
|
||||
/** Chat ID */
|
||||
chatId: InputPeerLike
|
|
@ -1,5 +1,7 @@
|
|||
import { BaseTelegramClient, MtArgumentError, tl } from '@mtcute/core'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { MtArgumentError } from '../../../types/errors.js'
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import {
|
||||
isInputPeerChannel,
|
||||
isInputPeerChat,
|
||||
|
@ -129,7 +131,7 @@ export const _getChannelsBatched = batchedQuery<tl.TypeInputChannel, tl.RawChann
|
|||
|
||||
/** @internal */
|
||||
export function _getRawPeerBatched(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
peer: tl.TypeInputPeer,
|
||||
): Promise<tl.TypeUser | tl.TypeChat | null> {
|
||||
if (isInputPeerUser(peer)) {
|
|
@ -1,7 +1,6 @@
|
|||
import { BaseTelegramClient } from '@mtcute/core'
|
||||
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { Chat } from '../../types/index.js'
|
||||
import { assertIsUpdatesGroup } from '../../utils/updates-utils.js'
|
||||
import { assertIsUpdatesGroup } from '../../updates/utils.js'
|
||||
|
||||
/**
|
||||
* Create a new broadcast channel
|
||||
|
@ -9,7 +8,7 @@ import { assertIsUpdatesGroup } from '../../utils/updates-utils.js'
|
|||
* @returns Newly created channel
|
||||
*/
|
||||
export async function createChannel(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
params: {
|
||||
/**
|
||||
* Channel title
|
||||
|
@ -33,7 +32,7 @@ export async function createChannel(
|
|||
|
||||
assertIsUpdatesGroup('channels.createChannel', res)
|
||||
|
||||
client.network.handleUpdate(res)
|
||||
client.handleClientUpdate(res)
|
||||
|
||||
return new Chat(res.chats[0])
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
import { BaseTelegramClient, MaybeArray } from '@mtcute/core'
|
||||
|
||||
import { MaybeArray } from '../../../types/utils.js'
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { Chat, InputPeerLike } from '../../types/index.js'
|
||||
import { assertIsUpdatesGroup } from '../../updates/utils.js'
|
||||
import { toInputUser } from '../../utils/peer-utils.js'
|
||||
import { assertIsUpdatesGroup } from '../../utils/updates-utils.js'
|
||||
import { resolvePeerMany } from '../users/resolve-peer-many.js'
|
||||
|
||||
/**
|
||||
|
@ -12,7 +12,7 @@ import { resolvePeerMany } from '../users/resolve-peer-many.js'
|
|||
* instead.
|
||||
*/
|
||||
export async function createGroup(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
params: {
|
||||
/**
|
||||
* Group title
|
||||
|
@ -48,7 +48,7 @@ export async function createGroup(
|
|||
|
||||
assertIsUpdatesGroup('messages.createChat', res)
|
||||
|
||||
client.network.handleUpdate(res)
|
||||
client.handleClientUpdate(res)
|
||||
|
||||
return new Chat(res.chats[0])
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
import { BaseTelegramClient } from '@mtcute/core'
|
||||
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { Chat } from '../../types/index.js'
|
||||
import { assertIsUpdatesGroup } from '../../utils/updates-utils.js'
|
||||
import { assertIsUpdatesGroup } from '../../updates/utils.js'
|
||||
|
||||
/**
|
||||
* Create a new supergroup
|
||||
|
@ -9,7 +8,7 @@ import { assertIsUpdatesGroup } from '../../utils/updates-utils.js'
|
|||
* @returns Newly created supergroup
|
||||
*/
|
||||
export async function createSupergroup(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
params: {
|
||||
/**
|
||||
* Supergroup title
|
||||
|
@ -47,7 +46,7 @@ export async function createSupergroup(
|
|||
|
||||
assertIsUpdatesGroup('channels.createChannel', res)
|
||||
|
||||
client.network.handleUpdate(res)
|
||||
client.handleClientUpdate(res)
|
||||
|
||||
return new Chat(res.chats[0])
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
import { BaseTelegramClient } from '@mtcute/core'
|
||||
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { InputPeerLike } from '../../types/index.js'
|
||||
import { toInputChannel } from '../../utils/peer-utils.js'
|
||||
import { resolvePeer } from '../users/resolve-peer.js'
|
||||
|
@ -10,10 +9,10 @@ import { resolvePeer } from '../users/resolve-peer.js'
|
|||
*
|
||||
* @param chatId Chat ID or username
|
||||
*/
|
||||
export async function deleteChannel(client: BaseTelegramClient, chatId: InputPeerLike): Promise<void> {
|
||||
export async function deleteChannel(client: ITelegramClient, chatId: InputPeerLike): Promise<void> {
|
||||
const res = await client.call({
|
||||
_: 'channels.deleteChannel',
|
||||
channel: toInputChannel(await resolvePeer(client, chatId), chatId),
|
||||
})
|
||||
client.network.handleUpdate(res)
|
||||
client.handleClientUpdate(res)
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
import { BaseTelegramClient } from '@mtcute/core'
|
||||
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { InputPeerLike, MtInvalidPeerTypeError } from '../../types/index.js'
|
||||
import { isInputPeerChannel, isInputPeerChat, toInputChannel } from '../../utils/peer-utils.js'
|
||||
import { resolvePeer } from '../users/resolve-peer.js'
|
||||
|
@ -11,7 +10,7 @@ import { resolvePeer } from '../users/resolve-peer.js'
|
|||
*
|
||||
* @param chatId Chat ID or username
|
||||
*/
|
||||
export async function deleteChatPhoto(client: BaseTelegramClient, chatId: InputPeerLike): Promise<void> {
|
||||
export async function deleteChatPhoto(client: ITelegramClient, chatId: InputPeerLike): Promise<void> {
|
||||
const chat = await resolvePeer(client, chatId)
|
||||
|
||||
let res
|
||||
|
@ -29,5 +28,5 @@ export async function deleteChatPhoto(client: BaseTelegramClient, chatId: InputP
|
|||
})
|
||||
} else throw new MtInvalidPeerTypeError(chatId, 'chat or channel')
|
||||
|
||||
client.network.handleUpdate(res)
|
||||
client.handleClientUpdate(res)
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
import { BaseTelegramClient } from '@mtcute/core'
|
||||
import { assertTrue } from '@mtcute/core/utils.js'
|
||||
|
||||
import { assertTrue } from '../../../utils/type-assertions.js'
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { InputPeerLike, MtInvalidPeerTypeError } from '../../types/index.js'
|
||||
import { isInputPeerChat } from '../../utils/peer-utils.js'
|
||||
import { resolvePeer } from '../users/resolve-peer.js'
|
||||
|
@ -10,7 +9,7 @@ import { resolvePeer } from '../users/resolve-peer.js'
|
|||
*
|
||||
* @param chatId Chat ID
|
||||
*/
|
||||
export async function deleteGroup(client: BaseTelegramClient, chatId: InputPeerLike): Promise<void> {
|
||||
export async function deleteGroup(client: ITelegramClient, chatId: InputPeerLike): Promise<void> {
|
||||
const chat = await resolvePeer(client, chatId)
|
||||
if (!isInputPeerChat(chat)) throw new MtInvalidPeerTypeError(chatId, 'chat')
|
||||
|
||||
|
@ -20,7 +19,7 @@ export async function deleteGroup(client: BaseTelegramClient, chatId: InputPeerL
|
|||
chatId: chat.chatId,
|
||||
userId: { _: 'inputUserSelf' },
|
||||
})
|
||||
client.network.handleUpdate(res)
|
||||
client.handleClientUpdate(res)
|
||||
|
||||
const r = await client.call({
|
||||
_: 'messages.deleteChat',
|
|
@ -1,15 +1,14 @@
|
|||
import { BaseTelegramClient } from '@mtcute/core'
|
||||
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { InputPeerLike } from '../../types/index.js'
|
||||
import { createDummyUpdate } from '../../updates/utils.js'
|
||||
import { isInputPeerChannel } from '../../utils/peer-utils.js'
|
||||
import { createDummyUpdate } from '../../utils/updates-utils.js'
|
||||
import { resolvePeer } from '../users/resolve-peer.js'
|
||||
|
||||
/**
|
||||
* Delete communication history (for private chats and legacy groups)
|
||||
*/
|
||||
export async function deleteHistory(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
chat: InputPeerLike,
|
||||
params?: {
|
||||
/**
|
||||
|
@ -45,8 +44,8 @@ export async function deleteHistory(
|
|||
})
|
||||
|
||||
if (isInputPeerChannel(peer)) {
|
||||
client.network.handleUpdate(createDummyUpdate(res.pts, res.ptsCount, peer.channelId))
|
||||
client.handleClientUpdate(createDummyUpdate(res.pts, res.ptsCount, peer.channelId))
|
||||
} else {
|
||||
client.network.handleUpdate(createDummyUpdate(res.pts, res.ptsCount))
|
||||
client.handleClientUpdate(createDummyUpdate(res.pts, res.ptsCount))
|
||||
}
|
||||
}
|
|
@ -1,15 +1,16 @@
|
|||
import { BaseTelegramClient, tl } from '@mtcute/core'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { InputPeerLike } from '../../types/index.js'
|
||||
import { createDummyUpdate } from '../../updates/utils.js'
|
||||
import { toInputChannel } from '../../utils/peer-utils.js'
|
||||
import { createDummyUpdate } from '../../utils/updates-utils.js'
|
||||
import { resolvePeer } from '../users/resolve-peer.js'
|
||||
|
||||
/**
|
||||
* Delete all messages of a user (or channel) in a supergroup
|
||||
*/
|
||||
export async function deleteUserHistory(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
params: {
|
||||
/** Chat ID */
|
||||
chatId: InputPeerLike
|
||||
|
@ -29,5 +30,5 @@ export async function deleteUserHistory(
|
|||
participant: peer,
|
||||
})
|
||||
|
||||
client.network.handleUpdate(createDummyUpdate(res.pts, res.ptsCount, (channel as tl.RawInputChannel).channelId))
|
||||
client.handleClientUpdate(createDummyUpdate(res.pts, res.ptsCount, (channel as tl.RawInputChannel).channelId))
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
import { BaseTelegramClient, tl } from '@mtcute/core'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { InputPeerLike } from '../../types/index.js'
|
||||
import { toInputChannel, toInputUser } from '../../utils/peer-utils.js'
|
||||
import { resolvePeer } from '../users/resolve-peer.js'
|
||||
|
@ -8,7 +9,7 @@ import { resolvePeer } from '../users/resolve-peer.js'
|
|||
* Edit supergroup/channel admin rights of a user.
|
||||
*/
|
||||
export async function editAdminRights(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
params: {
|
||||
/** Chat ID */
|
||||
chatId: InputPeerLike
|
||||
|
@ -36,5 +37,5 @@ export async function editAdminRights(
|
|||
rank,
|
||||
})
|
||||
|
||||
client.network.handleUpdate(res)
|
||||
client.handleClientUpdate(res)
|
||||
}
|
|
@ -1,5 +1,8 @@
|
|||
import { BaseTelegramClient, Long, tl } from '@mtcute/core'
|
||||
import Long from 'long'
|
||||
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { ChatEvent, InputPeerLike, PeersIndex } from '../../types/index.js'
|
||||
import { InputChatEventFilters, normalizeChatEventFilters } from '../../types/peers/chat-event/filters.js'
|
||||
import { toInputChannel, toInputUser } from '../../utils/peer-utils.js'
|
||||
|
@ -20,7 +23,7 @@ import { resolvePeerMany } from '../users/resolve-peer-many.js'
|
|||
* @param params
|
||||
*/
|
||||
export async function getChatEventLog(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
chatId: InputPeerLike,
|
||||
params?: {
|
||||
/**
|
|
@ -1,6 +1,7 @@
|
|||
import { BaseTelegramClient, tl } from '@mtcute/core'
|
||||
import { assertTypeIs } from '@mtcute/core/utils.js'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { assertTypeIs } from '../../../utils/type-assertions.js'
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { ChatMember, InputPeerLike, MtInvalidPeerTypeError, PeersIndex } from '../../types/index.js'
|
||||
import { isInputPeerChannel, isInputPeerChat, isInputPeerUser, toInputChannel } from '../../utils/peer-utils.js'
|
||||
import { resolvePeer } from '../users/resolve-peer.js'
|
||||
|
@ -13,7 +14,7 @@ import { resolvePeer } from '../users/resolve-peer.js'
|
|||
* @returns Chat member, or `null` if user is not a member of the chat
|
||||
*/
|
||||
export async function getChatMember(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
params: {
|
||||
/** Chat ID or username */
|
||||
chatId: InputPeerLike
|
|
@ -1,6 +1,10 @@
|
|||
import { assertNever, BaseTelegramClient, Long, tl } from '@mtcute/core'
|
||||
import { assertTypeIs } from '@mtcute/core/utils.js'
|
||||
import Long from 'long'
|
||||
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { assertNever } from '../../../types/utils.js'
|
||||
import { assertTypeIs } from '../../../utils/type-assertions.js'
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { ArrayWithTotal, ChatMember, InputPeerLike, MtInvalidPeerTypeError, PeersIndex } from '../../types/index.js'
|
||||
import { makeArrayWithTotal } from '../../utils/index.js'
|
||||
import { isInputPeerChannel, isInputPeerChat, toInputChannel } from '../../utils/peer-utils.js'
|
||||
|
@ -15,7 +19,7 @@ import { resolvePeer } from '../users/resolve-peer.js'
|
|||
* @param params Additional parameters
|
||||
*/
|
||||
export async function getChatMembers(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
chatId: InputPeerLike,
|
||||
params?: {
|
||||
/**
|
|
@ -1,5 +1,5 @@
|
|||
import { BaseTelegramClient, MtArgumentError } from '@mtcute/core'
|
||||
|
||||
import { MtArgumentError } from '../../../types/errors.js'
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { ChatPreview, MtPeerNotFoundError } from '../../types/index.js'
|
||||
import { INVITE_LINK_REGEX } from '../../utils/peer-utils.js'
|
||||
|
||||
|
@ -12,7 +12,7 @@ import { INVITE_LINK_REGEX } from '../../utils/peer-utils.js'
|
|||
* In case you are trying to get info about private chat that you have already joined.
|
||||
* Use {@link getChat} or {@link getFullChat} instead.
|
||||
*/
|
||||
export async function getChatPreview(client: BaseTelegramClient, inviteLink: string): Promise<ChatPreview> {
|
||||
export async function getChatPreview(client: ITelegramClient, inviteLink: string): Promise<ChatPreview> {
|
||||
const m = inviteLink.match(INVITE_LINK_REGEX)
|
||||
if (!m) throw new MtArgumentError('Invalid invite link')
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import { BaseTelegramClient, MtArgumentError } from '@mtcute/core'
|
||||
|
||||
import { MtArgumentError } from '../../../types/errors.js'
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { Chat, InputPeerLike, MtPeerNotFoundError } from '../../types/index.js'
|
||||
import { INVITE_LINK_REGEX } from '../../utils/peer-utils.js'
|
||||
import { resolvePeer } from '../users/resolve-peer.js'
|
||||
|
@ -14,7 +14,7 @@ import { _getRawPeerBatched } from './batched-queries.js'
|
|||
* In case you are trying to get info about private chat that you haven't joined.
|
||||
* Use {@link getChatPreview} instead.
|
||||
*/
|
||||
export async function getChat(client: BaseTelegramClient, chatId: InputPeerLike): Promise<Chat> {
|
||||
export async function getChat(client: ITelegramClient, chatId: InputPeerLike): Promise<Chat> {
|
||||
if (typeof chatId === 'string') {
|
||||
const m = chatId.match(INVITE_LINK_REGEX)
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
import { BaseTelegramClient, MtArgumentError, tl } from '@mtcute/core'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { MtArgumentError } from '../../../types/errors.js'
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { Chat, InputPeerLike } from '../../types/index.js'
|
||||
import {
|
||||
INVITE_LINK_REGEX,
|
||||
|
@ -20,7 +22,7 @@ import { resolvePeer } from '../users/resolve-peer.js'
|
|||
* In case you are trying to get info about private chat that you haven't joined.
|
||||
* Use {@link getChatPreview} instead.
|
||||
*/
|
||||
export async function getFullChat(client: BaseTelegramClient, chatId: InputPeerLike): Promise<Chat> {
|
||||
export async function getFullChat(client: ITelegramClient, chatId: InputPeerLike): Promise<Chat> {
|
||||
if (typeof chatId === 'string') {
|
||||
const m = chatId.match(INVITE_LINK_REGEX)
|
||||
|
|
@ -1,8 +1,10 @@
|
|||
import { BaseTelegramClient, getMarkedPeerId, tl } from '@mtcute/core'
|
||||
import { assertTypeIs } from '@mtcute/core/utils.js'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { getMarkedPeerId } from '../../../utils/peer-utils.js'
|
||||
import { assertTypeIs } from '../../../utils/type-assertions.js'
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { Chat } from '../../types/index.js'
|
||||
import { assertIsUpdatesGroup } from '../../utils/updates-utils.js'
|
||||
import { assertIsUpdatesGroup } from '../../updates/utils.js'
|
||||
|
||||
/**
|
||||
* Get nearby chats
|
||||
|
@ -10,7 +12,7 @@ import { assertIsUpdatesGroup } from '../../utils/updates-utils.js'
|
|||
* @param latitude Latitude of the location
|
||||
* @param longitude Longitude of the location
|
||||
*/
|
||||
export async function getNearbyChats(client: BaseTelegramClient, latitude: number, longitude: number): Promise<Chat[]> {
|
||||
export async function getNearbyChats(client: ITelegramClient, latitude: number, longitude: number): Promise<Chat[]> {
|
||||
const res = await client.call({
|
||||
_: 'contacts.getLocated',
|
||||
geoPoint: {
|
||||
|
@ -21,7 +23,7 @@ export async function getNearbyChats(client: BaseTelegramClient, latitude: numbe
|
|||
})
|
||||
|
||||
assertIsUpdatesGroup('contacts.getLocated', res)
|
||||
client.network.handleUpdate(res, true)
|
||||
// client.handleClientUpdate(res, true)
|
||||
|
||||
if (!res.updates.length) return []
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
import { BaseTelegramClient } from '@mtcute/core'
|
||||
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { ArrayWithTotal, Chat, InputPeerLike } from '../../types/index.js'
|
||||
import { makeArrayWithTotal } from '../../utils/misc-utils.js'
|
||||
import { toInputChannel } from '../../utils/peer-utils.js'
|
||||
|
@ -16,7 +15,7 @@ import { resolvePeer } from '../users/resolve-peer.js'
|
|||
* > Returns empty array in case there are no similar channels available.
|
||||
*/
|
||||
export async function getSimilarChannels(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
channel: InputPeerLike,
|
||||
): Promise<ArrayWithTotal<Chat>> {
|
||||
const res = await client.call({
|
|
@ -1,5 +1,8 @@
|
|||
import { BaseTelegramClient, Long, tl } from '@mtcute/core'
|
||||
import Long from 'long'
|
||||
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { ChatEvent, InputPeerLike } from '../../types/index.js'
|
||||
import { normalizeChatEventFilters } from '../../types/peers/chat-event/filters.js'
|
||||
import { toInputChannel, toInputUser } from '../../utils/peer-utils.js'
|
||||
|
@ -16,7 +19,7 @@ import { getChatEventLog } from './get-chat-event-log.js'
|
|||
* @param params
|
||||
*/
|
||||
export async function* iterChatEventLog(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
chatId: InputPeerLike,
|
||||
params?: Parameters<typeof getChatEventLog>[2] & {
|
||||
/**
|
|
@ -1,5 +1,4 @@
|
|||
import { BaseTelegramClient } from '@mtcute/core'
|
||||
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { ChatMember, InputPeerLike } from '../../types/index.js'
|
||||
import { isInputPeerChat } from '../../utils/peer-utils.js'
|
||||
import { resolvePeer } from '../users/resolve-peer.js'
|
||||
|
@ -16,7 +15,7 @@ import { getChatMembers } from './get-chat-members.js'
|
|||
* @param params Additional parameters
|
||||
*/
|
||||
export async function* iterChatMembers(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
chatId: InputPeerLike,
|
||||
params?: Parameters<typeof getChatMembers>[2] & {
|
||||
/**
|
|
@ -1,8 +1,7 @@
|
|||
import { BaseTelegramClient } from '@mtcute/core'
|
||||
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { Chat, InputPeerLike } from '../../types/index.js'
|
||||
import { assertIsUpdatesGroup } from '../../updates/utils.js'
|
||||
import { INVITE_LINK_REGEX, toInputChannel } from '../../utils/peer-utils.js'
|
||||
import { assertIsUpdatesGroup } from '../../utils/updates-utils.js'
|
||||
import { resolvePeer } from '../users/resolve-peer.js'
|
||||
|
||||
/**
|
||||
|
@ -16,7 +15,7 @@ import { resolvePeer } from '../users/resolve-peer.js'
|
|||
* Chat identifier. Either an invite link (`t.me/joinchat/*`), a username (`@username`)
|
||||
* or ID of the linked supergroup or channel.
|
||||
*/
|
||||
export async function joinChat(client: BaseTelegramClient, chatId: InputPeerLike): Promise<Chat> {
|
||||
export async function joinChat(client: ITelegramClient, chatId: InputPeerLike): Promise<Chat> {
|
||||
if (typeof chatId === 'string') {
|
||||
const m = chatId.match(INVITE_LINK_REGEX)
|
||||
|
||||
|
@ -27,7 +26,7 @@ export async function joinChat(client: BaseTelegramClient, chatId: InputPeerLike
|
|||
})
|
||||
assertIsUpdatesGroup('messages.importChatInvite', res)
|
||||
|
||||
client.network.handleUpdate(res)
|
||||
client.handleClientUpdate(res)
|
||||
|
||||
return new Chat(res.chats[0])
|
||||
}
|
||||
|
@ -40,7 +39,7 @@ export async function joinChat(client: BaseTelegramClient, chatId: InputPeerLike
|
|||
|
||||
assertIsUpdatesGroup('channels.joinChannel', res)
|
||||
|
||||
client.network.handleUpdate(res)
|
||||
client.handleClientUpdate(res)
|
||||
|
||||
return new Chat(res.chats[0])
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
import { BaseTelegramClient } from '@mtcute/core'
|
||||
import { sleep } from '@mtcute/core/utils.js'
|
||||
|
||||
import { sleep } from '../../../utils/misc-utils.js'
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { InputPeerLike, Message } from '../../types/index.js'
|
||||
import { isInputPeerChannel } from '../../utils/peer-utils.js'
|
||||
import { resolvePeer } from '../users/resolve-peer.js'
|
||||
|
@ -15,7 +14,7 @@ import { unbanChatMember } from './unban-chat-member.js'
|
|||
* @returns Service message about removed user, if one was generated.
|
||||
*/
|
||||
export async function kickChatMember(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
params: {
|
||||
/** Chat ID */
|
||||
chatId: InputPeerLike
|
|
@ -1,5 +1,4 @@
|
|||
import { BaseTelegramClient } from '@mtcute/core'
|
||||
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { InputPeerLike, MtInvalidPeerTypeError } from '../../types/index.js'
|
||||
import { isInputPeerChannel, isInputPeerChat, toInputChannel } from '../../utils/peer-utils.js'
|
||||
import { resolvePeer } from '../users/resolve-peer.js'
|
||||
|
@ -11,7 +10,7 @@ import { deleteHistory } from './delete-history.js'
|
|||
* @param chatId Chat ID or username
|
||||
*/
|
||||
export async function leaveChat(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
chatId: InputPeerLike,
|
||||
params?: {
|
||||
/**
|
||||
|
@ -27,14 +26,14 @@ export async function leaveChat(
|
|||
_: 'channels.leaveChannel',
|
||||
channel: toInputChannel(chat),
|
||||
})
|
||||
client.network.handleUpdate(res)
|
||||
client.handleClientUpdate(res)
|
||||
} else if (isInputPeerChat(chat)) {
|
||||
const res = await client.call({
|
||||
_: 'messages.deleteChatUser',
|
||||
chatId: chat.chatId,
|
||||
userId: { _: 'inputUserSelf' },
|
||||
})
|
||||
client.network.handleUpdate(res)
|
||||
client.handleClientUpdate(res)
|
||||
|
||||
if (params?.clear) {
|
||||
await deleteHistory(client, chat)
|
|
@ -1,6 +1,5 @@
|
|||
import { BaseTelegramClient } from '@mtcute/core'
|
||||
import { assertTrue } from '@mtcute/core/utils.js'
|
||||
|
||||
import { assertTrue } from '../../../utils/type-assertions.js'
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { InputPeerLike } from '../../types/index.js'
|
||||
import { resolvePeer } from '../users/resolve-peer.js'
|
||||
|
||||
|
@ -9,7 +8,7 @@ import { resolvePeer } from '../users/resolve-peer.js'
|
|||
*
|
||||
* @param chatId Chat ID
|
||||
*/
|
||||
export async function markChatUnread(client: BaseTelegramClient, chatId: InputPeerLike): Promise<void> {
|
||||
export async function markChatUnread(client: ITelegramClient, chatId: InputPeerLike): Promise<void> {
|
||||
const r = await client.call({
|
||||
_: 'messages.markDialogUnread',
|
||||
peer: {
|
|
@ -1,9 +1,7 @@
|
|||
import { BaseTelegramClient } from '@mtcute/core'
|
||||
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { InputPeerLike } from '../../types/peers/index.js'
|
||||
import { isInputPeerChannel } from '../../utils/peer-utils.js'
|
||||
import { getPeerDialogs } from '../dialogs/get-peer-dialogs.js'
|
||||
import { notifyChannelClosed, notifyChannelOpened } from '../updates/manager.js'
|
||||
import { resolvePeer } from '../users/resolve-peer.js'
|
||||
|
||||
/**
|
||||
|
@ -14,15 +12,13 @@ import { resolvePeer } from '../users/resolve-peer.js'
|
|||
*
|
||||
* @param chat Chat to open
|
||||
*/
|
||||
export async function openChat(client: BaseTelegramClient, chat: InputPeerLike): Promise<void> {
|
||||
export async function openChat(client: ITelegramClient, chat: InputPeerLike): Promise<void> {
|
||||
const peer = await resolvePeer(client, chat)
|
||||
|
||||
if (isInputPeerChannel(peer)) {
|
||||
const [dialog] = await getPeerDialogs(client, peer)
|
||||
|
||||
if (!client.network.params.disableUpdates) {
|
||||
notifyChannelOpened(client, peer.channelId, dialog.raw.pts)
|
||||
}
|
||||
await client.notifyChannelOpened(peer.channelId, dialog.raw.pts)
|
||||
}
|
||||
|
||||
// todo: once we have proper dialogs/peers db, we should also
|
||||
|
@ -38,11 +34,11 @@ export async function openChat(client: BaseTelegramClient, chat: InputPeerLike):
|
|||
*
|
||||
* @param chat Chat to open
|
||||
*/
|
||||
export async function closeChat(client: BaseTelegramClient, chat: InputPeerLike): Promise<void> {
|
||||
export async function closeChat(client: ITelegramClient, chat: InputPeerLike): Promise<void> {
|
||||
const peer = await resolvePeer(client, chat)
|
||||
|
||||
if (isInputPeerChannel(peer) && !client.network.params.disableUpdates) {
|
||||
notifyChannelClosed(client, peer.channelId)
|
||||
if (isInputPeerChannel(peer)) {
|
||||
await client.notifyChannelClosed(peer.channelId)
|
||||
}
|
||||
|
||||
// todo: once we have proper dialogs/peers db, we should also
|
|
@ -1,8 +1,8 @@
|
|||
import { BaseTelegramClient } from '@mtcute/core'
|
||||
|
||||
import { assertTrue } from '../../../utils/type-assertions.js'
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { InputPeerLike } from '../../types/index.js'
|
||||
import { assertTrue, isInputPeerChannel, isInputPeerUser, toInputChannel, toInputUser } from '../../utils/index.js'
|
||||
import { isSelfPeer } from '../auth/_state.js'
|
||||
import { isInputPeerChannel, isInputPeerUser, toInputChannel, toInputUser } from '../../utils/index.js'
|
||||
import { isSelfPeer } from '../auth/utils.js'
|
||||
import { resolvePeer } from '../users/resolve-peer.js'
|
||||
|
||||
/**
|
||||
|
@ -11,7 +11,7 @@ import { resolvePeer } from '../users/resolve-peer.js'
|
|||
* @param peerId Bot, channel or "me"/"self"
|
||||
*/
|
||||
export async function reorderUsernames(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
peerId: InputPeerLike,
|
||||
order: string[],
|
||||
): Promise<void> {
|
|
@ -1,5 +1,6 @@
|
|||
import { BaseTelegramClient, tl } from '@mtcute/core'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { InputPeerLike, MtInvalidPeerTypeError } from '../../types/index.js'
|
||||
import { normalizeDate } from '../../utils/misc-utils.js'
|
||||
import { isInputPeerChannel, toInputChannel } from '../../utils/peer-utils.js'
|
||||
|
@ -9,7 +10,7 @@ import { resolvePeer } from '../users/resolve-peer.js'
|
|||
* Restrict a user in a supergroup.
|
||||
*/
|
||||
export async function restrictChatMember(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
params: {
|
||||
/** Chat ID */
|
||||
chatId: InputPeerLike
|
||||
|
@ -56,5 +57,5 @@ export async function restrictChatMember(
|
|||
...restrictions,
|
||||
},
|
||||
})
|
||||
client.network.handleUpdate(res)
|
||||
client.handleClientUpdate(res)
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
import { BaseTelegramClient, tl } from '@mtcute/core'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { InputPeerLike } from '../../types/index.js'
|
||||
import { resolvePeer } from '../users/resolve-peer.js'
|
||||
|
||||
|
@ -10,7 +11,7 @@ import { resolvePeer } from '../users/resolve-peer.js'
|
|||
* @param draft Draft message, or `null` to delete.
|
||||
*/
|
||||
export async function saveDraft(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
chatId: InputPeerLike,
|
||||
draft: null | Omit<tl.RawDraftMessage, '_' | 'date'>,
|
||||
): Promise<void> {
|
|
@ -1,8 +1,11 @@
|
|||
import { BaseTelegramClient, MtTypeAssertionError, tl } from '@mtcute/core'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { MtTypeAssertionError } from '../../../types/errors.js'
|
||||
import { assertTrue } from '../../../utils/type-assertions.js'
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { InputPeerLike, MtInvalidPeerTypeError } from '../../types/index.js'
|
||||
import { assertTrue, isInputPeerChannel, isInputPeerUser, toInputChannel } from '../../utils/index.js'
|
||||
import { isSelfPeer } from '../auth/_state.js'
|
||||
import { isInputPeerChannel, isInputPeerUser, toInputChannel } from '../../utils/index.js'
|
||||
import { isSelfPeer } from '../auth/utils.js'
|
||||
import { resolvePeer } from '../users/resolve-peer.js'
|
||||
|
||||
// @available=user
|
||||
|
@ -10,7 +13,7 @@ import { resolvePeer } from '../users/resolve-peer.js'
|
|||
* Set peer color and optionally background pattern
|
||||
*/
|
||||
export async function setChatColor(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
params: {
|
||||
/**
|
||||
* Peer where to update the color.
|
||||
|
@ -58,7 +61,7 @@ export async function setChatColor(
|
|||
backgroundEmojiId,
|
||||
})
|
||||
|
||||
client.network.handleUpdate(res)
|
||||
client.handleClientUpdate(res)
|
||||
|
||||
return
|
||||
}
|
|
@ -1,7 +1,8 @@
|
|||
import { BaseTelegramClient, tl } from '@mtcute/core'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { Chat, InputPeerLike } from '../../types/index.js'
|
||||
import { assertIsUpdatesGroup } from '../../utils/updates-utils.js'
|
||||
import { assertIsUpdatesGroup } from '../../updates/utils.js'
|
||||
import { resolvePeer } from '../users/resolve-peer.js'
|
||||
|
||||
/**
|
||||
|
@ -17,7 +18,7 @@ import { resolvePeer } from '../users/resolve-peer.js'
|
|||
* and passing `{}` (empty object) will lift any restrictions
|
||||
*/
|
||||
export async function setChatDefaultPermissions(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
chatId: InputPeerLike,
|
||||
restrictions: Omit<tl.RawChatBannedRights, '_' | 'untilDate'>,
|
||||
): Promise<Chat> {
|
||||
|
@ -35,7 +36,7 @@ export async function setChatDefaultPermissions(
|
|||
|
||||
assertIsUpdatesGroup('messages.editChatDefaultBannedRights', res)
|
||||
|
||||
client.network.handleUpdate(res)
|
||||
client.handleClientUpdate(res)
|
||||
|
||||
return new Chat(res.chats[0])
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
import { BaseTelegramClient } from '@mtcute/core'
|
||||
import { assertTrue } from '@mtcute/core/utils.js'
|
||||
|
||||
import { assertTrue } from '../../../utils/type-assertions.js'
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { InputPeerLike } from '../../types/index.js'
|
||||
import { resolvePeer } from '../users/resolve-peer.js'
|
||||
|
||||
|
@ -13,7 +12,7 @@ import { resolvePeer } from '../users/resolve-peer.js'
|
|||
* @param description New chat description, 0-255 characters
|
||||
*/
|
||||
export async function setChatDescription(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
chatId: InputPeerLike,
|
||||
description: string,
|
||||
): Promise<void> {
|
|
@ -1,7 +1,10 @@
|
|||
import { BaseTelegramClient, MtArgumentError, tl } from '@mtcute/core'
|
||||
import { fileIdToInputPhoto, tdFileId } from '@mtcute/file-id'
|
||||
import { tdFileId } from '@mtcute/file-id'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { MtArgumentError } from '../../../types/errors.js'
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { InputFileLike, InputPeerLike, isUploadedFile, MtInvalidPeerTypeError } from '../../types/index.js'
|
||||
import { fileIdToInputPhoto } from '../../utils/convert-file-id.js'
|
||||
import { isInputPeerChannel, isInputPeerChat, toInputChannel } from '../../utils/peer-utils.js'
|
||||
import { uploadFile } from '../files/upload-file.js'
|
||||
import { resolvePeer } from '../users/resolve-peer.js'
|
||||
|
@ -12,7 +15,7 @@ import { resolvePeer } from '../users/resolve-peer.js'
|
|||
* You must be an administrator and have the appropriate permissions.
|
||||
*/
|
||||
export async function setChatPhoto(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
params: {
|
||||
/** Chat ID or username */
|
||||
chatId: InputPeerLike
|
||||
|
@ -99,5 +102,5 @@ export async function setChatPhoto(
|
|||
photo,
|
||||
})
|
||||
}
|
||||
client.network.handleUpdate(res)
|
||||
client.handleClientUpdate(res)
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
import { BaseTelegramClient } from '@mtcute/core'
|
||||
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { InputPeerLike, MtInvalidPeerTypeError } from '../../types/index.js'
|
||||
import { isInputPeerChannel, isInputPeerChat, toInputChannel } from '../../utils/peer-utils.js'
|
||||
import { resolvePeer } from '../users/resolve-peer.js'
|
||||
|
@ -12,7 +11,7 @@ import { resolvePeer } from '../users/resolve-peer.js'
|
|||
* @param chatId Chat ID or username
|
||||
* @param title New chat title, 1-255 characters
|
||||
*/
|
||||
export async function setChatTitle(client: BaseTelegramClient, chatId: InputPeerLike, title: string): Promise<void> {
|
||||
export async function setChatTitle(client: ITelegramClient, chatId: InputPeerLike, title: string): Promise<void> {
|
||||
const chat = await resolvePeer(client, chatId)
|
||||
|
||||
let res
|
||||
|
@ -30,5 +29,5 @@ export async function setChatTitle(client: BaseTelegramClient, chatId: InputPeer
|
|||
})
|
||||
} else throw new MtInvalidPeerTypeError(chatId, 'chat or channel')
|
||||
|
||||
client.network.handleUpdate(res)
|
||||
client.handleClientUpdate(res)
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
import { BaseTelegramClient } from '@mtcute/core'
|
||||
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { InputPeerLike } from '../../types/index.js'
|
||||
import { resolvePeer } from '../users/resolve-peer.js'
|
||||
|
||||
|
@ -9,7 +8,7 @@ import { resolvePeer } from '../users/resolve-peer.js'
|
|||
* @param chatId Chat ID
|
||||
* @param period New TTL period, in seconds (or 0 to disable)
|
||||
*/
|
||||
export async function setChatTtl(client: BaseTelegramClient, chatId: InputPeerLike, period: number): Promise<void> {
|
||||
export async function setChatTtl(client: ITelegramClient, chatId: InputPeerLike, period: number): Promise<void> {
|
||||
await client.call({
|
||||
_: 'messages.setHistoryTTL',
|
||||
peer: await resolvePeer(client, chatId),
|
|
@ -1,6 +1,5 @@
|
|||
import { BaseTelegramClient } from '@mtcute/core'
|
||||
import { assertTrue } from '@mtcute/core/utils.js'
|
||||
|
||||
import { assertTrue } from '../../../utils/type-assertions.js'
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { InputPeerLike } from '../../types/index.js'
|
||||
import { toInputChannel } from '../../utils/peer-utils.js'
|
||||
import { resolvePeer } from '../users/resolve-peer.js'
|
||||
|
@ -14,7 +13,7 @@ import { resolvePeer } from '../users/resolve-peer.js'
|
|||
* @param username New username, or `null` to remove
|
||||
*/
|
||||
export async function setChatUsername(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
chatId: InputPeerLike,
|
||||
username: string | null,
|
||||
): Promise<void> {
|
|
@ -1,5 +1,4 @@
|
|||
import { BaseTelegramClient } from '@mtcute/core'
|
||||
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { InputPeerLike } from '../../types/index.js'
|
||||
import { toInputChannel } from '../../utils/peer-utils.js'
|
||||
import { resolvePeer } from '../users/resolve-peer.js'
|
||||
|
@ -13,11 +12,11 @@ import { resolvePeer } from '../users/resolve-peer.js'
|
|||
* Users will be able to send a message only once per this interval.
|
||||
* Valid values are: `0 (off), 10, 30, 60 (1m), 300 (5m), 900 (15m) or 3600 (1h)`
|
||||
*/
|
||||
export async function setSlowMode(client: BaseTelegramClient, chatId: InputPeerLike, seconds = 0): Promise<void> {
|
||||
export async function setSlowMode(client: ITelegramClient, chatId: InputPeerLike, seconds = 0): Promise<void> {
|
||||
const res = await client.call({
|
||||
_: 'channels.toggleSlowMode',
|
||||
channel: toInputChannel(await resolvePeer(client, chatId), chatId),
|
||||
seconds,
|
||||
})
|
||||
client.network.handleUpdate(res)
|
||||
client.handleClientUpdate(res)
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
import { BaseTelegramClient } from '@mtcute/core'
|
||||
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { InputPeerLike } from '../../types/index.js'
|
||||
import { resolvePeer } from '../users/resolve-peer.js'
|
||||
|
||||
|
@ -10,7 +9,7 @@ import { resolvePeer } from '../users/resolve-peer.js'
|
|||
* @param enabled Whether content protection should be enabled
|
||||
*/
|
||||
export async function toggleContentProtection(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
chatId: InputPeerLike,
|
||||
enabled = false,
|
||||
): Promise<void> {
|
||||
|
@ -19,5 +18,5 @@ export async function toggleContentProtection(
|
|||
peer: await resolvePeer(client, chatId),
|
||||
enabled,
|
||||
})
|
||||
client.network.handleUpdate(res)
|
||||
client.handleClientUpdate(res)
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
import { BaseTelegramClient } from '@mtcute/core'
|
||||
|
||||
import { assertTrue } from '../../../utils/type-assertions.js'
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { InputPeerLike } from '../../types/index.js'
|
||||
import { assertTrue, isInputPeerChannel, isInputPeerUser, toInputChannel, toInputUser } from '../../utils/index.js'
|
||||
import { isSelfPeer } from '../auth/_state.js'
|
||||
import { isInputPeerChannel, isInputPeerUser, toInputChannel, toInputUser } from '../../utils/index.js'
|
||||
import { isSelfPeer } from '../auth/utils.js'
|
||||
import { resolvePeer } from '../users/resolve-peer.js'
|
||||
|
||||
/**
|
||||
|
@ -12,7 +12,7 @@ import { resolvePeer } from '../users/resolve-peer.js'
|
|||
* > using {@link setUsername}/{@link setChatUsername}
|
||||
*/
|
||||
export async function toggleFragmentUsername(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
params: {
|
||||
/** Peer ID whose username to toggle */
|
||||
peerId: InputPeerLike
|
|
@ -1,5 +1,4 @@
|
|||
import { BaseTelegramClient } from '@mtcute/core'
|
||||
|
||||
import { ITelegramClient } from '../../client.types.js'
|
||||
import { InputPeerLike } from '../../types/index.js'
|
||||
import { toInputChannel } from '../../utils/peer-utils.js'
|
||||
import { resolvePeer } from '../users/resolve-peer.js'
|
||||
|
@ -14,7 +13,7 @@ import { resolvePeer } from '../users/resolve-peer.js'
|
|||
* @param enabled Whether join requests should be enabled
|
||||
*/
|
||||
export async function toggleJoinRequests(
|
||||
client: BaseTelegramClient,
|
||||
client: ITelegramClient,
|
||||
chatId: InputPeerLike,
|
||||
enabled = false,
|
||||
): Promise<void> {
|
||||
|
@ -23,5 +22,5 @@ export async function toggleJoinRequests(
|
|||
channel: toInputChannel(await resolvePeer(client, chatId), chatId),
|
||||
enabled,
|
||||
})
|
||||
client.network.handleUpdate(res)
|
||||
client.handleClientUpdate(res)
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue