mirror of
https://github.com/zhigang1992/mtcute.git
synced 2026-01-12 22:49:02 +08:00
docs: documented usage of custom schemas
This commit is contained in:
@@ -115,6 +115,7 @@ export default ({ mode }) => defineConfig({
|
||||
{ text: 'Converting sessions', link: '/guide/advanced/session-convert' },
|
||||
{ text: 'Network middlewares', link: '/guide/advanced/net-middlewares' },
|
||||
{ text: 'Object serialization', link: '/guide/advanced/serialization' },
|
||||
{ text: 'Custom schema', link: '/guide/advanced/custom-schema' },
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
100
docs/guide/advanced/custom-schema.md
Normal file
100
docs/guide/advanced/custom-schema.md
Normal file
@@ -0,0 +1,100 @@
|
||||
# Custom schema
|
||||
|
||||
::: danger
|
||||
While this *is* a somewhat supported feature/use-case, very limited support is provided
|
||||
because of the nature of the feature.
|
||||
|
||||
When having any problems with the **implementation**, feel free to open an issue.
|
||||
|
||||
In all other cases linked to usage of this, but not caused by the implementation itself
|
||||
(e.g. internal state breaking, storage corruption, missing updates, wrong types, etc.), please deal with it as you see fit.
|
||||
:::
|
||||
|
||||
In some cases it might be viable for you to use a custom schema for your bot,
|
||||
including but not limited to:
|
||||
|
||||
- Using a yet unreleased layer (e.g. taken from [Telegram Android](https://github.com/TGScheme/Schema))
|
||||
- Using a newer layer before the library is updated to support it
|
||||
- Using an older layer
|
||||
- Using undocumented/non-existent constructors (e.g. fuzzing)
|
||||
|
||||
## Basics
|
||||
|
||||
At the base level, mtcute provides a special `mtcute.customMethod` method that basically forwards
|
||||
the bytes you pass to the server as-is, without any additional serialization, and return the result as-is too:
|
||||
|
||||
```ts
|
||||
const res = tg.call({
|
||||
_: 'mtcute.customMethod',
|
||||
// `bytes` is the raw TL serialization of the method you want to call
|
||||
bytes: new Uint8Array([0xde, 0xad, 0xbe, 0xef])
|
||||
})
|
||||
// res is the raw TL serialization of the result
|
||||
console.log(res)
|
||||
```
|
||||
|
||||
Additionally, there's `overrideLayer` client option that allows you to override the layer number:
|
||||
|
||||
```ts
|
||||
const tg = new TelegramClient({
|
||||
...,
|
||||
overrideLayer: 1337
|
||||
})
|
||||
```
|
||||
|
||||
## Parsing TL schema
|
||||
|
||||
However, manually de/serializing everything would be super tedious,
|
||||
so you can use `@mtcute/tl-utils` to code-gen everything on demand:
|
||||
|
||||
```ts
|
||||
import { patchRuntimeTlSchema } from '@mtcute/tl-utils'
|
||||
// note: make sure @mtcute/tl version matches the one used by @mtcute/core
|
||||
import { __tlReaderMap } from '@mtcute/tl/binary/reader.js'
|
||||
import { __tlWriterMap } from '@mtcute/tl/binary/writer.js'
|
||||
|
||||
// here you can pass just the difference between
|
||||
// the built-in schema and the custom one
|
||||
const nextSchema = patchRuntimeTlSchema(`
|
||||
updateWoof from:Peer = Update;
|
||||
---functions---
|
||||
woof.bark at:InputPeer = Bool;
|
||||
`.trim(), __tlReaderMap, __tlWriterMap)
|
||||
```
|
||||
::: tip
|
||||
`patchRuntimeTlSchema` uses `eval` under the hood, so it might not work in all environments
|
||||
:::
|
||||
|
||||
Once parsed, you can pass `nextSchema` to `TlBinaryReader` and `TlBinaryWriter` to use it:
|
||||
|
||||
```ts
|
||||
import { TlBinaryReader, TlBinaryWriter } from '@mtcute/tl-runtime'
|
||||
|
||||
const r = await tg.call({
|
||||
_: 'mtcute.customMethod',
|
||||
bytes: TlBinaryWriter.serializeObject(nextSchema.writerMap, {
|
||||
_: 'woof.bark',
|
||||
at: await tg.resolvePeer('teidesu')
|
||||
} as any)
|
||||
})
|
||||
|
||||
console.log(TlBinaryReader.deserializeObject(nextSchema.readerMap, r))
|
||||
```
|
||||
|
||||
## Updates
|
||||
|
||||
Handling new updates is a bit more involved, since there is no request-response mechanism,
|
||||
so you will have to hack into the inners of the library.
|
||||
|
||||
```ts
|
||||
const tg = new TelegramClient({
|
||||
...,
|
||||
readerMap: nextSchema.readerMap
|
||||
})
|
||||
|
||||
tg.onRawUpdate.add(({ update, peers }) => {
|
||||
if (update._ === 'updateWoof') {
|
||||
console.log('got woof from %o', peers.get(update.at))
|
||||
}
|
||||
})
|
||||
```
|
||||
@@ -50,8 +50,8 @@ tg.onUpdate.add((upd) => {
|
||||
})
|
||||
|
||||
// As well as raw MTProto updates:
|
||||
tg.onRawUpdate.add((upd, users, chats) => {
|
||||
console.log(upd._)
|
||||
tg.onRawUpdate.add(({ update, peers }) => {
|
||||
console.log(update._)
|
||||
})
|
||||
```
|
||||
|
||||
|
||||
Reference in New Issue
Block a user