feat(client): better support for sticker sets, getInstalledStickers and getStickerSet methods
This commit is contained in:
parent
68ce10d292
commit
2fc8a90edf
7 changed files with 299 additions and 17 deletions
|
@ -75,6 +75,8 @@ import {
|
||||||
setDefaultParseMode,
|
setDefaultParseMode,
|
||||||
unregisterParseMode,
|
unregisterParseMode,
|
||||||
} from './methods/parse-modes/parse-modes'
|
} from './methods/parse-modes/parse-modes'
|
||||||
|
import { getInstalledStickers } from './methods/stickers/get-installed-stickers'
|
||||||
|
import { getStickerSet } from './methods/stickers/get-sticker-set'
|
||||||
import {
|
import {
|
||||||
_fetchUpdatesState,
|
_fetchUpdatesState,
|
||||||
_handleUpdate,
|
_handleUpdate,
|
||||||
|
@ -105,6 +107,7 @@ import {
|
||||||
PartialExcept,
|
PartialExcept,
|
||||||
ReplyMarkup,
|
ReplyMarkup,
|
||||||
SentCode,
|
SentCode,
|
||||||
|
StickerSet,
|
||||||
TakeoutSession,
|
TakeoutSession,
|
||||||
TermsOfService,
|
TermsOfService,
|
||||||
UploadFileLike,
|
UploadFileLike,
|
||||||
|
@ -1675,6 +1678,24 @@ export interface TelegramClient extends BaseTelegramClient {
|
||||||
* @throws MtCuteError When given parse mode is not registered.
|
* @throws MtCuteError When given parse mode is not registered.
|
||||||
*/
|
*/
|
||||||
setDefaultParseMode(name: string): void
|
setDefaultParseMode(name: string): void
|
||||||
|
/**
|
||||||
|
* Get a list of all installed sticker packs
|
||||||
|
*
|
||||||
|
* > **Note**: This method returns *brief* meta information about
|
||||||
|
* > the packs, that does not include the stickers themselves.
|
||||||
|
* > Use {@link StickerSet.getFull} or {@link getStickerSet}
|
||||||
|
* > to get a stickerset that will include the stickers
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
getInstalledStickers(): Promise<StickerSet[]>
|
||||||
|
/**
|
||||||
|
* Get a sticker pack and stickers inside of it.
|
||||||
|
*
|
||||||
|
* @param id Sticker pack short name, dice emoji, `"emoji"` for animated emojis or input ID
|
||||||
|
*/
|
||||||
|
getStickerSet(
|
||||||
|
id: string | { dice: string } | tl.TypeInputStickerSet
|
||||||
|
): Promise<StickerSet>
|
||||||
/**
|
/**
|
||||||
* Base function for update handling. Replace or override this function
|
* Base function for update handling. Replace or override this function
|
||||||
* and implement your own update handler, and call this function
|
* and implement your own update handler, and call this function
|
||||||
|
@ -1846,6 +1867,8 @@ export class TelegramClient extends BaseTelegramClient {
|
||||||
unregisterParseMode = unregisterParseMode
|
unregisterParseMode = unregisterParseMode
|
||||||
getParseMode = getParseMode
|
getParseMode = getParseMode
|
||||||
setDefaultParseMode = setDefaultParseMode
|
setDefaultParseMode = setDefaultParseMode
|
||||||
|
getInstalledStickers = getInstalledStickers
|
||||||
|
getStickerSet = getStickerSet
|
||||||
protected _fetchUpdatesState = _fetchUpdatesState
|
protected _fetchUpdatesState = _fetchUpdatesState
|
||||||
protected _loadStorage = _loadStorage
|
protected _loadStorage = _loadStorage
|
||||||
protected _saveStorage = _saveStorage
|
protected _saveStorage = _saveStorage
|
||||||
|
|
|
@ -26,7 +26,8 @@ import {
|
||||||
Message,
|
Message,
|
||||||
ReplyMarkup,
|
ReplyMarkup,
|
||||||
InputMediaLike,
|
InputMediaLike,
|
||||||
TakeoutSession
|
TakeoutSession,
|
||||||
|
StickerSet
|
||||||
} from '../types'
|
} from '../types'
|
||||||
|
|
||||||
// @copy
|
// @copy
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
import { TelegramClient } from '../../client'
|
||||||
|
import { StickerSet } from '../../types'
|
||||||
|
import { assertTypeIs } from '../../utils/type-assertion'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of all installed sticker packs
|
||||||
|
*
|
||||||
|
* > **Note**: This method returns *brief* meta information about
|
||||||
|
* > the packs, that does not include the stickers themselves.
|
||||||
|
* > Use {@link StickerSet.getFull} or {@link getStickerSet}
|
||||||
|
* > to get a stickerset that will include the stickers
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
export async function getInstalledStickers(
|
||||||
|
this: TelegramClient
|
||||||
|
): Promise<StickerSet[]> {
|
||||||
|
const res = await this.call({
|
||||||
|
_: 'messages.getAllStickers',
|
||||||
|
hash: 0
|
||||||
|
})
|
||||||
|
|
||||||
|
assertTypeIs('getInstalledStickers', res, 'messages.allStickers')
|
||||||
|
|
||||||
|
return res.sets.map((set) => new StickerSet(this, set))
|
||||||
|
}
|
38
packages/client/src/methods/stickers/get-sticker-set.ts
Normal file
38
packages/client/src/methods/stickers/get-sticker-set.ts
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
import { TelegramClient } from '../../client'
|
||||||
|
import { tl } from '@mtcute/tl'
|
||||||
|
import { StickerSet } from '../../types'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a sticker pack and stickers inside of it.
|
||||||
|
*
|
||||||
|
* @param id Sticker pack short name, dice emoji, `"emoji"` for animated emojis or input ID
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
export async function getStickerSet(
|
||||||
|
this: TelegramClient,
|
||||||
|
id: string | { dice: string } | tl.TypeInputStickerSet
|
||||||
|
): Promise<StickerSet> {
|
||||||
|
let input: tl.TypeInputStickerSet
|
||||||
|
if (typeof id === 'string') {
|
||||||
|
input = id === 'emoji' ? {
|
||||||
|
_: 'inputStickerSetAnimatedEmoji'
|
||||||
|
} : {
|
||||||
|
_: 'inputStickerSetShortName',
|
||||||
|
shortName: id
|
||||||
|
}
|
||||||
|
} else if ('dice' in id) {
|
||||||
|
input = {
|
||||||
|
_: 'inputStickerSetDice',
|
||||||
|
emoticon: id.dice
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
input = id
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = await this.call({
|
||||||
|
_: 'messages.getStickerSet',
|
||||||
|
stickerset: input
|
||||||
|
})
|
||||||
|
|
||||||
|
return new StickerSet(this, res)
|
||||||
|
}
|
|
@ -2,6 +2,7 @@ import { RawDocument } from './document'
|
||||||
import { TelegramClient } from '../../client'
|
import { TelegramClient } from '../../client'
|
||||||
import { tl } from '@mtcute/tl'
|
import { tl } from '@mtcute/tl'
|
||||||
import { makeInspectable } from '../utils'
|
import { makeInspectable } from '../utils'
|
||||||
|
import { StickerSet } from '../misc'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A sticker
|
* A sticker
|
||||||
|
@ -36,14 +37,15 @@ export class Sticker extends RawDocument {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Emoji associated with this sticker.
|
* Primary emoji associated with this sticker,
|
||||||
|
* that is displayed in dialogs list.
|
||||||
*
|
*
|
||||||
* If there is none, empty string is returned.
|
* If there is none, empty string is returned.
|
||||||
*
|
*
|
||||||
* **Note:** This only contains at most one emoji.
|
* **Note:** This only contains at most one emoji.
|
||||||
* Some stickers have multiple associated emojis,
|
* Some stickers have multiple associated emojis,
|
||||||
* but only one is returned here. This is Telegram's
|
* but only one is returned here. This is Telegram's
|
||||||
* limitation! Use {@link getAllEmojis}
|
* limitation! Use {@link getAllEmojis} instead.
|
||||||
*/
|
*/
|
||||||
get emoji(): string {
|
get emoji(): string {
|
||||||
return this.attr.alt
|
return this.attr.alt
|
||||||
|
@ -72,13 +74,10 @@ export class Sticker extends RawDocument {
|
||||||
*
|
*
|
||||||
* Returns `null` if there's no sticker set.
|
* Returns `null` if there's no sticker set.
|
||||||
*/
|
*/
|
||||||
async getStickerSet(): Promise<tl.messages.RawStickerSet | null> {
|
async getStickerSet(): Promise<StickerSet | null> {
|
||||||
if (!this.hasStickerSet) return null
|
if (!this.hasStickerSet) return null
|
||||||
|
|
||||||
return this.client.call({
|
return this.client.getStickerSet(this.attr.stickerset)
|
||||||
_: 'messages.getStickerSet',
|
|
||||||
stickerset: this.attr.stickerset,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -88,18 +87,11 @@ export class Sticker extends RawDocument {
|
||||||
* with a sticker pack.
|
* with a sticker pack.
|
||||||
*/
|
*/
|
||||||
async getAllEmojis(): Promise<string> {
|
async getAllEmojis(): Promise<string> {
|
||||||
let ret = ''
|
|
||||||
|
|
||||||
const set = await this.getStickerSet()
|
const set = await this.getStickerSet()
|
||||||
if (!set) return ''
|
if (!set) return ''
|
||||||
|
|
||||||
set.packs.forEach((pack) => {
|
return set.stickers.find((it) => it.sticker.doc.id.eq(this.doc.id))!
|
||||||
if (pack.documents.some((doc) => doc.eq(this.doc.id))) {
|
.emoji
|
||||||
ret += pack.emoticon
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return ret
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1 +1,2 @@
|
||||||
export * from './takeout-session'
|
export * from './takeout-session'
|
||||||
|
export * from './sticker-set'
|
||||||
|
|
201
packages/client/src/types/misc/sticker-set.ts
Normal file
201
packages/client/src/types/misc/sticker-set.ts
Normal file
|
@ -0,0 +1,201 @@
|
||||||
|
import { TelegramClient } from '../../client'
|
||||||
|
import { tl } from '@mtcute/tl'
|
||||||
|
import { makeInspectable } from '../utils'
|
||||||
|
import { Sticker } from '../media'
|
||||||
|
import { MtCuteEmptyError, MtCuteTypeAssertionError } from '../errors'
|
||||||
|
import { parseDocument } from '../media/document-utils'
|
||||||
|
|
||||||
|
export namespace StickerSet {
|
||||||
|
/**
|
||||||
|
* Information about one sticker inside the set
|
||||||
|
*/
|
||||||
|
export interface StickerInfo {
|
||||||
|
/**
|
||||||
|
* Primary alt emoji that is displayed in dialogs list
|
||||||
|
*/
|
||||||
|
readonly alt: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* One or more emojis representing this sticker
|
||||||
|
*/
|
||||||
|
readonly emoji: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Document with the actual sticker
|
||||||
|
*/
|
||||||
|
readonly sticker: Sticker
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A stickerset (aka sticker pack)
|
||||||
|
*/
|
||||||
|
export class StickerSet {
|
||||||
|
readonly client: TelegramClient
|
||||||
|
readonly brief: tl.RawStickerSet
|
||||||
|
readonly full?: tl.messages.RawStickerSet
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether this object contains information about stickers inside the set
|
||||||
|
*/
|
||||||
|
readonly isFull: boolean
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
client: TelegramClient,
|
||||||
|
raw: tl.RawStickerSet | tl.messages.RawStickerSet
|
||||||
|
) {
|
||||||
|
this.client = client
|
||||||
|
if (raw._ === 'messages.stickerSet') {
|
||||||
|
this.full = raw
|
||||||
|
this.brief = raw.set
|
||||||
|
} else {
|
||||||
|
this.brief = raw
|
||||||
|
}
|
||||||
|
|
||||||
|
this.isFull = raw._ === 'messages.stickerSet'
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether this stickerset was archived (due to too many saved stickers in the current account)
|
||||||
|
*/
|
||||||
|
get isArchived(): boolean {
|
||||||
|
return this.brief.archived!
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether this stickerset is official
|
||||||
|
*/
|
||||||
|
get isOfficial(): boolean {
|
||||||
|
return this.brief.official!
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether this stickerset is a set of masks
|
||||||
|
*/
|
||||||
|
get isMasks(): boolean {
|
||||||
|
return this.brief.masks!
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether this stickerset is animated
|
||||||
|
*/
|
||||||
|
get isAnimated(): boolean {
|
||||||
|
return this.brief.animated!
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Date when this stickerset was installed
|
||||||
|
*/
|
||||||
|
get installedDate(): Date | null {
|
||||||
|
return this.brief.installedDate
|
||||||
|
? new Date(this.brief.installedDate * 1000)
|
||||||
|
: null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of stickers in this stickerset
|
||||||
|
*/
|
||||||
|
get count(): number {
|
||||||
|
return this.brief.count
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Input sticker set to be used in other API methods
|
||||||
|
*/
|
||||||
|
get inputStickerSet(): tl.TypeInputStickerSet {
|
||||||
|
return {
|
||||||
|
_: 'inputStickerSetID',
|
||||||
|
id: this.brief.id,
|
||||||
|
accessHash: this.brief.accessHash
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Title of the stickerset
|
||||||
|
*/
|
||||||
|
get title(): string {
|
||||||
|
return this.brief.title
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Short name of stickerset to use in `tg://addstickers?set=short_name`
|
||||||
|
* or `https://t.me/addstickers/short_name`
|
||||||
|
*/
|
||||||
|
get shortName(): string {
|
||||||
|
return this.brief.shortName
|
||||||
|
}
|
||||||
|
|
||||||
|
private _stickers?: StickerSet.StickerInfo[]
|
||||||
|
/**
|
||||||
|
* List of stickers inside this stickerset
|
||||||
|
*
|
||||||
|
* @throws MtCuteEmptyError
|
||||||
|
* In case this object does not contain info about stickers (i.e. {@link isFull} = false)
|
||||||
|
*/
|
||||||
|
get stickers(): StickerSet.StickerInfo[] {
|
||||||
|
if (!this.isFull) throw new MtCuteEmptyError()
|
||||||
|
|
||||||
|
if (!this._stickers) {
|
||||||
|
this._stickers = []
|
||||||
|
const index: Record<string, tl.Mutable<StickerSet.StickerInfo>> = {}
|
||||||
|
|
||||||
|
this.full!.documents.forEach((doc) => {
|
||||||
|
const sticker = parseDocument(
|
||||||
|
this.client,
|
||||||
|
doc as tl.RawDocument
|
||||||
|
)
|
||||||
|
if (!(sticker instanceof Sticker)) {
|
||||||
|
throw new MtCuteTypeAssertionError(
|
||||||
|
'StickerSet#stickers (full.documents)',
|
||||||
|
'Sticker',
|
||||||
|
sticker.mimeType
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const info: tl.Mutable<StickerSet.StickerInfo> = {
|
||||||
|
alt: sticker.emoji,
|
||||||
|
emoji: '', // populated later
|
||||||
|
sticker
|
||||||
|
}
|
||||||
|
this._stickers!.push(info)
|
||||||
|
index[doc.id.toString()] = info
|
||||||
|
})
|
||||||
|
|
||||||
|
this.full!.packs.forEach((pack) => {
|
||||||
|
pack.documents.forEach((id) => {
|
||||||
|
const sid = id.toString()
|
||||||
|
if (sid in index) {
|
||||||
|
index[sid].emoji += pack.emoticon
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._stickers
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find stickers given their emoji.
|
||||||
|
*
|
||||||
|
* @param emoji Emoji to search for
|
||||||
|
* @throws MtCuteEmptyError
|
||||||
|
* In case this object does not contain info about stickers (i.e. {@link isFull} = false)
|
||||||
|
*/
|
||||||
|
getStickersByEmoji(emoji: string): StickerSet.StickerInfo[] {
|
||||||
|
return this.stickers.filter(it => it.alt === emoji || it.emoji.indexOf(emoji) != -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get full stickerset object.
|
||||||
|
*
|
||||||
|
* If this object is already full, this method will just
|
||||||
|
* return `this`
|
||||||
|
*/
|
||||||
|
async getFull(): Promise<StickerSet> {
|
||||||
|
if (this.isFull) return this
|
||||||
|
|
||||||
|
return this.client.getStickerSet(this.inputStickerSet)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
makeInspectable(StickerSet, ['isFull'])
|
Loading…
Reference in a new issue