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': [
|
'simple-import-sort/imports': [
|
||||||
'error',
|
'error',
|
||||||
{
|
{
|
||||||
groups: [['^[a-z]'], ['^@mtcute'], ['^@/'], ['^~/'], ['^\\.']],
|
groups: [['^[a-z]'], ['^@?mtcute'], ['^@/'], ['^~/'], ['^\\.']],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
'simple-import-sort/exports': 'error',
|
'simple-import-sort/exports': 'error',
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"name": "mtcute",
|
"name": "mtcute-workspace",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.6.0",
|
"version": "0.6.0",
|
||||||
"description": "Type-safe library for MTProto (Telegram API) for browser and NodeJS",
|
"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 }) => ({
|
module.exports = ({ path, transformFile, packageDir, outDir }) => ({
|
||||||
esmOnlyDirectives: true,
|
esmOnlyDirectives: true,
|
||||||
|
esmImportDirectives: true,
|
||||||
final() {
|
final() {
|
||||||
const version = require(path.join(packageDir, 'package.json')).version
|
const version = require(path.join(packageDir, 'package.json')).version
|
||||||
const replaceVersion = (content) => content.replace('%VERSION%', version)
|
const replaceVersion = (content) => content.replace('%VERSION%', version)
|
||||||
|
|
|
@ -2,13 +2,15 @@
|
||||||
"name": "@mtcute/core",
|
"name": "@mtcute/core",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.6.0",
|
"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>",
|
"author": "Alina Sireneva <alina@tei.su>",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"main": "src/index.ts",
|
"main": "src/index.ts",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"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": {
|
"browser": {
|
||||||
"./src/utils/platform/crypto.js": "./src/utils/platform/crypto.web.js",
|
"./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/logging.js": "./src/utils/platform/logging.web.js",
|
||||||
"./src/utils/platform/random.js": "./src/utils/platform/random.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/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
|
"./src/storage/json-file.js": false
|
||||||
},
|
},
|
||||||
"distOnlyFields": {
|
"distOnlyFields": {
|
||||||
|
@ -39,6 +46,14 @@
|
||||||
"./storage/*": {
|
"./storage/*": {
|
||||||
"import": "./esm/storage/*",
|
"import": "./esm/storage/*",
|
||||||
"require": "./cjs/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": "workspace:^",
|
||||||
"@mtcute/tl-runtime": "workspace:^",
|
"@mtcute/tl-runtime": "workspace:^",
|
||||||
"@mtcute/wasm": "workspace:^",
|
"@mtcute/wasm": "workspace:^",
|
||||||
|
"@mtcute/file-id": "workspace:^",
|
||||||
"@types/events": "3.0.0",
|
"@types/events": "3.0.0",
|
||||||
"events": "3.2.0",
|
"events": "3.2.0",
|
||||||
"long": "5.2.3"
|
"long": "5.2.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/ws": "8.5.4",
|
"@types/ws": "8.5.4",
|
||||||
"node-forge": "1.3.1",
|
|
||||||
"@mtcute/test": "workspace:^",
|
"@mtcute/test": "workspace:^",
|
||||||
"ws": "8.13.0"
|
"ws": "8.13.0"
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ function findMethodAvailability(method) {
|
||||||
return entry.available ?? null
|
return entry.available ?? null
|
||||||
}
|
}
|
||||||
|
|
||||||
const targetDir = path.join(__dirname, '../src')
|
const targetDir = path.join(__dirname, '../src/highlevel')
|
||||||
|
|
||||||
async function* getFiles(dir) {
|
async function* getFiles(dir) {
|
||||||
const dirents = await fs.promises.readdir(dir, { withFileTypes: true })
|
const dirents = await fs.promises.readdir(dir, { withFileTypes: true })
|
||||||
|
@ -315,7 +315,7 @@ async function addSingleMethod(state, fileName) {
|
||||||
|
|
||||||
const firstArg = stmt.parameters[0]
|
const firstArg = stmt.parameters[0]
|
||||||
|
|
||||||
if (isExported && (!firstArg || firstArg.type.getText() !== 'BaseTelegramClient')) {
|
if (isExported && (!firstArg || firstArg.type.getText() !== 'ITelegramClient')) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -421,7 +421,8 @@ async function addSingleMethod(state, fileName) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function main() {
|
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 = {
|
const state = {
|
||||||
imports: {},
|
imports: {},
|
||||||
fields: [],
|
fields: [],
|
||||||
|
@ -435,7 +436,7 @@ async function main() {
|
||||||
files: {},
|
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')) {
|
if (!file.startsWith('.') && file.endsWith('.ts') && !file.endsWith('.web.ts') && !file.endsWith('.test.ts')) {
|
||||||
await addSingleMethod(state, file)
|
await addSingleMethod(state, file)
|
||||||
}
|
}
|
||||||
|
@ -444,7 +445,9 @@ async function main() {
|
||||||
output.write(
|
output.write(
|
||||||
'/* eslint-disable @typescript-eslint/no-unsafe-declaration-merging, @typescript-eslint/unified-signatures */\n' +
|
'/* eslint-disable @typescript-eslint/no-unsafe-declaration-merging, @typescript-eslint/unified-signatures */\n' +
|
||||||
'/* eslint-disable @typescript-eslint/no-unsafe-argument */\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]) => {
|
Object.entries(state.imports).forEach(([module, items]) => {
|
||||||
items = [...items]
|
items = [...items]
|
||||||
|
@ -458,7 +461,7 @@ async function main() {
|
||||||
output.write(`// from ${from}\n${code}\n`)
|
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(`/**
|
output.write(`/**
|
||||||
* Register a raw update handler
|
* 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(', ')}>` :
|
`<${func.typeParameters.map((it) => it.getFullText()).join(', ')}>` :
|
||||||
''
|
''
|
||||||
const rawParams = (func.parameters || []).filter(
|
const rawParams = (func.parameters || []).filter(
|
||||||
(it) => !it.type || it.type.getText() !== 'BaseTelegramClient',
|
(it) => !it.type || it.type.getText() !== 'ITelegramClient',
|
||||||
)
|
)
|
||||||
const parameters = rawParams
|
const parameters = rawParams
|
||||||
.map((it) => {
|
.map((it) => {
|
||||||
|
@ -648,8 +651,8 @@ on(name: string, handler: (...args: any[]) => void): this\n`)
|
||||||
if (hasOverloads) {
|
if (hasOverloads) {
|
||||||
classProtoDecls.push('// @ts-expect-error this kinda breaks typings for overloads, idc')
|
classProtoDecls.push('// @ts-expect-error this kinda breaks typings for overloads, idc')
|
||||||
}
|
}
|
||||||
classProtoDecls.push(` return ${origName}(this, ...args);`)
|
classProtoDecls.push(` return ${origName}(this._client, ...args);`)
|
||||||
classProtoDecls.push('}\n')
|
classProtoDecls.push('}')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -657,11 +660,13 @@ on(name: string, handler: (...args: any[]) => void): this\n`)
|
||||||
output.write('}\n')
|
output.write('}\n')
|
||||||
|
|
||||||
output.write('\nexport type { TelegramClientOptions }\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`))
|
state.fields.forEach(({ code }) => output.write(`protected ${code}\n`))
|
||||||
|
|
||||||
output.write('constructor(opts: TelegramClientOptions) {\n')
|
output.write('constructor(opts: TelegramClientOptions) {\n')
|
||||||
|
output.write(' super()\n')
|
||||||
state.init.forEach((code) => {
|
state.init.forEach((code) => {
|
||||||
output.write(code + '\n')
|
output.write(code + '\n')
|
||||||
})
|
})
|
||||||
|
@ -670,10 +675,45 @@ on(name: string, handler: (...args: any[]) => void): this\n`)
|
||||||
classContents.forEach((line) => output.write(line + '\n'))
|
classContents.forEach((line) => output.write(line + '\n'))
|
||||||
output.write('}\n')
|
output.write('}\n')
|
||||||
classProtoDecls.forEach((line) => output.write(line + '\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`))
|
state.impls.forEach(({ name, code }) => output.write(`TelegramClient.prototype.${name} = ${code}\n`))
|
||||||
|
|
||||||
// format the resulting file with prettier
|
// format the resulting file with prettier
|
||||||
const targetFile = path.join(__dirname, '../src/client.ts')
|
|
||||||
const prettierConfig = await prettier.resolveConfig(targetFile)
|
const prettierConfig = await prettier.resolveConfig(targetFile)
|
||||||
let fullSource = await fs.promises.readFile(targetFile, 'utf-8')
|
let fullSource = await fs.promises.readFile(targetFile, 'utf-8')
|
||||||
fullSource = await prettier.format(fullSource, {
|
fullSource = await prettier.format(fullSource, {
|
|
@ -1,4 +1,3 @@
|
||||||
/* eslint-disable no-restricted-globals */
|
|
||||||
const fs = require('fs')
|
const fs = require('fs')
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
const prettier = require('prettier')
|
const prettier = require('prettier')
|
||||||
|
@ -90,7 +89,7 @@ function toSentence(type, stype = 'inline') {
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateParsedUpdate() {
|
function generateParsedUpdate() {
|
||||||
replaceSections('types/updates/index.ts', {
|
replaceSections('highlevel/types/updates/index.ts', {
|
||||||
codegen:
|
codegen:
|
||||||
'export type ParsedUpdate =\n' +
|
'export type ParsedUpdate =\n' +
|
||||||
types.map((typ) => ` | { name: '${typ.typeName}'; data: ${typ.updateType} }\n`).join(''),
|
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
|
```typescript
|
||||||
// @initialize
|
// @initialize
|
||||||
function _initializeAwesomeExtension(client: BaseTelegramClient) {
|
function _initializeAwesomeExtension(client: ITelegramClient) {
|
||||||
this._field1 = 42
|
this._field1 = 42
|
||||||
this._field2 = 'uwu'
|
this._field2 = 'uwu'
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@ Example:
|
||||||
// @exported
|
// @exported
|
||||||
export type FooOrBar = Foo | Bar
|
export type FooOrBar = Foo | Bar
|
||||||
|
|
||||||
export function getFooOrBar(client: BaseTelegramClient): FooOrBar {
|
export function getFooOrBar(client: ITelegramClient): FooOrBar {
|
||||||
return new Foo()
|
return new Foo()
|
||||||
}
|
}
|
||||||
```
|
```
|
|
@ -1,19 +1,18 @@
|
||||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||||
// @copy
|
|
||||||
import {
|
|
||||||
BaseTelegramClient,
|
|
||||||
BaseTelegramClientOptions,
|
|
||||||
IMtStorageProvider,
|
|
||||||
Long,
|
|
||||||
MaybeArray,
|
|
||||||
MaybeAsync,
|
|
||||||
PartialExcept,
|
|
||||||
PartialOnly,
|
|
||||||
tl,
|
|
||||||
} from '@mtcute/core'
|
|
||||||
// @copy
|
// @copy
|
||||||
import { tdFileId } from '@mtcute/file-id'
|
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
|
// @copy
|
||||||
import {
|
import {
|
||||||
AllStories,
|
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 { ITelegramClient } from '../../client.types.js'
|
||||||
import { computeSrpParams } from '@mtcute/core/utils.js'
|
|
||||||
|
|
||||||
import { User } from '../../types/index.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
|
* Check your Two-Step verification password and log in
|
||||||
|
@ -11,11 +9,10 @@ import { _onAuthorization } from './_state.js'
|
||||||
* @returns The authorized user
|
* @returns The authorized user
|
||||||
* @throws BadRequestError In case the password is invalid
|
* @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({
|
const res = await client.call({
|
||||||
_: 'auth.checkPassword',
|
_: 'auth.checkPassword',
|
||||||
password: await computeSrpParams(
|
password: await client.computeSrpParams(
|
||||||
client.crypto,
|
|
||||||
await client.call({
|
await client.call({
|
||||||
_: 'account.getPassword',
|
_: 'account.getPassword',
|
||||||
}),
|
}),
|
|
@ -1,11 +1,11 @@
|
||||||
import { BaseTelegramClient } from '@mtcute/core'
|
import { ITelegramClient } from '../../client.types.js'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get your Two-Step Verification password hint.
|
* Get your Two-Step Verification password hint.
|
||||||
*
|
*
|
||||||
* @returns The password hint as a string, if any
|
* @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
|
return client
|
||||||
.call({
|
.call({
|
||||||
_: 'account.getPassword',
|
_: '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.
|
* 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
|
* @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.call({ _: 'auth.logOut' })
|
||||||
|
await client.notifyLoggedOut()
|
||||||
await client.storage.self.store(null)
|
|
||||||
// authState.selfUsername = null todo
|
|
||||||
|
|
||||||
client.emit('logged_out')
|
|
||||||
|
|
||||||
await client.storage.clear()
|
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
|
@ -1,7 +1,6 @@
|
||||||
import { BaseTelegramClient } from '@mtcute/core'
|
import { ITelegramClient } from '../../client.types.js'
|
||||||
|
|
||||||
import { User } from '../../types/index.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.
|
* 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
|
* @throws BadRequestError In case the code is invalid
|
||||||
*/
|
*/
|
||||||
export async function recoverPassword(
|
export async function recoverPassword(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
params: {
|
params: {
|
||||||
/** The recovery code sent via email */
|
/** The recovery code sent via email */
|
||||||
recoveryCode: string
|
recoveryCode: string
|
|
@ -1,7 +1,6 @@
|
||||||
import { BaseTelegramClient } from '@mtcute/core'
|
import { assertTypeIs } from '../../../utils/type-assertions.js'
|
||||||
import { assertTypeIs } from '@mtcute/core/utils.js'
|
import { ITelegramClient } from '../../client.types.js'
|
||||||
|
import { SentCode } from '../../types/auth/sent-code.js'
|
||||||
import { SentCode } from '../../types/index.js'
|
|
||||||
import { normalizePhoneNumber } from '../../utils/misc-utils.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}
|
* {@link SentCode} object returned by {@link sendCode}
|
||||||
*/
|
*/
|
||||||
export async function resendCode(
|
export async function resendCode(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
params: {
|
params: {
|
||||||
/** Phone number in international format */
|
/** Phone number in international format */
|
||||||
phone: string
|
phone: string
|
|
@ -1,6 +1,4 @@
|
||||||
import { BaseTelegramClient } from '@mtcute/core'
|
import { ITelegramClient } from '../../client.types.js'
|
||||||
|
|
||||||
import { TelegramClient } from '../../index.js'
|
|
||||||
import { User } from '../../types/index.js'
|
import { User } from '../../types/index.js'
|
||||||
import { start } from './start.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 params Parameters to be passed to {@link start}
|
||||||
* @param then Function to be called after {@link start} returns
|
* @param then Function to be called after {@link start} returns
|
||||||
* @manual=noemit
|
|
||||||
*/
|
*/
|
||||||
export function run(
|
export function run(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
params: Parameters<typeof start>[1],
|
params: Parameters<typeof start>[1],
|
||||||
then?: (user: User) => void | Promise<void>,
|
then?: (user: User) => void | Promise<void>,
|
||||||
): void {
|
): void {
|
||||||
start(client, params)
|
start(client, params)
|
||||||
.then(then)
|
.then(then)
|
||||||
.catch((err) => client._emitError(err))
|
.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))
|
|
||||||
}
|
}
|
|
@ -1,7 +1,6 @@
|
||||||
import { BaseTelegramClient } from '@mtcute/core'
|
import { assertTypeIs } from '../../../utils/type-assertions.js'
|
||||||
import { assertTypeIs } from '@mtcute/core/utils.js'
|
import { ITelegramClient } from '../../client.types.js'
|
||||||
|
import { SentCode } from '../../types/auth/sent-code.js'
|
||||||
import { SentCode } from '../../types/index.js'
|
|
||||||
import { normalizePhoneNumber } from '../../utils/misc-utils.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
|
* @returns An object containing information about the sent confirmation code
|
||||||
*/
|
*/
|
||||||
export async function sendCode(
|
export async function sendCode(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
params: {
|
params: {
|
||||||
/** Phone number in international format */
|
/** Phone number in international format */
|
||||||
phone: string
|
phone: string
|
||||||
|
@ -18,11 +17,13 @@ export async function sendCode(
|
||||||
): Promise<SentCode> {
|
): Promise<SentCode> {
|
||||||
const phone = normalizePhoneNumber(params.phone)
|
const phone = normalizePhoneNumber(params.phone)
|
||||||
|
|
||||||
|
const { id, hash } = await client.getApiCrenetials()
|
||||||
|
|
||||||
const res = await client.call({
|
const res = await client.call({
|
||||||
_: 'auth.sendCode',
|
_: 'auth.sendCode',
|
||||||
phoneNumber: phone,
|
phoneNumber: phone,
|
||||||
apiId: client.params.apiId,
|
apiId: id,
|
||||||
apiHash: client.params.apiHash,
|
apiHash: hash,
|
||||||
settings: { _: 'codeSettings' },
|
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
|
* Send a code to email needed to recover your password
|
||||||
*
|
*
|
||||||
* @returns String containing email pattern to which the recovery code was sent
|
* @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
|
return client
|
||||||
.call({
|
.call({
|
||||||
_: 'auth.requestPasswordRecovery',
|
_: 'auth.requestPasswordRecovery',
|
|
@ -1,7 +1,6 @@
|
||||||
import { BaseTelegramClient } from '@mtcute/core'
|
import { ITelegramClient } from '../../client.types.js'
|
||||||
|
import { User } from '../../types/peers/user.js'
|
||||||
import { User } from '../../types/index.js'
|
import { _onAuthorization } from './utils.js'
|
||||||
import { _onAuthorization } from './_state.js'
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Authorize a bot using its token issued by [@BotFather](//t.me/BotFather)
|
* 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
|
* @returns Bot's {@link User} object
|
||||||
* @throws BadRequestError In case the bot token is invalid
|
* @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({
|
const res = await client.call({
|
||||||
_: 'auth.importBotAuthorization',
|
_: 'auth.importBotAuthorization',
|
||||||
flags: 0,
|
flags: 0,
|
||||||
apiId: client.params.apiId,
|
apiId: id,
|
||||||
apiHash: client.params.apiHash,
|
apiHash: hash,
|
||||||
botAuthToken: token,
|
botAuthToken: token,
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import { BaseTelegramClient } from '@mtcute/core'
|
import { ITelegramClient } from '../../client.types.js'
|
||||||
|
import { User } from '../../types/peers/user.js'
|
||||||
import { User } from '../../types/index.js'
|
|
||||||
import { normalizePhoneNumber } from '../../utils/misc-utils.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.
|
* 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
|
* @throws SessionPasswordNeededError In case a password is needed to sign in
|
||||||
*/
|
*/
|
||||||
export async function signIn(
|
export async function signIn(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
params: {
|
params: {
|
||||||
/** Phone number in international format */
|
/** Phone number in international format */
|
||||||
phone: string
|
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 { User } from '../../types/index.js'
|
||||||
import { logOut } from './log-out.js'
|
import { logOut } from './log-out.js'
|
||||||
import { start } from './start.js'
|
import { start } from './start.js'
|
||||||
|
@ -15,7 +15,7 @@ import { start } from './start.js'
|
||||||
* @param params Additional parameters
|
* @param params Additional parameters
|
||||||
*/
|
*/
|
||||||
export async function startTest(
|
export async function startTest(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
params?: {
|
params?: {
|
||||||
/**
|
/**
|
||||||
* Whether to log out if current session is logged in.
|
* 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})`)
|
throw new MtArgumentError(`${phone} has invalid DC ID (${id})`)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let dcId = client.network.getPrimaryDcId()
|
let dcId = await client.getPrimaryDcId()
|
||||||
|
|
||||||
if (params.dcId) {
|
if (params.dcId) {
|
||||||
if (!availableDcs.find((dc) => dc.id === params!.dcId)) {
|
if (!availableDcs.find((dc) => dc.id === params!.dcId)) {
|
|
@ -1,8 +1,13 @@
|
||||||
/* eslint-disable no-console */
|
/* eslint-disable no-console */
|
||||||
import { BaseTelegramClient, MaybeAsync, MtArgumentError, tl } from '@mtcute/core'
|
import { tl } from '@mtcute/tl'
|
||||||
|
|
||||||
import type { TelegramClient } from '../../client.js'
|
import { MtArgumentError } from '../../../types/errors.js'
|
||||||
import { MaybeDynamic, SentCode, User } from '../../types/index.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 { normalizePhoneNumber, resolveMaybeDynamic } from '../../utils/misc-utils.js'
|
||||||
import { getMe } from '../users/get-me.js'
|
import { getMe } from '../users/get-me.js'
|
||||||
import { checkPassword } from './check-password.js'
|
import { checkPassword } from './check-password.js'
|
||||||
|
@ -11,7 +16,6 @@ import { sendCode } from './send-code.js'
|
||||||
import { signIn } from './sign-in.js'
|
import { signIn } from './sign-in.js'
|
||||||
import { signInBot } from './sign-in-bot.js'
|
import { signInBot } from './sign-in-bot.js'
|
||||||
|
|
||||||
// @manual
|
|
||||||
// @available=both
|
// @available=both
|
||||||
/**
|
/**
|
||||||
* Start the client in an interactive and declarative manner,
|
* 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.
|
* you'll probably need to use other auth methods.
|
||||||
*/
|
*/
|
||||||
export async function start(
|
export async function start(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
params: {
|
params: {
|
||||||
/**
|
/**
|
||||||
* String session exported using {@link TelegramClient.exportSession}.
|
* 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
|
* Note that passed session will be ignored in case storage already
|
||||||
* contains authorization.
|
* contains authorization.
|
||||||
*/
|
*/
|
||||||
session?: string
|
session?: string | StringSessionData
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether to overwrite existing session.
|
* Whether to overwrite existing session.
|
||||||
|
@ -93,7 +97,7 @@ export async function start(
|
||||||
},
|
},
|
||||||
): Promise<User> {
|
): Promise<User> {
|
||||||
if (params.session) {
|
if (params.session) {
|
||||||
client.importSession(params.session, params.sessionForce)
|
await client.importSession(params.session, params.sessionForce)
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
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.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
|
return me
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -211,15 +215,3 @@ export async function start(
|
||||||
|
|
||||||
throw new MtArgumentError('Failed to log in with provided credentials')
|
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 Long from 'long'
|
||||||
import { assertTrue } from '@mtcute/core/utils.js'
|
|
||||||
|
|
||||||
|
import { assertTrue } from '../../../utils/type-assertions.js'
|
||||||
|
import { ITelegramClient } from '../../client.types.js'
|
||||||
import { CallbackQuery } from '../../types/updates/callback-query.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
|
* @param params Parameters of the answer
|
||||||
*/
|
*/
|
||||||
export async function answerCallbackQuery(
|
export async function answerCallbackQuery(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
queryId: Long | CallbackQuery,
|
queryId: Long | CallbackQuery,
|
||||||
params?: {
|
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 { BotInline, InputInlineResult } from '../../types/bots/index.js'
|
||||||
import { InlineQuery } from '../../types/updates/inline-query.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
|
* @param params Additional parameters
|
||||||
*/
|
*/
|
||||||
export async function answerInlineQuery(
|
export async function answerInlineQuery(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
queryId: tl.Long | InlineQuery,
|
queryId: tl.Long | InlineQuery,
|
||||||
results: InputInlineResult[],
|
results: InputInlineResult[],
|
||||||
params?: {
|
params?: {
|
|
@ -1,6 +1,9 @@
|
||||||
import { BaseTelegramClient, Long, tl } from '@mtcute/core'
|
import Long from 'long'
|
||||||
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 type { PreCheckoutQuery } from '../../types/updates/pre-checkout-query.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
|
* @param queryId Pre-checkout query ID
|
||||||
*/
|
*/
|
||||||
export async function answerPreCheckoutQuery(
|
export async function answerPreCheckoutQuery(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
queryId: tl.Long | PreCheckoutQuery,
|
queryId: tl.Long | PreCheckoutQuery,
|
||||||
params?: {
|
params?: {
|
||||||
/** If pre-checkout is rejected, error message to show to the user */
|
/** 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 { BotCommands } from '../../types/index.js'
|
||||||
import { _normalizeCommandScope } from './normalize-command-scope.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)
|
* Learn more about scopes in the [Bot API docs](https://core.telegram.org/bots/api#botcommandscope)
|
||||||
*/
|
*/
|
||||||
export async function deleteMyCommands(
|
export async function deleteMyCommands(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
params?: {
|
params?: {
|
||||||
/**
|
/**
|
||||||
* Scope of the commands.
|
* 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 { InputPeerLike } from '../../types/index.js'
|
||||||
import { toInputUser } from '../../utils/peer-utils.js'
|
import { toInputUser } from '../../utils/peer-utils.js'
|
||||||
import { resolvePeer } from '../users/resolve-peer.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)
|
* Gets information about a bot the current uzer owns (or the current bot)
|
||||||
*/
|
*/
|
||||||
export async function getBotInfo(
|
export async function getBotInfo(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
params: {
|
params: {
|
||||||
/**
|
/**
|
||||||
* When called by a user, a bot the user owns must be specified.
|
* 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 { InputPeerLike } from '../../types/index.js'
|
||||||
import { toInputUser } from '../../utils/peer-utils.js'
|
import { toInputUser } from '../../utils/peer-utils.js'
|
||||||
import { resolvePeer } from '../users/resolve-peer.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.
|
* 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({
|
return await client.call({
|
||||||
_: 'bots.getBotMenuButton',
|
_: 'bots.getBotMenuButton',
|
||||||
userId: toInputUser(await resolvePeer(client, user), user),
|
userId: toInputUser(await resolvePeer(client, user), user),
|
|
@ -1,6 +1,7 @@
|
||||||
import { BaseTelegramClient, tl } from '@mtcute/core'
|
import { tl } from '@mtcute/tl'
|
||||||
import { computeSrpParams, utf8EncodeToBuffer } from '@mtcute/core/utils.js'
|
import { utf8EncodeToBuffer } from '@mtcute/tl-runtime'
|
||||||
|
|
||||||
|
import { ITelegramClient } from '../../client.types.js'
|
||||||
import { InputMessageId, normalizeInputMessageId } from '../../types/index.js'
|
import { InputMessageId, normalizeInputMessageId } from '../../types/index.js'
|
||||||
import { resolvePeer } from '../users/resolve-peer.js'
|
import { resolvePeer } from '../users/resolve-peer.js'
|
||||||
|
|
||||||
|
@ -11,7 +12,7 @@ import { resolvePeer } from '../users/resolve-peer.js'
|
||||||
* @param params
|
* @param params
|
||||||
*/
|
*/
|
||||||
export async function getCallbackAnswer(
|
export async function getCallbackAnswer(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
params: InputMessageId & {
|
params: InputMessageId & {
|
||||||
/** Data contained in the button */
|
/** Data contained in the button */
|
||||||
data: string | Uint8Array
|
data: string | Uint8Array
|
||||||
|
@ -44,7 +45,7 @@ export async function getCallbackAnswer(
|
||||||
|
|
||||||
if (params?.password) {
|
if (params?.password) {
|
||||||
const pwd = await client.call({ _: 'account.getPassword' })
|
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(
|
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 { GameHighScore, InputMessageId, InputPeerLike, normalizeInputMessageId, PeersIndex } from '../../types/index.js'
|
||||||
import { normalizeInlineId } from '../../utils/inline-utils.js'
|
import { normalizeInlineId } from '../../utils/inline-utils.js'
|
||||||
import { toInputUser } from '../../utils/peer-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
|
* Get high scores of a game
|
||||||
*/
|
*/
|
||||||
export async function getGameHighScores(
|
export async function getGameHighScores(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
params: InputMessageId & {
|
params: InputMessageId & {
|
||||||
/** ID of the user to find high scores for */
|
/** ID of the user to find high scores for */
|
||||||
userId?: InputPeerLike
|
userId?: InputPeerLike
|
||||||
|
@ -47,7 +48,7 @@ export async function getGameHighScores(
|
||||||
* @param userId ID of the user to find high scores for
|
* @param userId ID of the user to find high scores for
|
||||||
*/
|
*/
|
||||||
export async function getInlineGameHighScores(
|
export async function getInlineGameHighScores(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
messageId: string | tl.TypeInputBotInlineMessageID,
|
messageId: string | tl.TypeInputBotInlineMessageID,
|
||||||
userId?: InputPeerLike,
|
userId?: InputPeerLike,
|
||||||
): Promise<GameHighScore[]> {
|
): 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 { BotCommands } from '../../types/index.js'
|
||||||
import { _normalizeCommandScope } from './normalize-command-scope.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)
|
* Learn more about scopes in the [Bot API docs](https://core.telegram.org/bots/api#botcommandscope)
|
||||||
*/
|
*/
|
||||||
export async function getMyCommands(
|
export async function getMyCommands(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
params?: {
|
params?: {
|
||||||
/**
|
/**
|
||||||
* Scope of the commands.
|
* 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 { BotCommands } from '../../types/index.js'
|
||||||
import { toInputUser } from '../../utils/peer-utils.js'
|
import { toInputUser } from '../../utils/peer-utils.js'
|
||||||
import { resolvePeer } from '../users/resolve-peer.js'
|
import { resolvePeer } from '../users/resolve-peer.js'
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
export async function _normalizeCommandScope(
|
export async function _normalizeCommandScope(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
scope: tl.TypeBotCommandScope | BotCommands.IntermediateScope,
|
scope: tl.TypeBotCommandScope | BotCommands.IntermediateScope,
|
||||||
): Promise<tl.TypeBotCommandScope> {
|
): Promise<tl.TypeBotCommandScope> {
|
||||||
if (tl.isAnyBotCommandScope(scope)) return scope
|
if (tl.isAnyBotCommandScope(scope)) return scope
|
|
@ -1,6 +1,5 @@
|
||||||
import { BaseTelegramClient } from '@mtcute/core'
|
import { assertTrue } from '../../../utils/type-assertions.js'
|
||||||
import { assertTrue } from '@mtcute/core/utils.js'
|
import { ITelegramClient } from '../../client.types.js'
|
||||||
|
|
||||||
import { InputPeerLike } from '../../types/index.js'
|
import { InputPeerLike } from '../../types/index.js'
|
||||||
import { toInputUser } from '../../utils/peer-utils.js'
|
import { toInputUser } from '../../utils/peer-utils.js'
|
||||||
import { resolvePeer } from '../users/resolve-peer.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)
|
* Sets information about a bot the current uzer owns (or the current bot)
|
||||||
*/
|
*/
|
||||||
export async function setBotInfo(
|
export async function setBotInfo(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
params: {
|
params: {
|
||||||
/**
|
/**
|
||||||
* When called by a user, a bot the user owns must be specified.
|
* When called by a user, a bot the user owns must be specified.
|
|
@ -1,6 +1,7 @@
|
||||||
import { BaseTelegramClient, tl } from '@mtcute/core'
|
import { tl } from '@mtcute/tl'
|
||||||
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 { InputPeerLike } from '../../types/index.js'
|
||||||
import { toInputUser } from '../../utils/peer-utils.js'
|
import { toInputUser } from '../../utils/peer-utils.js'
|
||||||
import { resolvePeer } from '../users/resolve-peer.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.
|
* Sets a menu button for the given user.
|
||||||
*/
|
*/
|
||||||
export async function setBotMenuButton(
|
export async function setBotMenuButton(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
user: InputPeerLike,
|
user: InputPeerLike,
|
||||||
button: tl.TypeBotMenuButton,
|
button: tl.TypeBotMenuButton,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
|
@ -1,6 +1,7 @@
|
||||||
import { BaseTelegramClient, tl } from '@mtcute/core'
|
import { tl } from '@mtcute/tl'
|
||||||
import { assertTrue } from '@mtcute/core/utils.js'
|
|
||||||
|
|
||||||
|
import { assertTrue } from '../../../utils/type-assertions.js'
|
||||||
|
import { ITelegramClient } from '../../client.types.js'
|
||||||
import { InputMessageId, InputPeerLike, Message, normalizeInputMessageId } from '../../types/index.js'
|
import { InputMessageId, InputPeerLike, Message, normalizeInputMessageId } from '../../types/index.js'
|
||||||
import { normalizeInlineId } from '../../utils/inline-utils.js'
|
import { normalizeInlineId } from '../../utils/inline-utils.js'
|
||||||
import { toInputUser } from '../../utils/peer-utils.js'
|
import { toInputUser } from '../../utils/peer-utils.js'
|
||||||
|
@ -14,7 +15,7 @@ import { resolvePeer } from '../users/resolve-peer.js'
|
||||||
* @returns The modified message
|
* @returns The modified message
|
||||||
*/
|
*/
|
||||||
export async function setGameScore(
|
export async function setGameScore(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
params: InputMessageId & {
|
params: InputMessageId & {
|
||||||
/** ID of the user who has scored */
|
/** ID of the user who has scored */
|
||||||
userId: InputPeerLike
|
userId: InputPeerLike
|
||||||
|
@ -67,7 +68,7 @@ export async function setGameScore(
|
||||||
* @param params
|
* @param params
|
||||||
*/
|
*/
|
||||||
export async function setInlineGameScore(
|
export async function setInlineGameScore(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
params: {
|
params: {
|
||||||
/** ID of the inline message */
|
/** ID of the inline message */
|
||||||
messageId: string | tl.TypeInputBotInlineMessageID
|
messageId: string | tl.TypeInputBotInlineMessageID
|
|
@ -1,6 +1,7 @@
|
||||||
import { BaseTelegramClient, tl } from '@mtcute/core'
|
import { tl } from '@mtcute/tl'
|
||||||
import { assertTrue } from '@mtcute/core/utils.js'
|
|
||||||
|
|
||||||
|
import { assertTrue } from '../../../utils/type-assertions.js'
|
||||||
|
import { ITelegramClient } from '../../client.types.js'
|
||||||
import { BotCommands } from '../../types/index.js'
|
import { BotCommands } from '../../types/index.js'
|
||||||
import { _normalizeCommandScope } from './normalize-command-scope.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)
|
* Learn more about scopes in the [Bot API docs](https://core.telegram.org/bots/api#botcommandscope)
|
||||||
*/
|
*/
|
||||||
export async function setMyCommands(
|
export async function setMyCommands(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
params: {
|
params: {
|
||||||
/**
|
/**
|
||||||
* New list of bot commands for the given scope.
|
* New list of bot commands for the given scope.
|
|
@ -1,11 +1,13 @@
|
||||||
import { BaseTelegramClient, tl } from '@mtcute/core'
|
import { tl } from '@mtcute/tl'
|
||||||
import { assertTrue } from '@mtcute/core/utils.js'
|
|
||||||
|
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.
|
* Sets the default chat permissions for the bot in the supergroup or channel.
|
||||||
*/
|
*/
|
||||||
export async function setMyDefaultRights(
|
export async function setMyDefaultRights(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
params: {
|
params: {
|
||||||
/** Whether to target groups or channels. */
|
/** Whether to target groups or channels. */
|
||||||
target: 'channel' | 'group'
|
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 { InputPeerLike, MtInvalidPeerTypeError } from '../../types/index.js'
|
||||||
import { isInputPeerChannel, isInputPeerChat, toInputChannel, toInputUser } from '../../utils/peer-utils.js'
|
import { isInputPeerChannel, isInputPeerChat, toInputChannel, toInputUser } from '../../utils/peer-utils.js'
|
||||||
import { resolvePeer } from '../users/resolve-peer.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
|
* @param users ID(s) of the user(s) to add
|
||||||
*/
|
*/
|
||||||
export async function addChatMembers(
|
export async function addChatMembers(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
chatId: InputPeerLike,
|
chatId: InputPeerLike,
|
||||||
users: MaybeArray<InputPeerLike>,
|
users: MaybeArray<InputPeerLike>,
|
||||||
params: {
|
params: {
|
||||||
|
@ -41,7 +41,7 @@ export async function addChatMembers(
|
||||||
userId: p,
|
userId: p,
|
||||||
fwdLimit: forwardCount,
|
fwdLimit: forwardCount,
|
||||||
})
|
})
|
||||||
client.network.handleUpdate(updates)
|
client.handleClientUpdate(updates)
|
||||||
}
|
}
|
||||||
} else if (isInputPeerChannel(chat)) {
|
} else if (isInputPeerChannel(chat)) {
|
||||||
const updates = await client.call({
|
const updates = await client.call({
|
||||||
|
@ -49,7 +49,6 @@ export async function addChatMembers(
|
||||||
channel: toInputChannel(chat),
|
channel: toInputChannel(chat),
|
||||||
users: await resolvePeerMany(client, users, toInputUser),
|
users: await resolvePeerMany(client, users, toInputUser),
|
||||||
})
|
})
|
||||||
|
client.handleClientUpdate(updates)
|
||||||
client.network.handleUpdate(updates)
|
|
||||||
} else throw new MtInvalidPeerTypeError(chatId, 'chat or channel')
|
} 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 { InputPeerLike } from '../../types/index.js'
|
||||||
import { resolvePeerMany } from '../users/resolve-peer-many.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"`
|
* @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]
|
if (!Array.isArray(chats)) chats = [chats]
|
||||||
|
|
||||||
const resolvedPeers = await resolvePeerMany(client, chats)
|
const resolvedPeers = await resolvePeerMany(client, chats)
|
||||||
|
@ -21,5 +21,5 @@ export async function archiveChats(client: BaseTelegramClient, chats: MaybeArray
|
||||||
folderId: 1,
|
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 { InputPeerLike, Message, MtInvalidPeerTypeError } from '../../types/index.js'
|
||||||
import { isInputPeerChannel, isInputPeerChat, toInputChannel, toInputUser } from '../../utils/peer-utils.js'
|
import { isInputPeerChannel, isInputPeerChat, toInputChannel, toInputUser } from '../../utils/peer-utils.js'
|
||||||
import { _findMessageInUpdate } from '../messages/find-in-update.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.
|
* @returns Service message about removed user, if one was generated.
|
||||||
*/
|
*/
|
||||||
export async function banChatMember(
|
export async function banChatMember(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
params: {
|
params: {
|
||||||
/** Chat ID */
|
/** Chat ID */
|
||||||
chatId: InputPeerLike
|
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 {
|
import {
|
||||||
isInputPeerChannel,
|
isInputPeerChannel,
|
||||||
isInputPeerChat,
|
isInputPeerChat,
|
||||||
|
@ -129,7 +131,7 @@ export const _getChannelsBatched = batchedQuery<tl.TypeInputChannel, tl.RawChann
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
export function _getRawPeerBatched(
|
export function _getRawPeerBatched(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
peer: tl.TypeInputPeer,
|
peer: tl.TypeInputPeer,
|
||||||
): Promise<tl.TypeUser | tl.TypeChat | null> {
|
): Promise<tl.TypeUser | tl.TypeChat | null> {
|
||||||
if (isInputPeerUser(peer)) {
|
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 { Chat } from '../../types/index.js'
|
||||||
import { assertIsUpdatesGroup } from '../../utils/updates-utils.js'
|
import { assertIsUpdatesGroup } from '../../updates/utils.js'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new broadcast channel
|
* Create a new broadcast channel
|
||||||
|
@ -9,7 +8,7 @@ import { assertIsUpdatesGroup } from '../../utils/updates-utils.js'
|
||||||
* @returns Newly created channel
|
* @returns Newly created channel
|
||||||
*/
|
*/
|
||||||
export async function createChannel(
|
export async function createChannel(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
params: {
|
params: {
|
||||||
/**
|
/**
|
||||||
* Channel title
|
* Channel title
|
||||||
|
@ -33,7 +32,7 @@ export async function createChannel(
|
||||||
|
|
||||||
assertIsUpdatesGroup('channels.createChannel', res)
|
assertIsUpdatesGroup('channels.createChannel', res)
|
||||||
|
|
||||||
client.network.handleUpdate(res)
|
client.handleClientUpdate(res)
|
||||||
|
|
||||||
return new Chat(res.chats[0])
|
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 { Chat, InputPeerLike } from '../../types/index.js'
|
||||||
|
import { assertIsUpdatesGroup } from '../../updates/utils.js'
|
||||||
import { toInputUser } from '../../utils/peer-utils.js'
|
import { toInputUser } from '../../utils/peer-utils.js'
|
||||||
import { assertIsUpdatesGroup } from '../../utils/updates-utils.js'
|
|
||||||
import { resolvePeerMany } from '../users/resolve-peer-many.js'
|
import { resolvePeerMany } from '../users/resolve-peer-many.js'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -12,7 +12,7 @@ import { resolvePeerMany } from '../users/resolve-peer-many.js'
|
||||||
* instead.
|
* instead.
|
||||||
*/
|
*/
|
||||||
export async function createGroup(
|
export async function createGroup(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
params: {
|
params: {
|
||||||
/**
|
/**
|
||||||
* Group title
|
* Group title
|
||||||
|
@ -48,7 +48,7 @@ export async function createGroup(
|
||||||
|
|
||||||
assertIsUpdatesGroup('messages.createChat', res)
|
assertIsUpdatesGroup('messages.createChat', res)
|
||||||
|
|
||||||
client.network.handleUpdate(res)
|
client.handleClientUpdate(res)
|
||||||
|
|
||||||
return new Chat(res.chats[0])
|
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 { Chat } from '../../types/index.js'
|
||||||
import { assertIsUpdatesGroup } from '../../utils/updates-utils.js'
|
import { assertIsUpdatesGroup } from '../../updates/utils.js'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new supergroup
|
* Create a new supergroup
|
||||||
|
@ -9,7 +8,7 @@ import { assertIsUpdatesGroup } from '../../utils/updates-utils.js'
|
||||||
* @returns Newly created supergroup
|
* @returns Newly created supergroup
|
||||||
*/
|
*/
|
||||||
export async function createSupergroup(
|
export async function createSupergroup(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
params: {
|
params: {
|
||||||
/**
|
/**
|
||||||
* Supergroup title
|
* Supergroup title
|
||||||
|
@ -47,7 +46,7 @@ export async function createSupergroup(
|
||||||
|
|
||||||
assertIsUpdatesGroup('channels.createChannel', res)
|
assertIsUpdatesGroup('channels.createChannel', res)
|
||||||
|
|
||||||
client.network.handleUpdate(res)
|
client.handleClientUpdate(res)
|
||||||
|
|
||||||
return new Chat(res.chats[0])
|
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 { InputPeerLike } from '../../types/index.js'
|
||||||
import { toInputChannel } from '../../utils/peer-utils.js'
|
import { toInputChannel } from '../../utils/peer-utils.js'
|
||||||
import { resolvePeer } from '../users/resolve-peer.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
|
* @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({
|
const res = await client.call({
|
||||||
_: 'channels.deleteChannel',
|
_: 'channels.deleteChannel',
|
||||||
channel: toInputChannel(await resolvePeer(client, chatId), chatId),
|
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 { InputPeerLike, MtInvalidPeerTypeError } from '../../types/index.js'
|
||||||
import { isInputPeerChannel, isInputPeerChat, toInputChannel } from '../../utils/peer-utils.js'
|
import { isInputPeerChannel, isInputPeerChat, toInputChannel } from '../../utils/peer-utils.js'
|
||||||
import { resolvePeer } from '../users/resolve-peer.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
|
* @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)
|
const chat = await resolvePeer(client, chatId)
|
||||||
|
|
||||||
let res
|
let res
|
||||||
|
@ -29,5 +28,5 @@ export async function deleteChatPhoto(client: BaseTelegramClient, chatId: InputP
|
||||||
})
|
})
|
||||||
} else throw new MtInvalidPeerTypeError(chatId, 'chat or channel')
|
} 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 '../../../utils/type-assertions.js'
|
||||||
import { assertTrue } from '@mtcute/core/utils.js'
|
import { ITelegramClient } from '../../client.types.js'
|
||||||
|
|
||||||
import { InputPeerLike, MtInvalidPeerTypeError } from '../../types/index.js'
|
import { InputPeerLike, MtInvalidPeerTypeError } from '../../types/index.js'
|
||||||
import { isInputPeerChat } from '../../utils/peer-utils.js'
|
import { isInputPeerChat } from '../../utils/peer-utils.js'
|
||||||
import { resolvePeer } from '../users/resolve-peer.js'
|
import { resolvePeer } from '../users/resolve-peer.js'
|
||||||
|
@ -10,7 +9,7 @@ import { resolvePeer } from '../users/resolve-peer.js'
|
||||||
*
|
*
|
||||||
* @param chatId Chat ID
|
* @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)
|
const chat = await resolvePeer(client, chatId)
|
||||||
if (!isInputPeerChat(chat)) throw new MtInvalidPeerTypeError(chatId, 'chat')
|
if (!isInputPeerChat(chat)) throw new MtInvalidPeerTypeError(chatId, 'chat')
|
||||||
|
|
||||||
|
@ -20,7 +19,7 @@ export async function deleteGroup(client: BaseTelegramClient, chatId: InputPeerL
|
||||||
chatId: chat.chatId,
|
chatId: chat.chatId,
|
||||||
userId: { _: 'inputUserSelf' },
|
userId: { _: 'inputUserSelf' },
|
||||||
})
|
})
|
||||||
client.network.handleUpdate(res)
|
client.handleClientUpdate(res)
|
||||||
|
|
||||||
const r = await client.call({
|
const r = await client.call({
|
||||||
_: 'messages.deleteChat',
|
_: 'messages.deleteChat',
|
|
@ -1,15 +1,14 @@
|
||||||
import { BaseTelegramClient } from '@mtcute/core'
|
import { ITelegramClient } from '../../client.types.js'
|
||||||
|
|
||||||
import { InputPeerLike } from '../../types/index.js'
|
import { InputPeerLike } from '../../types/index.js'
|
||||||
|
import { createDummyUpdate } from '../../updates/utils.js'
|
||||||
import { isInputPeerChannel } from '../../utils/peer-utils.js'
|
import { isInputPeerChannel } from '../../utils/peer-utils.js'
|
||||||
import { createDummyUpdate } from '../../utils/updates-utils.js'
|
|
||||||
import { resolvePeer } from '../users/resolve-peer.js'
|
import { resolvePeer } from '../users/resolve-peer.js'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete communication history (for private chats and legacy groups)
|
* Delete communication history (for private chats and legacy groups)
|
||||||
*/
|
*/
|
||||||
export async function deleteHistory(
|
export async function deleteHistory(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
chat: InputPeerLike,
|
chat: InputPeerLike,
|
||||||
params?: {
|
params?: {
|
||||||
/**
|
/**
|
||||||
|
@ -45,8 +44,8 @@ export async function deleteHistory(
|
||||||
})
|
})
|
||||||
|
|
||||||
if (isInputPeerChannel(peer)) {
|
if (isInputPeerChannel(peer)) {
|
||||||
client.network.handleUpdate(createDummyUpdate(res.pts, res.ptsCount, peer.channelId))
|
client.handleClientUpdate(createDummyUpdate(res.pts, res.ptsCount, peer.channelId))
|
||||||
} else {
|
} 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 { InputPeerLike } from '../../types/index.js'
|
||||||
|
import { createDummyUpdate } from '../../updates/utils.js'
|
||||||
import { toInputChannel } from '../../utils/peer-utils.js'
|
import { toInputChannel } from '../../utils/peer-utils.js'
|
||||||
import { createDummyUpdate } from '../../utils/updates-utils.js'
|
|
||||||
import { resolvePeer } from '../users/resolve-peer.js'
|
import { resolvePeer } from '../users/resolve-peer.js'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete all messages of a user (or channel) in a supergroup
|
* Delete all messages of a user (or channel) in a supergroup
|
||||||
*/
|
*/
|
||||||
export async function deleteUserHistory(
|
export async function deleteUserHistory(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
params: {
|
params: {
|
||||||
/** Chat ID */
|
/** Chat ID */
|
||||||
chatId: InputPeerLike
|
chatId: InputPeerLike
|
||||||
|
@ -29,5 +30,5 @@ export async function deleteUserHistory(
|
||||||
participant: peer,
|
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 { InputPeerLike } from '../../types/index.js'
|
||||||
import { toInputChannel, toInputUser } from '../../utils/peer-utils.js'
|
import { toInputChannel, toInputUser } from '../../utils/peer-utils.js'
|
||||||
import { resolvePeer } from '../users/resolve-peer.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.
|
* Edit supergroup/channel admin rights of a user.
|
||||||
*/
|
*/
|
||||||
export async function editAdminRights(
|
export async function editAdminRights(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
params: {
|
params: {
|
||||||
/** Chat ID */
|
/** Chat ID */
|
||||||
chatId: InputPeerLike
|
chatId: InputPeerLike
|
||||||
|
@ -36,5 +37,5 @@ export async function editAdminRights(
|
||||||
rank,
|
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 { ChatEvent, InputPeerLike, PeersIndex } from '../../types/index.js'
|
||||||
import { InputChatEventFilters, normalizeChatEventFilters } from '../../types/peers/chat-event/filters.js'
|
import { InputChatEventFilters, normalizeChatEventFilters } from '../../types/peers/chat-event/filters.js'
|
||||||
import { toInputChannel, toInputUser } from '../../utils/peer-utils.js'
|
import { toInputChannel, toInputUser } from '../../utils/peer-utils.js'
|
||||||
|
@ -20,7 +23,7 @@ import { resolvePeerMany } from '../users/resolve-peer-many.js'
|
||||||
* @param params
|
* @param params
|
||||||
*/
|
*/
|
||||||
export async function getChatEventLog(
|
export async function getChatEventLog(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
chatId: InputPeerLike,
|
chatId: InputPeerLike,
|
||||||
params?: {
|
params?: {
|
||||||
/**
|
/**
|
|
@ -1,6 +1,7 @@
|
||||||
import { BaseTelegramClient, tl } from '@mtcute/core'
|
import { tl } from '@mtcute/tl'
|
||||||
import { assertTypeIs } from '@mtcute/core/utils.js'
|
|
||||||
|
|
||||||
|
import { assertTypeIs } from '../../../utils/type-assertions.js'
|
||||||
|
import { ITelegramClient } from '../../client.types.js'
|
||||||
import { ChatMember, InputPeerLike, MtInvalidPeerTypeError, PeersIndex } from '../../types/index.js'
|
import { ChatMember, InputPeerLike, MtInvalidPeerTypeError, PeersIndex } from '../../types/index.js'
|
||||||
import { isInputPeerChannel, isInputPeerChat, isInputPeerUser, toInputChannel } from '../../utils/peer-utils.js'
|
import { isInputPeerChannel, isInputPeerChat, isInputPeerUser, toInputChannel } from '../../utils/peer-utils.js'
|
||||||
import { resolvePeer } from '../users/resolve-peer.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
|
* @returns Chat member, or `null` if user is not a member of the chat
|
||||||
*/
|
*/
|
||||||
export async function getChatMember(
|
export async function getChatMember(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
params: {
|
params: {
|
||||||
/** Chat ID or username */
|
/** Chat ID or username */
|
||||||
chatId: InputPeerLike
|
chatId: InputPeerLike
|
|
@ -1,6 +1,10 @@
|
||||||
import { assertNever, BaseTelegramClient, Long, tl } from '@mtcute/core'
|
import Long from 'long'
|
||||||
import { assertTypeIs } from '@mtcute/core/utils.js'
|
|
||||||
|
|
||||||
|
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 { ArrayWithTotal, ChatMember, InputPeerLike, MtInvalidPeerTypeError, PeersIndex } from '../../types/index.js'
|
||||||
import { makeArrayWithTotal } from '../../utils/index.js'
|
import { makeArrayWithTotal } from '../../utils/index.js'
|
||||||
import { isInputPeerChannel, isInputPeerChat, toInputChannel } from '../../utils/peer-utils.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
|
* @param params Additional parameters
|
||||||
*/
|
*/
|
||||||
export async function getChatMembers(
|
export async function getChatMembers(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
chatId: InputPeerLike,
|
chatId: InputPeerLike,
|
||||||
params?: {
|
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 { ChatPreview, MtPeerNotFoundError } from '../../types/index.js'
|
||||||
import { INVITE_LINK_REGEX } from '../../utils/peer-utils.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.
|
* In case you are trying to get info about private chat that you have already joined.
|
||||||
* Use {@link getChat} or {@link getFullChat} instead.
|
* 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)
|
const m = inviteLink.match(INVITE_LINK_REGEX)
|
||||||
if (!m) throw new MtArgumentError('Invalid invite link')
|
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 { Chat, InputPeerLike, MtPeerNotFoundError } from '../../types/index.js'
|
||||||
import { INVITE_LINK_REGEX } from '../../utils/peer-utils.js'
|
import { INVITE_LINK_REGEX } from '../../utils/peer-utils.js'
|
||||||
import { resolvePeer } from '../users/resolve-peer.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.
|
* In case you are trying to get info about private chat that you haven't joined.
|
||||||
* Use {@link getChatPreview} instead.
|
* 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') {
|
if (typeof chatId === 'string') {
|
||||||
const m = chatId.match(INVITE_LINK_REGEX)
|
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 { Chat, InputPeerLike } from '../../types/index.js'
|
||||||
import {
|
import {
|
||||||
INVITE_LINK_REGEX,
|
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.
|
* In case you are trying to get info about private chat that you haven't joined.
|
||||||
* Use {@link getChatPreview} instead.
|
* 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') {
|
if (typeof chatId === 'string') {
|
||||||
const m = chatId.match(INVITE_LINK_REGEX)
|
const m = chatId.match(INVITE_LINK_REGEX)
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
import { BaseTelegramClient, getMarkedPeerId, tl } from '@mtcute/core'
|
import { tl } from '@mtcute/tl'
|
||||||
import { assertTypeIs } from '@mtcute/core/utils.js'
|
|
||||||
|
|
||||||
|
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 { Chat } from '../../types/index.js'
|
||||||
import { assertIsUpdatesGroup } from '../../utils/updates-utils.js'
|
import { assertIsUpdatesGroup } from '../../updates/utils.js'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get nearby chats
|
* Get nearby chats
|
||||||
|
@ -10,7 +12,7 @@ import { assertIsUpdatesGroup } from '../../utils/updates-utils.js'
|
||||||
* @param latitude Latitude of the location
|
* @param latitude Latitude of the location
|
||||||
* @param longitude Longitude 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({
|
const res = await client.call({
|
||||||
_: 'contacts.getLocated',
|
_: 'contacts.getLocated',
|
||||||
geoPoint: {
|
geoPoint: {
|
||||||
|
@ -21,7 +23,7 @@ export async function getNearbyChats(client: BaseTelegramClient, latitude: numbe
|
||||||
})
|
})
|
||||||
|
|
||||||
assertIsUpdatesGroup('contacts.getLocated', res)
|
assertIsUpdatesGroup('contacts.getLocated', res)
|
||||||
client.network.handleUpdate(res, true)
|
// client.handleClientUpdate(res, true)
|
||||||
|
|
||||||
if (!res.updates.length) return []
|
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 { ArrayWithTotal, Chat, InputPeerLike } from '../../types/index.js'
|
||||||
import { makeArrayWithTotal } from '../../utils/misc-utils.js'
|
import { makeArrayWithTotal } from '../../utils/misc-utils.js'
|
||||||
import { toInputChannel } from '../../utils/peer-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.
|
* > Returns empty array in case there are no similar channels available.
|
||||||
*/
|
*/
|
||||||
export async function getSimilarChannels(
|
export async function getSimilarChannels(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
channel: InputPeerLike,
|
channel: InputPeerLike,
|
||||||
): Promise<ArrayWithTotal<Chat>> {
|
): Promise<ArrayWithTotal<Chat>> {
|
||||||
const res = await client.call({
|
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 { ChatEvent, InputPeerLike } from '../../types/index.js'
|
||||||
import { normalizeChatEventFilters } from '../../types/peers/chat-event/filters.js'
|
import { normalizeChatEventFilters } from '../../types/peers/chat-event/filters.js'
|
||||||
import { toInputChannel, toInputUser } from '../../utils/peer-utils.js'
|
import { toInputChannel, toInputUser } from '../../utils/peer-utils.js'
|
||||||
|
@ -16,7 +19,7 @@ import { getChatEventLog } from './get-chat-event-log.js'
|
||||||
* @param params
|
* @param params
|
||||||
*/
|
*/
|
||||||
export async function* iterChatEventLog(
|
export async function* iterChatEventLog(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
chatId: InputPeerLike,
|
chatId: InputPeerLike,
|
||||||
params?: Parameters<typeof getChatEventLog>[2] & {
|
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 { ChatMember, InputPeerLike } from '../../types/index.js'
|
||||||
import { isInputPeerChat } from '../../utils/peer-utils.js'
|
import { isInputPeerChat } from '../../utils/peer-utils.js'
|
||||||
import { resolvePeer } from '../users/resolve-peer.js'
|
import { resolvePeer } from '../users/resolve-peer.js'
|
||||||
|
@ -16,7 +15,7 @@ import { getChatMembers } from './get-chat-members.js'
|
||||||
* @param params Additional parameters
|
* @param params Additional parameters
|
||||||
*/
|
*/
|
||||||
export async function* iterChatMembers(
|
export async function* iterChatMembers(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
chatId: InputPeerLike,
|
chatId: InputPeerLike,
|
||||||
params?: Parameters<typeof getChatMembers>[2] & {
|
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 { Chat, InputPeerLike } from '../../types/index.js'
|
||||||
|
import { assertIsUpdatesGroup } from '../../updates/utils.js'
|
||||||
import { INVITE_LINK_REGEX, toInputChannel } from '../../utils/peer-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'
|
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`)
|
* Chat identifier. Either an invite link (`t.me/joinchat/*`), a username (`@username`)
|
||||||
* or ID of the linked supergroup or channel.
|
* 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') {
|
if (typeof chatId === 'string') {
|
||||||
const m = chatId.match(INVITE_LINK_REGEX)
|
const m = chatId.match(INVITE_LINK_REGEX)
|
||||||
|
|
||||||
|
@ -27,7 +26,7 @@ export async function joinChat(client: BaseTelegramClient, chatId: InputPeerLike
|
||||||
})
|
})
|
||||||
assertIsUpdatesGroup('messages.importChatInvite', res)
|
assertIsUpdatesGroup('messages.importChatInvite', res)
|
||||||
|
|
||||||
client.network.handleUpdate(res)
|
client.handleClientUpdate(res)
|
||||||
|
|
||||||
return new Chat(res.chats[0])
|
return new Chat(res.chats[0])
|
||||||
}
|
}
|
||||||
|
@ -40,7 +39,7 @@ export async function joinChat(client: BaseTelegramClient, chatId: InputPeerLike
|
||||||
|
|
||||||
assertIsUpdatesGroup('channels.joinChannel', res)
|
assertIsUpdatesGroup('channels.joinChannel', res)
|
||||||
|
|
||||||
client.network.handleUpdate(res)
|
client.handleClientUpdate(res)
|
||||||
|
|
||||||
return new Chat(res.chats[0])
|
return new Chat(res.chats[0])
|
||||||
}
|
}
|
|
@ -1,6 +1,5 @@
|
||||||
import { BaseTelegramClient } from '@mtcute/core'
|
import { sleep } from '../../../utils/misc-utils.js'
|
||||||
import { sleep } from '@mtcute/core/utils.js'
|
import { ITelegramClient } from '../../client.types.js'
|
||||||
|
|
||||||
import { InputPeerLike, Message } from '../../types/index.js'
|
import { InputPeerLike, Message } from '../../types/index.js'
|
||||||
import { isInputPeerChannel } from '../../utils/peer-utils.js'
|
import { isInputPeerChannel } from '../../utils/peer-utils.js'
|
||||||
import { resolvePeer } from '../users/resolve-peer.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.
|
* @returns Service message about removed user, if one was generated.
|
||||||
*/
|
*/
|
||||||
export async function kickChatMember(
|
export async function kickChatMember(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
params: {
|
params: {
|
||||||
/** Chat ID */
|
/** Chat ID */
|
||||||
chatId: InputPeerLike
|
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 { InputPeerLike, MtInvalidPeerTypeError } from '../../types/index.js'
|
||||||
import { isInputPeerChannel, isInputPeerChat, toInputChannel } from '../../utils/peer-utils.js'
|
import { isInputPeerChannel, isInputPeerChat, toInputChannel } from '../../utils/peer-utils.js'
|
||||||
import { resolvePeer } from '../users/resolve-peer.js'
|
import { resolvePeer } from '../users/resolve-peer.js'
|
||||||
|
@ -11,7 +10,7 @@ import { deleteHistory } from './delete-history.js'
|
||||||
* @param chatId Chat ID or username
|
* @param chatId Chat ID or username
|
||||||
*/
|
*/
|
||||||
export async function leaveChat(
|
export async function leaveChat(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
chatId: InputPeerLike,
|
chatId: InputPeerLike,
|
||||||
params?: {
|
params?: {
|
||||||
/**
|
/**
|
||||||
|
@ -27,14 +26,14 @@ export async function leaveChat(
|
||||||
_: 'channels.leaveChannel',
|
_: 'channels.leaveChannel',
|
||||||
channel: toInputChannel(chat),
|
channel: toInputChannel(chat),
|
||||||
})
|
})
|
||||||
client.network.handleUpdate(res)
|
client.handleClientUpdate(res)
|
||||||
} else if (isInputPeerChat(chat)) {
|
} else if (isInputPeerChat(chat)) {
|
||||||
const res = await client.call({
|
const res = await client.call({
|
||||||
_: 'messages.deleteChatUser',
|
_: 'messages.deleteChatUser',
|
||||||
chatId: chat.chatId,
|
chatId: chat.chatId,
|
||||||
userId: { _: 'inputUserSelf' },
|
userId: { _: 'inputUserSelf' },
|
||||||
})
|
})
|
||||||
client.network.handleUpdate(res)
|
client.handleClientUpdate(res)
|
||||||
|
|
||||||
if (params?.clear) {
|
if (params?.clear) {
|
||||||
await deleteHistory(client, chat)
|
await deleteHistory(client, chat)
|
|
@ -1,6 +1,5 @@
|
||||||
import { BaseTelegramClient } from '@mtcute/core'
|
import { assertTrue } from '../../../utils/type-assertions.js'
|
||||||
import { assertTrue } from '@mtcute/core/utils.js'
|
import { ITelegramClient } from '../../client.types.js'
|
||||||
|
|
||||||
import { InputPeerLike } from '../../types/index.js'
|
import { InputPeerLike } from '../../types/index.js'
|
||||||
import { resolvePeer } from '../users/resolve-peer.js'
|
import { resolvePeer } from '../users/resolve-peer.js'
|
||||||
|
|
||||||
|
@ -9,7 +8,7 @@ import { resolvePeer } from '../users/resolve-peer.js'
|
||||||
*
|
*
|
||||||
* @param chatId Chat ID
|
* @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({
|
const r = await client.call({
|
||||||
_: 'messages.markDialogUnread',
|
_: 'messages.markDialogUnread',
|
||||||
peer: {
|
peer: {
|
|
@ -1,9 +1,7 @@
|
||||||
import { BaseTelegramClient } from '@mtcute/core'
|
import { ITelegramClient } from '../../client.types.js'
|
||||||
|
|
||||||
import { InputPeerLike } from '../../types/peers/index.js'
|
import { InputPeerLike } from '../../types/peers/index.js'
|
||||||
import { isInputPeerChannel } from '../../utils/peer-utils.js'
|
import { isInputPeerChannel } from '../../utils/peer-utils.js'
|
||||||
import { getPeerDialogs } from '../dialogs/get-peer-dialogs.js'
|
import { getPeerDialogs } from '../dialogs/get-peer-dialogs.js'
|
||||||
import { notifyChannelClosed, notifyChannelOpened } from '../updates/manager.js'
|
|
||||||
import { resolvePeer } from '../users/resolve-peer.js'
|
import { resolvePeer } from '../users/resolve-peer.js'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -14,15 +12,13 @@ import { resolvePeer } from '../users/resolve-peer.js'
|
||||||
*
|
*
|
||||||
* @param chat Chat to open
|
* @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)
|
const peer = await resolvePeer(client, chat)
|
||||||
|
|
||||||
if (isInputPeerChannel(peer)) {
|
if (isInputPeerChannel(peer)) {
|
||||||
const [dialog] = await getPeerDialogs(client, peer)
|
const [dialog] = await getPeerDialogs(client, peer)
|
||||||
|
|
||||||
if (!client.network.params.disableUpdates) {
|
await client.notifyChannelOpened(peer.channelId, dialog.raw.pts)
|
||||||
notifyChannelOpened(client, peer.channelId, dialog.raw.pts)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo: once we have proper dialogs/peers db, we should also
|
// 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
|
* @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)
|
const peer = await resolvePeer(client, chat)
|
||||||
|
|
||||||
if (isInputPeerChannel(peer) && !client.network.params.disableUpdates) {
|
if (isInputPeerChannel(peer)) {
|
||||||
notifyChannelClosed(client, peer.channelId)
|
await client.notifyChannelClosed(peer.channelId)
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo: once we have proper dialogs/peers db, we should also
|
// 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 { InputPeerLike } from '../../types/index.js'
|
||||||
import { assertTrue, isInputPeerChannel, isInputPeerUser, toInputChannel, toInputUser } from '../../utils/index.js'
|
import { isInputPeerChannel, isInputPeerUser, toInputChannel, toInputUser } from '../../utils/index.js'
|
||||||
import { isSelfPeer } from '../auth/_state.js'
|
import { isSelfPeer } from '../auth/utils.js'
|
||||||
import { resolvePeer } from '../users/resolve-peer.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"
|
* @param peerId Bot, channel or "me"/"self"
|
||||||
*/
|
*/
|
||||||
export async function reorderUsernames(
|
export async function reorderUsernames(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
peerId: InputPeerLike,
|
peerId: InputPeerLike,
|
||||||
order: string[],
|
order: string[],
|
||||||
): Promise<void> {
|
): 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 { InputPeerLike, MtInvalidPeerTypeError } from '../../types/index.js'
|
||||||
import { normalizeDate } from '../../utils/misc-utils.js'
|
import { normalizeDate } from '../../utils/misc-utils.js'
|
||||||
import { isInputPeerChannel, toInputChannel } from '../../utils/peer-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.
|
* Restrict a user in a supergroup.
|
||||||
*/
|
*/
|
||||||
export async function restrictChatMember(
|
export async function restrictChatMember(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
params: {
|
params: {
|
||||||
/** Chat ID */
|
/** Chat ID */
|
||||||
chatId: InputPeerLike
|
chatId: InputPeerLike
|
||||||
|
@ -56,5 +57,5 @@ export async function restrictChatMember(
|
||||||
...restrictions,
|
...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 { InputPeerLike } from '../../types/index.js'
|
||||||
import { resolvePeer } from '../users/resolve-peer.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.
|
* @param draft Draft message, or `null` to delete.
|
||||||
*/
|
*/
|
||||||
export async function saveDraft(
|
export async function saveDraft(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
chatId: InputPeerLike,
|
chatId: InputPeerLike,
|
||||||
draft: null | Omit<tl.RawDraftMessage, '_' | 'date'>,
|
draft: null | Omit<tl.RawDraftMessage, '_' | 'date'>,
|
||||||
): Promise<void> {
|
): 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 { InputPeerLike, MtInvalidPeerTypeError } from '../../types/index.js'
|
||||||
import { assertTrue, isInputPeerChannel, isInputPeerUser, toInputChannel } from '../../utils/index.js'
|
import { isInputPeerChannel, isInputPeerUser, toInputChannel } from '../../utils/index.js'
|
||||||
import { isSelfPeer } from '../auth/_state.js'
|
import { isSelfPeer } from '../auth/utils.js'
|
||||||
import { resolvePeer } from '../users/resolve-peer.js'
|
import { resolvePeer } from '../users/resolve-peer.js'
|
||||||
|
|
||||||
// @available=user
|
// @available=user
|
||||||
|
@ -10,7 +13,7 @@ import { resolvePeer } from '../users/resolve-peer.js'
|
||||||
* Set peer color and optionally background pattern
|
* Set peer color and optionally background pattern
|
||||||
*/
|
*/
|
||||||
export async function setChatColor(
|
export async function setChatColor(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
params: {
|
params: {
|
||||||
/**
|
/**
|
||||||
* Peer where to update the color.
|
* Peer where to update the color.
|
||||||
|
@ -58,7 +61,7 @@ export async function setChatColor(
|
||||||
backgroundEmojiId,
|
backgroundEmojiId,
|
||||||
})
|
})
|
||||||
|
|
||||||
client.network.handleUpdate(res)
|
client.handleClientUpdate(res)
|
||||||
|
|
||||||
return
|
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 { 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'
|
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
|
* and passing `{}` (empty object) will lift any restrictions
|
||||||
*/
|
*/
|
||||||
export async function setChatDefaultPermissions(
|
export async function setChatDefaultPermissions(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
chatId: InputPeerLike,
|
chatId: InputPeerLike,
|
||||||
restrictions: Omit<tl.RawChatBannedRights, '_' | 'untilDate'>,
|
restrictions: Omit<tl.RawChatBannedRights, '_' | 'untilDate'>,
|
||||||
): Promise<Chat> {
|
): Promise<Chat> {
|
||||||
|
@ -35,7 +36,7 @@ export async function setChatDefaultPermissions(
|
||||||
|
|
||||||
assertIsUpdatesGroup('messages.editChatDefaultBannedRights', res)
|
assertIsUpdatesGroup('messages.editChatDefaultBannedRights', res)
|
||||||
|
|
||||||
client.network.handleUpdate(res)
|
client.handleClientUpdate(res)
|
||||||
|
|
||||||
return new Chat(res.chats[0])
|
return new Chat(res.chats[0])
|
||||||
}
|
}
|
|
@ -1,6 +1,5 @@
|
||||||
import { BaseTelegramClient } from '@mtcute/core'
|
import { assertTrue } from '../../../utils/type-assertions.js'
|
||||||
import { assertTrue } from '@mtcute/core/utils.js'
|
import { ITelegramClient } from '../../client.types.js'
|
||||||
|
|
||||||
import { InputPeerLike } from '../../types/index.js'
|
import { InputPeerLike } from '../../types/index.js'
|
||||||
import { resolvePeer } from '../users/resolve-peer.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
|
* @param description New chat description, 0-255 characters
|
||||||
*/
|
*/
|
||||||
export async function setChatDescription(
|
export async function setChatDescription(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
chatId: InputPeerLike,
|
chatId: InputPeerLike,
|
||||||
description: string,
|
description: string,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
|
@ -1,7 +1,10 @@
|
||||||
import { BaseTelegramClient, MtArgumentError, tl } from '@mtcute/core'
|
import { tdFileId } from '@mtcute/file-id'
|
||||||
import { fileIdToInputPhoto, 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 { 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 { isInputPeerChannel, isInputPeerChat, toInputChannel } from '../../utils/peer-utils.js'
|
||||||
import { uploadFile } from '../files/upload-file.js'
|
import { uploadFile } from '../files/upload-file.js'
|
||||||
import { resolvePeer } from '../users/resolve-peer.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.
|
* You must be an administrator and have the appropriate permissions.
|
||||||
*/
|
*/
|
||||||
export async function setChatPhoto(
|
export async function setChatPhoto(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
params: {
|
params: {
|
||||||
/** Chat ID or username */
|
/** Chat ID or username */
|
||||||
chatId: InputPeerLike
|
chatId: InputPeerLike
|
||||||
|
@ -99,5 +102,5 @@ export async function setChatPhoto(
|
||||||
photo,
|
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 { InputPeerLike, MtInvalidPeerTypeError } from '../../types/index.js'
|
||||||
import { isInputPeerChannel, isInputPeerChat, toInputChannel } from '../../utils/peer-utils.js'
|
import { isInputPeerChannel, isInputPeerChat, toInputChannel } from '../../utils/peer-utils.js'
|
||||||
import { resolvePeer } from '../users/resolve-peer.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 chatId Chat ID or username
|
||||||
* @param title New chat title, 1-255 characters
|
* @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)
|
const chat = await resolvePeer(client, chatId)
|
||||||
|
|
||||||
let res
|
let res
|
||||||
|
@ -30,5 +29,5 @@ export async function setChatTitle(client: BaseTelegramClient, chatId: InputPeer
|
||||||
})
|
})
|
||||||
} else throw new MtInvalidPeerTypeError(chatId, 'chat or channel')
|
} 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 { InputPeerLike } from '../../types/index.js'
|
||||||
import { resolvePeer } from '../users/resolve-peer.js'
|
import { resolvePeer } from '../users/resolve-peer.js'
|
||||||
|
|
||||||
|
@ -9,7 +8,7 @@ import { resolvePeer } from '../users/resolve-peer.js'
|
||||||
* @param chatId Chat ID
|
* @param chatId Chat ID
|
||||||
* @param period New TTL period, in seconds (or 0 to disable)
|
* @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({
|
await client.call({
|
||||||
_: 'messages.setHistoryTTL',
|
_: 'messages.setHistoryTTL',
|
||||||
peer: await resolvePeer(client, chatId),
|
peer: await resolvePeer(client, chatId),
|
|
@ -1,6 +1,5 @@
|
||||||
import { BaseTelegramClient } from '@mtcute/core'
|
import { assertTrue } from '../../../utils/type-assertions.js'
|
||||||
import { assertTrue } from '@mtcute/core/utils.js'
|
import { ITelegramClient } from '../../client.types.js'
|
||||||
|
|
||||||
import { InputPeerLike } from '../../types/index.js'
|
import { InputPeerLike } from '../../types/index.js'
|
||||||
import { toInputChannel } from '../../utils/peer-utils.js'
|
import { toInputChannel } from '../../utils/peer-utils.js'
|
||||||
import { resolvePeer } from '../users/resolve-peer.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
|
* @param username New username, or `null` to remove
|
||||||
*/
|
*/
|
||||||
export async function setChatUsername(
|
export async function setChatUsername(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
chatId: InputPeerLike,
|
chatId: InputPeerLike,
|
||||||
username: string | null,
|
username: string | null,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
|
@ -1,5 +1,4 @@
|
||||||
import { BaseTelegramClient } from '@mtcute/core'
|
import { ITelegramClient } from '../../client.types.js'
|
||||||
|
|
||||||
import { InputPeerLike } from '../../types/index.js'
|
import { InputPeerLike } from '../../types/index.js'
|
||||||
import { toInputChannel } from '../../utils/peer-utils.js'
|
import { toInputChannel } from '../../utils/peer-utils.js'
|
||||||
import { resolvePeer } from '../users/resolve-peer.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.
|
* 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)`
|
* 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({
|
const res = await client.call({
|
||||||
_: 'channels.toggleSlowMode',
|
_: 'channels.toggleSlowMode',
|
||||||
channel: toInputChannel(await resolvePeer(client, chatId), chatId),
|
channel: toInputChannel(await resolvePeer(client, chatId), chatId),
|
||||||
seconds,
|
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 { InputPeerLike } from '../../types/index.js'
|
||||||
import { resolvePeer } from '../users/resolve-peer.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
|
* @param enabled Whether content protection should be enabled
|
||||||
*/
|
*/
|
||||||
export async function toggleContentProtection(
|
export async function toggleContentProtection(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
chatId: InputPeerLike,
|
chatId: InputPeerLike,
|
||||||
enabled = false,
|
enabled = false,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
|
@ -19,5 +18,5 @@ export async function toggleContentProtection(
|
||||||
peer: await resolvePeer(client, chatId),
|
peer: await resolvePeer(client, chatId),
|
||||||
enabled,
|
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 { InputPeerLike } from '../../types/index.js'
|
||||||
import { assertTrue, isInputPeerChannel, isInputPeerUser, toInputChannel, toInputUser } from '../../utils/index.js'
|
import { isInputPeerChannel, isInputPeerUser, toInputChannel, toInputUser } from '../../utils/index.js'
|
||||||
import { isSelfPeer } from '../auth/_state.js'
|
import { isSelfPeer } from '../auth/utils.js'
|
||||||
import { resolvePeer } from '../users/resolve-peer.js'
|
import { resolvePeer } from '../users/resolve-peer.js'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -12,7 +12,7 @@ import { resolvePeer } from '../users/resolve-peer.js'
|
||||||
* > using {@link setUsername}/{@link setChatUsername}
|
* > using {@link setUsername}/{@link setChatUsername}
|
||||||
*/
|
*/
|
||||||
export async function toggleFragmentUsername(
|
export async function toggleFragmentUsername(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
params: {
|
params: {
|
||||||
/** Peer ID whose username to toggle */
|
/** Peer ID whose username to toggle */
|
||||||
peerId: InputPeerLike
|
peerId: InputPeerLike
|
|
@ -1,5 +1,4 @@
|
||||||
import { BaseTelegramClient } from '@mtcute/core'
|
import { ITelegramClient } from '../../client.types.js'
|
||||||
|
|
||||||
import { InputPeerLike } from '../../types/index.js'
|
import { InputPeerLike } from '../../types/index.js'
|
||||||
import { toInputChannel } from '../../utils/peer-utils.js'
|
import { toInputChannel } from '../../utils/peer-utils.js'
|
||||||
import { resolvePeer } from '../users/resolve-peer.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
|
* @param enabled Whether join requests should be enabled
|
||||||
*/
|
*/
|
||||||
export async function toggleJoinRequests(
|
export async function toggleJoinRequests(
|
||||||
client: BaseTelegramClient,
|
client: ITelegramClient,
|
||||||
chatId: InputPeerLike,
|
chatId: InputPeerLike,
|
||||||
enabled = false,
|
enabled = false,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
|
@ -23,5 +22,5 @@ export async function toggleJoinRequests(
|
||||||
channel: toInputChannel(await resolvePeer(client, chatId), chatId),
|
channel: toInputChannel(await resolvePeer(client, chatId), chatId),
|
||||||
enabled,
|
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