Merge branch 'master' of github.com:mtcute/mtcute into fuman-net
This commit is contained in:
commit
439f50bc50
31 changed files with 499 additions and 97 deletions
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "mtcute-workspace",
|
"name": "mtcute-workspace",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "0.17.0",
|
"version": "0.17.2",
|
||||||
"private": true,
|
"private": true,
|
||||||
"packageManager": "pnpm@9.0.6",
|
"packageManager": "pnpm@9.0.6",
|
||||||
"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,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "@mtcute/core",
|
"name": "@mtcute/core",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "0.17.0",
|
"version": "0.17.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"description": "Type-safe library for MTProto (Telegram API)",
|
"description": "Type-safe library for MTProto (Telegram API)",
|
||||||
"author": "alina sireneva <alina@tei.su>",
|
"author": "alina sireneva <alina@tei.su>",
|
||||||
|
|
|
@ -202,6 +202,7 @@ export { verifyPasswordEmail } from './methods/password/password-email.js'
|
||||||
export { resendPasswordEmail } from './methods/password/password-email.js'
|
export { resendPasswordEmail } from './methods/password/password-email.js'
|
||||||
export { cancelPasswordEmail } from './methods/password/password-email.js'
|
export { cancelPasswordEmail } from './methods/password/password-email.js'
|
||||||
export { removeCloudPassword } from './methods/password/remove-cloud-password.js'
|
export { removeCloudPassword } from './methods/password/remove-cloud-password.js'
|
||||||
|
export { acceptStarGift } from './methods/premium/accept-star-gift.js'
|
||||||
export { applyBoost } from './methods/premium/apply-boost.js'
|
export { applyBoost } from './methods/premium/apply-boost.js'
|
||||||
export { canApplyBoost } from './methods/premium/can-apply-boost.js'
|
export { canApplyBoost } from './methods/premium/can-apply-boost.js'
|
||||||
export type { CanApplyBoostResult } from './methods/premium/can-apply-boost.js'
|
export type { CanApplyBoostResult } from './methods/premium/can-apply-boost.js'
|
||||||
|
@ -213,9 +214,13 @@ export { getBoosts } from './methods/premium/get-boosts.js'
|
||||||
export { getBusinessChatLinks } from './methods/premium/get-business-chat-links.js'
|
export { getBusinessChatLinks } from './methods/premium/get-business-chat-links.js'
|
||||||
export { getBusinessConnection } from './methods/premium/get-business-connection.js'
|
export { getBusinessConnection } from './methods/premium/get-business-connection.js'
|
||||||
export { getMyBoostSlots } from './methods/premium/get-my-boost-slots.js'
|
export { getMyBoostSlots } from './methods/premium/get-my-boost-slots.js'
|
||||||
|
export { getStarGiftOptions } from './methods/premium/get-star-gift-options.js'
|
||||||
|
export { getStarGifts } from './methods/premium/get-star-gifts.js'
|
||||||
export { getStarsTransactions } from './methods/premium/get-stars-transactions.js'
|
export { getStarsTransactions } from './methods/premium/get-stars-transactions.js'
|
||||||
export { iterBoosters } from './methods/premium/iter-boosters.js'
|
export { iterBoosters } from './methods/premium/iter-boosters.js'
|
||||||
|
export { iterStarGifts } from './methods/premium/iter-star-gifts.js'
|
||||||
export { iterStarsTransactions } from './methods/premium/iter-stars-transactions.js'
|
export { iterStarsTransactions } from './methods/premium/iter-stars-transactions.js'
|
||||||
|
export { sendStarGift } from './methods/premium/send-star-gift.js'
|
||||||
export { setBusinessIntro } from './methods/premium/set-business-intro.js'
|
export { setBusinessIntro } from './methods/premium/set-business-intro.js'
|
||||||
export { setBusinessWorkHours } from './methods/premium/set-business-work-hours.js'
|
export { setBusinessWorkHours } from './methods/premium/set-business-work-hours.js'
|
||||||
export { addStickerToSet } from './methods/stickers/add-sticker-to-set.js'
|
export { addStickerToSet } from './methods/stickers/add-sticker-to-set.js'
|
||||||
|
@ -247,7 +252,6 @@ export { iterAllStories } from './methods/stories/iter-all-stories.js'
|
||||||
export { iterProfileStories } from './methods/stories/iter-profile-stories.js'
|
export { iterProfileStories } from './methods/stories/iter-profile-stories.js'
|
||||||
export { iterStoryViewers } from './methods/stories/iter-story-viewers.js'
|
export { iterStoryViewers } from './methods/stories/iter-story-viewers.js'
|
||||||
export { readStories } from './methods/stories/read-stories.js'
|
export { readStories } from './methods/stories/read-stories.js'
|
||||||
export { reportStory } from './methods/stories/report-story.js'
|
|
||||||
export { sendStoryReaction } from './methods/stories/send-story-reaction.js'
|
export { sendStoryReaction } from './methods/stories/send-story-reaction.js'
|
||||||
export { sendStory } from './methods/stories/send-story.js'
|
export { sendStory } from './methods/stories/send-story.js'
|
||||||
export { togglePeerStoriesArchived } from './methods/stories/toggle-peer-stories-archived.js'
|
export { togglePeerStoriesArchived } from './methods/stories/toggle-peer-stories-archived.js'
|
||||||
|
|
|
@ -89,6 +89,7 @@ import {
|
||||||
RawDocument,
|
RawDocument,
|
||||||
ReplyMarkup,
|
ReplyMarkup,
|
||||||
SentCode,
|
SentCode,
|
||||||
|
StarGift,
|
||||||
StarsStatus,
|
StarsStatus,
|
||||||
StarsTransaction,
|
StarsTransaction,
|
||||||
Sticker,
|
Sticker,
|
||||||
|
@ -107,6 +108,7 @@ import {
|
||||||
UploadFileLike,
|
UploadFileLike,
|
||||||
UploadedFile,
|
UploadedFile,
|
||||||
User,
|
User,
|
||||||
|
UserStarGift,
|
||||||
UserStatusUpdate,
|
UserStatusUpdate,
|
||||||
UserTypingUpdate,
|
UserTypingUpdate,
|
||||||
} from '../types/index.js'
|
} from '../types/index.js'
|
||||||
|
|
|
@ -55,22 +55,20 @@ export async function findDialogs(client: ITelegramClient, peers: MaybeArray<str
|
||||||
foundIdxToOriginalIdx.set(foundInputPeers.length - 1, i)
|
foundIdxToOriginalIdx.set(foundInputPeers.length - 1, i)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (foundInputPeers.length === 0) {
|
|
||||||
// we didn't find anything, we can't even fetch the dialogs
|
|
||||||
throw new MtPeerNotFoundError(`Could not find dialogs with peers: ${peers.join(', ')}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
const dialogs = await getPeerDialogs(client, foundInputPeers)
|
|
||||||
|
|
||||||
if (foundInputPeers.length === peers.length) {
|
|
||||||
return dialogs
|
|
||||||
}
|
|
||||||
|
|
||||||
const ret: Dialog[] = Array.from({ length: peers.length })
|
const ret: Dialog[] = Array.from({ length: peers.length })
|
||||||
|
|
||||||
// populate found dialogs
|
if (foundInputPeers.length !== 0) {
|
||||||
for (const [idx, origIdx] of foundIdxToOriginalIdx) {
|
// we have some input peers, try to fetch them
|
||||||
ret[origIdx] = dialogs[idx]
|
const dialogs = await getPeerDialogs(client, foundInputPeers)
|
||||||
|
|
||||||
|
if (foundInputPeers.length === peers.length) {
|
||||||
|
return dialogs
|
||||||
|
}
|
||||||
|
|
||||||
|
// populate found dialogs
|
||||||
|
for (const [idx, origIdx] of foundIdxToOriginalIdx) {
|
||||||
|
ret[origIdx] = dialogs[idx]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// now we need to iterate over all dialogs and try to find the rest
|
// now we need to iterate over all dialogs and try to find the rest
|
||||||
|
|
|
@ -257,6 +257,7 @@ export async function _normalizeInputMedia(
|
||||||
fileMime: sendMime,
|
fileMime: sendMime,
|
||||||
fileSize: media.fileSize,
|
fileSize: media.fileSize,
|
||||||
requireFileSize: media.type === 'photo',
|
requireFileSize: media.type === 'photo',
|
||||||
|
requireExtension: media.type === 'photo',
|
||||||
})
|
})
|
||||||
inputFile = uploaded.inputFile
|
inputFile = uploaded.inputFile
|
||||||
mime = uploaded.mime
|
mime = uploaded.mime
|
||||||
|
|
|
@ -102,6 +102,15 @@ export async function uploadFile(
|
||||||
* the stream will be buffered in memory and the file size will be inferred from the buffer.
|
* the stream will be buffered in memory and the file size will be inferred from the buffer.
|
||||||
*/
|
*/
|
||||||
requireFileSize?: boolean
|
requireFileSize?: boolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When using `inputMediaUploadedPhoto` (e.g. when sending an uploaded photo) require
|
||||||
|
* the file extension to be known beforehand.
|
||||||
|
*
|
||||||
|
* This will make the library try to guess the file extension from the file mime type,
|
||||||
|
* or throw an error if it cannot be guessed.
|
||||||
|
*/
|
||||||
|
requireExtension?: boolean
|
||||||
},
|
},
|
||||||
): Promise<UploadedFile> {
|
): Promise<UploadedFile> {
|
||||||
// normalize params
|
// normalize params
|
||||||
|
@ -128,6 +137,7 @@ export async function uploadFile(
|
||||||
if (HAS_FILE && file instanceof File) {
|
if (HAS_FILE && file instanceof File) {
|
||||||
fileName = file.name
|
fileName = file.name
|
||||||
fileSize = file.size
|
fileSize = file.size
|
||||||
|
fileMime = file.type
|
||||||
file = file.stream()
|
file = file.stream()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -312,6 +322,21 @@ export async function uploadFile(
|
||||||
// telegram requires us to specify the file extension
|
// telegram requires us to specify the file extension
|
||||||
const ext = MIME_TO_EXTENSION[fileMime!]
|
const ext = MIME_TO_EXTENSION[fileMime!]
|
||||||
fileName = ext ? `${DEFAULT_FILE_NAME}.${ext}` : DEFAULT_FILE_NAME
|
fileName = ext ? `${DEFAULT_FILE_NAME}.${ext}` : DEFAULT_FILE_NAME
|
||||||
|
} else if (params.requireExtension) {
|
||||||
|
const extFromMime = MIME_TO_EXTENSION[fileMime!]
|
||||||
|
|
||||||
|
const idx = fileName.lastIndexOf('.')
|
||||||
|
const extFromName = idx === -1 ? undefined : fileName.slice(idx + 1)
|
||||||
|
|
||||||
|
if (!extFromName) {
|
||||||
|
if (!extFromMime) {
|
||||||
|
throw new MtArgumentError(`File name does not have an extension, and we cannot guess it from the mime type (${fileMime})`)
|
||||||
|
}
|
||||||
|
|
||||||
|
fileName = `${fileName}.${extFromMime}`
|
||||||
|
} else if (extFromMime && extFromName !== extFromMime) {
|
||||||
|
throw new MtArgumentError(`File name has ${extFromName} extension (${fileName}), but the mime type (${fileMime}) expects it to be ${extFromMime}`)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let inputFile: tl.TypeInputFile
|
let inputFile: tl.TypeInputFile
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
import type { ITelegramClient } from '../../client.types.js'
|
||||||
|
import { type InputMessageId, normalizeInputMessageId } from '../../types/messages/input-message-id.js'
|
||||||
|
import { resolveUser } from '../users/resolve-peer.js'
|
||||||
|
|
||||||
|
// @available=user
|
||||||
|
/**
|
||||||
|
* Accept, hide or convert a star gift.
|
||||||
|
*
|
||||||
|
* @returns Whether the action was successful
|
||||||
|
*/
|
||||||
|
export async function acceptStarGift(
|
||||||
|
client: ITelegramClient,
|
||||||
|
params: InputMessageId & {
|
||||||
|
/**
|
||||||
|
* Action to perform on the gift.
|
||||||
|
* - `save` - save the gift to your profile
|
||||||
|
* - `hide` - hide the gift from your profile
|
||||||
|
* - `convert` - convert the gift to stars (can't be undone)
|
||||||
|
*/
|
||||||
|
action: 'save' | 'hide' | 'convert'
|
||||||
|
},
|
||||||
|
): Promise<boolean> {
|
||||||
|
const { action } = params
|
||||||
|
const { chatId, message } = normalizeInputMessageId(params)
|
||||||
|
const userId = await resolveUser(client, chatId)
|
||||||
|
|
||||||
|
return client.call(
|
||||||
|
action === 'convert'
|
||||||
|
? {
|
||||||
|
_: 'payments.convertStarGift',
|
||||||
|
userId,
|
||||||
|
msgId: message,
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
_: 'payments.saveStarGift',
|
||||||
|
unsave: action === 'hide',
|
||||||
|
userId,
|
||||||
|
msgId: message,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
import { assertTypeIsNot } from '../../../utils/type-assertions.js'
|
||||||
|
import type { ITelegramClient } from '../../client.types.js'
|
||||||
|
import { StarGift } from '../../types/premium/stars-gift.js'
|
||||||
|
|
||||||
|
// @available=user
|
||||||
|
/**
|
||||||
|
* Get the list of available star gifts.
|
||||||
|
*/
|
||||||
|
export async function getStarGiftOptions(client: ITelegramClient): Promise<StarGift[]> {
|
||||||
|
const res = await client.call({
|
||||||
|
_: 'payments.getStarGifts',
|
||||||
|
hash: 0,
|
||||||
|
})
|
||||||
|
|
||||||
|
assertTypeIsNot('payments.getStarGifts', res, 'payments.starGiftsNotModified')
|
||||||
|
|
||||||
|
return res.gifts.map(gift => new StarGift(gift))
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
import type { ITelegramClient } from '../../client.types.js'
|
||||||
|
import type { InputPeerLike } from '../../types/peers/peer.js'
|
||||||
|
import { PeersIndex } from '../../types/peers/peers-index.js'
|
||||||
|
import { UserStarGift } from '../../types/premium/stars-gift.js'
|
||||||
|
import type { ArrayPaginated } from '../../types/utils.js'
|
||||||
|
import { makeArrayPaginated } from '../../utils/misc-utils.js'
|
||||||
|
import { resolveUser } from '../users/resolve-peer.js'
|
||||||
|
|
||||||
|
// @available=user
|
||||||
|
/**
|
||||||
|
* Get a list of gifts sent to a user.
|
||||||
|
*
|
||||||
|
* @param userId User whose gifts to fetch
|
||||||
|
* @returns Gifts sent to the user
|
||||||
|
*/
|
||||||
|
export async function getStarGifts(
|
||||||
|
client: ITelegramClient,
|
||||||
|
userId: InputPeerLike,
|
||||||
|
params?: {
|
||||||
|
/**
|
||||||
|
* Offset for pagination.
|
||||||
|
*/
|
||||||
|
offset?: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maximum number of gifts to fetch.
|
||||||
|
*
|
||||||
|
* @default 100
|
||||||
|
*/
|
||||||
|
limit?: number
|
||||||
|
},
|
||||||
|
): Promise<ArrayPaginated<UserStarGift, string>> {
|
||||||
|
const { offset = '', limit = 100 } = params ?? {}
|
||||||
|
|
||||||
|
const res = await client.call({
|
||||||
|
_: 'payments.getUserStarGifts',
|
||||||
|
userId: await resolveUser(client, userId),
|
||||||
|
offset,
|
||||||
|
limit,
|
||||||
|
})
|
||||||
|
|
||||||
|
const peers = PeersIndex.from(res)
|
||||||
|
const gifts = res.gifts.map(gift => new UserStarGift(gift, peers))
|
||||||
|
|
||||||
|
return makeArrayPaginated(gifts, res.count, offset)
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
import type { ITelegramClient } from '../../client.types.js'
|
||||||
|
import type { InputPeerLike, UserStarGift } from '../../types/index.js'
|
||||||
|
import { resolvePeer } from '../users/resolve-peer.js'
|
||||||
|
|
||||||
|
import { getStarGifts } from './get-star-gifts.js'
|
||||||
|
|
||||||
|
// @available=user
|
||||||
|
/**
|
||||||
|
* Iterate over gifts sent to a given user.
|
||||||
|
*
|
||||||
|
* Wrapper over {@link getStarGifts}
|
||||||
|
*
|
||||||
|
* @param peerId Peer ID
|
||||||
|
* @param params Additional parameters
|
||||||
|
*/
|
||||||
|
export async function* iterStarGifts(
|
||||||
|
client: ITelegramClient,
|
||||||
|
peerId: InputPeerLike,
|
||||||
|
params?: Parameters<typeof getStarGifts>[2] & {
|
||||||
|
/**
|
||||||
|
* Total number of gifts to fetch
|
||||||
|
*
|
||||||
|
* @default Infinity, i.e. fetch all gifts
|
||||||
|
*/
|
||||||
|
limit?: number
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of gifts to fetch per request
|
||||||
|
* Usually you don't need to change this
|
||||||
|
*
|
||||||
|
* @default 100
|
||||||
|
*/
|
||||||
|
chunkSize?: number
|
||||||
|
},
|
||||||
|
): AsyncIterableIterator<UserStarGift> {
|
||||||
|
if (!params) params = {}
|
||||||
|
const { limit = Infinity, chunkSize = 100 } = params
|
||||||
|
|
||||||
|
let { offset } = params
|
||||||
|
let current = 0
|
||||||
|
|
||||||
|
const peer = await resolvePeer(client, peerId)
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
const res = await getStarGifts(client, peer, {
|
||||||
|
offset,
|
||||||
|
limit: Math.min(limit - current, chunkSize),
|
||||||
|
})
|
||||||
|
|
||||||
|
for (const gift of res) {
|
||||||
|
yield gift
|
||||||
|
|
||||||
|
if (++current >= limit) return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!res.next) return
|
||||||
|
offset = res.next
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
import Long from 'long'
|
||||||
|
import type { tl } from '@mtcute/tl'
|
||||||
|
|
||||||
|
import type { InputPeerLike } from '../../types/peers/peer.js'
|
||||||
|
import type { StarGift } from '../../types/premium/stars-gift.js'
|
||||||
|
import { type InputText, inputTextToTl } from '../../types/misc/entities.js'
|
||||||
|
import type { ITelegramClient } from '../../client.types.js'
|
||||||
|
import { resolveUser } from '../users/resolve-peer.js'
|
||||||
|
import { assertTypeIs } from '../../../utils/type-assertions.js'
|
||||||
|
import { _findMessageInUpdate } from '../messages/find-in-update.js'
|
||||||
|
import type { Message } from '../../types/messages/message.js'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a star gift to a user.
|
||||||
|
*
|
||||||
|
* > **Note**: this method is not indended to be used by full-fledged clients,
|
||||||
|
* > as this method hides the actual invoice and payment form from the user.
|
||||||
|
* > For GUI clients, you should refer to the method's source code and
|
||||||
|
* > present the payment form to the user.
|
||||||
|
*
|
||||||
|
* @returns Service message about the sent gift
|
||||||
|
*/
|
||||||
|
export async function sendStarGift(
|
||||||
|
client: ITelegramClient,
|
||||||
|
params: {
|
||||||
|
/** ID of the user to send the gift to */
|
||||||
|
userId: InputPeerLike
|
||||||
|
|
||||||
|
/** ID of the gift to send */
|
||||||
|
gift: Long | StarGift
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether to send the gift anonymously
|
||||||
|
* (i.e. if the recipient chooses to display the gift
|
||||||
|
* on their profile, your name won't be visible)
|
||||||
|
*/
|
||||||
|
anonymous?: boolean
|
||||||
|
|
||||||
|
/** Message to send along with the gift */
|
||||||
|
message?: InputText
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether to dispatch the new message event
|
||||||
|
* to the client's update handler.
|
||||||
|
*/
|
||||||
|
shouldDispatch?: true
|
||||||
|
},
|
||||||
|
): Promise<Message> {
|
||||||
|
const { userId, gift, anonymous, message, shouldDispatch } = params
|
||||||
|
|
||||||
|
const invoice: tl.TypeInputInvoice = {
|
||||||
|
_: 'inputInvoiceStarGift',
|
||||||
|
hideName: anonymous,
|
||||||
|
userId: await resolveUser(client, userId),
|
||||||
|
giftId: Long.isLong(gift) ? gift : gift.id,
|
||||||
|
message: message ? inputTextToTl(message) : undefined,
|
||||||
|
}
|
||||||
|
|
||||||
|
const form = await client.call({
|
||||||
|
_: 'payments.getPaymentForm',
|
||||||
|
invoice,
|
||||||
|
})
|
||||||
|
|
||||||
|
const res = await client.call({
|
||||||
|
_: 'payments.sendStarsForm',
|
||||||
|
invoice,
|
||||||
|
formId: form.formId,
|
||||||
|
})
|
||||||
|
|
||||||
|
assertTypeIs('payments.sendStarsForm', res, 'payments.paymentResult')
|
||||||
|
|
||||||
|
return _findMessageInUpdate(client, res.updates, false, !shouldDispatch)
|
||||||
|
}
|
|
@ -5,7 +5,6 @@ import type {
|
||||||
InputFileLike,
|
InputFileLike,
|
||||||
InputPeerLike,
|
InputPeerLike,
|
||||||
InputStickerSetItem,
|
InputStickerSetItem,
|
||||||
StickerSourceType,
|
|
||||||
StickerType,
|
StickerType,
|
||||||
} from '../../types/index.js'
|
} from '../../types/index.js'
|
||||||
import {
|
import {
|
||||||
|
@ -54,13 +53,6 @@ export async function createStickerSet(
|
||||||
*/
|
*/
|
||||||
type?: StickerType
|
type?: StickerType
|
||||||
|
|
||||||
/**
|
|
||||||
* File source type for the stickers in this set.
|
|
||||||
*
|
|
||||||
* @default `static`, i.e. regular WEBP stickers.
|
|
||||||
*/
|
|
||||||
sourceType?: StickerSourceType
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether to create "adaptive" emoji set.
|
* Whether to create "adaptive" emoji set.
|
||||||
*
|
*
|
||||||
|
@ -113,8 +105,6 @@ export async function createStickerSet(
|
||||||
|
|
||||||
const res = await client.call({
|
const res = await client.call({
|
||||||
_: 'stickers.createStickerSet',
|
_: 'stickers.createStickerSet',
|
||||||
animated: params.sourceType === 'animated',
|
|
||||||
videos: params.sourceType === 'video',
|
|
||||||
masks: params.type === 'mask',
|
masks: params.type === 'mask',
|
||||||
emojis: params.type === 'emoji',
|
emojis: params.type === 'emoji',
|
||||||
textColor: params.adaptive,
|
textColor: params.adaptive,
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
import type { tl } from '@mtcute/tl'
|
|
||||||
|
|
||||||
import type { MaybeArray } from '../../../types/utils.js'
|
|
||||||
import { assertTrue } from '../../../utils/type-assertions.js'
|
|
||||||
import type { ITelegramClient } from '../../client.types.js'
|
|
||||||
import type { InputPeerLike } from '../../types/index.js'
|
|
||||||
import { resolvePeer } from '../users/resolve-peer.js'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Report a story (or multiple stories) to the moderation team
|
|
||||||
*/
|
|
||||||
export async function reportStory(
|
|
||||||
client: ITelegramClient,
|
|
||||||
peerId: InputPeerLike,
|
|
||||||
storyIds: MaybeArray<number>,
|
|
||||||
params?: {
|
|
||||||
/**
|
|
||||||
* Reason for reporting
|
|
||||||
*
|
|
||||||
* @default inputReportReasonSpam
|
|
||||||
*/
|
|
||||||
reason?: tl.TypeReportReason
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Additional comment to the report
|
|
||||||
*/
|
|
||||||
message?: string
|
|
||||||
},
|
|
||||||
): Promise<void> {
|
|
||||||
const { reason = { _: 'inputReportReasonSpam' }, message = '' } = params ?? {}
|
|
||||||
|
|
||||||
const r = await client.call({
|
|
||||||
_: 'stories.report',
|
|
||||||
peer: await resolvePeer(client, peerId),
|
|
||||||
id: Array.isArray(storyIds) ? storyIds : [storyIds],
|
|
||||||
message,
|
|
||||||
reason,
|
|
||||||
})
|
|
||||||
|
|
||||||
assertTrue('stories.report', r)
|
|
||||||
}
|
|
|
@ -333,6 +333,20 @@ export function requestPeer(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Button to copy text to the user's clipboard
|
||||||
|
*/
|
||||||
|
export function copy(params: {
|
||||||
|
text: string
|
||||||
|
copyText?: string
|
||||||
|
}): tl.RawKeyboardButtonCopy {
|
||||||
|
return {
|
||||||
|
_: 'keyboardButtonCopy',
|
||||||
|
text: params.text,
|
||||||
|
copyText: params?.copyText ?? params.text,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find a button in the keyboard by its text or by predicate
|
* Find a button in the keyboard by its text or by predicate
|
||||||
*
|
*
|
||||||
|
|
|
@ -90,6 +90,10 @@ export class Video extends RawDocument {
|
||||||
get videoStartTs(): number | null {
|
get videoStartTs(): number | null {
|
||||||
return this.attr._ === 'documentAttributeVideo' ? this.attr.videoStartTs ?? null : null
|
return this.attr._ === 'documentAttributeVideo' ? this.attr.videoStartTs ?? null : null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get codec(): string | null {
|
||||||
|
return this.attr._ === 'documentAttributeVideo' ? this.attr.videoCodec ?? null : null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
memoizeGetters(Video, ['fileName', 'thumbnails', 'fileId', 'uniqueFileId', 'isAnimation'])
|
memoizeGetters(Video, ['fileName', 'thumbnails', 'fileId', 'uniqueFileId', 'isAnimation'])
|
||||||
|
|
|
@ -6,6 +6,8 @@ import { _callDiscardReasonFromTl } from '../calls/index.js'
|
||||||
import { Photo } from '../media/photo.js'
|
import { Photo } from '../media/photo.js'
|
||||||
import type { Peer } from '../peers/peer.js'
|
import type { Peer } from '../peers/peer.js'
|
||||||
import { parsePeer } from '../peers/peer.js'
|
import { parsePeer } from '../peers/peer.js'
|
||||||
|
import { StarGift } from '../premium/stars-gift.js'
|
||||||
|
import type { TextWithEntities } from '../misc/entities.js'
|
||||||
|
|
||||||
import type { Message } from './message.js'
|
import type { Message } from './message.js'
|
||||||
|
|
||||||
|
@ -478,7 +480,7 @@ export interface ActionPaymentRefunded {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Telegram Stars were gifted by the other chat participant */
|
/** Telegram Stars were gifted by the other chat participant */
|
||||||
export interface ActionStarsGifted {
|
export interface ActionStarGifted {
|
||||||
readonly type: 'stars_gifted'
|
readonly type: 'stars_gifted'
|
||||||
|
|
||||||
/** Whether `currency` is a cryptocurrency */
|
/** Whether `currency` is a cryptocurrency */
|
||||||
|
@ -512,12 +514,30 @@ export interface ActionStarsPrize {
|
||||||
/** Transaction ID */
|
/** Transaction ID */
|
||||||
transactionId: string
|
transactionId: string
|
||||||
|
|
||||||
|
// todo: what does this mean?
|
||||||
boostPeer: Peer
|
boostPeer: Peer
|
||||||
|
|
||||||
/** Message ID containing the giveaway */
|
/** Message ID containing the giveaway */
|
||||||
giveawayMessageId: number
|
giveawayMessageId: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ActionStarGift {
|
||||||
|
readonly type: 'stars_gift'
|
||||||
|
|
||||||
|
/** Whether the sender chose to send the gift anonymously */
|
||||||
|
nameHidden: boolean
|
||||||
|
/** Whether this gift was saved to the recipient's profile */
|
||||||
|
saved: boolean
|
||||||
|
/** Whether this gift was converted to stars */
|
||||||
|
converted: boolean
|
||||||
|
/** Amount of stars the gift can be converted to by the recipient */
|
||||||
|
convertStars: tl.Long
|
||||||
|
/** The gift itself */
|
||||||
|
gift: StarGift
|
||||||
|
/** Message attached to the gift */
|
||||||
|
message: TextWithEntities | null
|
||||||
|
}
|
||||||
|
|
||||||
export type MessageAction =
|
export type MessageAction =
|
||||||
| ActionChatCreated
|
| ActionChatCreated
|
||||||
| ActionChannelCreated
|
| ActionChannelCreated
|
||||||
|
@ -562,8 +582,9 @@ export type MessageAction =
|
||||||
| ActionGiveawayEnded
|
| ActionGiveawayEnded
|
||||||
| ActionBoostApply
|
| ActionBoostApply
|
||||||
| ActionPaymentRefunded
|
| ActionPaymentRefunded
|
||||||
| ActionStarsGifted
|
| ActionStarGifted
|
||||||
| ActionStarsPrize
|
| ActionStarsPrize
|
||||||
|
| ActionStarGift
|
||||||
| null
|
| null
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
|
@ -848,6 +869,16 @@ export function _messageActionFromTl(this: Message, act: tl.TypeMessageAction):
|
||||||
boostPeer: parsePeer(act.boostPeer, this._peers),
|
boostPeer: parsePeer(act.boostPeer, this._peers),
|
||||||
giveawayMessageId: act.giveawayMsgId,
|
giveawayMessageId: act.giveawayMsgId,
|
||||||
}
|
}
|
||||||
|
case 'messageActionStarGift':
|
||||||
|
return {
|
||||||
|
type: 'stars_gift',
|
||||||
|
nameHidden: act.nameHidden!,
|
||||||
|
saved: act.saved!,
|
||||||
|
converted: act.converted!,
|
||||||
|
convertStars: act.convertStars,
|
||||||
|
gift: new StarGift(act.gift),
|
||||||
|
message: act.message ?? null,
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { memoizeGetters } from '../../utils/memoize.js'
|
||||||
import { MtEmptyError } from '../errors.js'
|
import { MtEmptyError } from '../errors.js'
|
||||||
import type { InputFileLike } from '../files/index.js'
|
import type { InputFileLike } from '../files/index.js'
|
||||||
import { parseSticker } from '../media/document-utils.js'
|
import { parseSticker } from '../media/document-utils.js'
|
||||||
import type { MaskPosition, Sticker, StickerSourceType, StickerType } from '../media/index.js'
|
import type { MaskPosition, Sticker, StickerType } from '../media/index.js'
|
||||||
import { Thumbnail } from '../media/index.js'
|
import { Thumbnail } from '../media/index.js'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -175,21 +175,6 @@ export class StickerSet {
|
||||||
return 'sticker'
|
return 'sticker'
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Source file type of the stickers in this set
|
|
||||||
*/
|
|
||||||
get sourceType(): StickerSourceType {
|
|
||||||
if (this.brief.animated) {
|
|
||||||
return 'animated'
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.brief.videos) {
|
|
||||||
return 'video'
|
|
||||||
}
|
|
||||||
|
|
||||||
return 'static'
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Date when this sticker set was installed
|
* Date when this sticker set was installed
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -8,3 +8,4 @@ export * from './business-intro.js'
|
||||||
export * from './business-work-hours.js'
|
export * from './business-work-hours.js'
|
||||||
export * from './stars-transaction.js'
|
export * from './stars-transaction.js'
|
||||||
export * from './stars-status.js'
|
export * from './stars-status.js'
|
||||||
|
export * from './stars-gift.js'
|
||||||
|
|
123
packages/core/src/highlevel/types/premium/stars-gift.ts
Normal file
123
packages/core/src/highlevel/types/premium/stars-gift.ts
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
import type { tl } from '@mtcute/tl'
|
||||||
|
|
||||||
|
import type { Sticker } from '../media/sticker.js'
|
||||||
|
import { parseDocument } from '../media/document-utils.js'
|
||||||
|
import { assertTypeIs } from '../../../utils/type-assertions.js'
|
||||||
|
import { MtTypeAssertionError } from '../../../types/errors.js'
|
||||||
|
import { makeInspectable } from '../../utils/inspectable.js'
|
||||||
|
import { memoizeGetters } from '../../utils/memoize.js'
|
||||||
|
import type { PeersIndex } from '../peers/peers-index.js'
|
||||||
|
import { User } from '../peers/user.js'
|
||||||
|
import type { TextWithEntities } from '../misc/entities.js'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A gift with stars attached to it.
|
||||||
|
*/
|
||||||
|
export class StarGift {
|
||||||
|
constructor(
|
||||||
|
readonly raw: tl.TypeStarGift,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
/** ID of the gift */
|
||||||
|
get id(): tl.Long {
|
||||||
|
return this.raw.id
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sticker associated with the gift */
|
||||||
|
get sticker(): Sticker {
|
||||||
|
assertTypeIs('StarGift#sticker', this.raw.sticker, 'document')
|
||||||
|
const parsed = parseDocument(this.raw.sticker)
|
||||||
|
|
||||||
|
if (parsed.type !== 'sticker') {
|
||||||
|
throw new MtTypeAssertionError('StarGift#sticker', 'sticker', parsed.type)
|
||||||
|
}
|
||||||
|
|
||||||
|
return parsed
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Amount of stars the gift was purchased for */
|
||||||
|
get purchaseStars(): tl.Long {
|
||||||
|
return this.raw.stars
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Amount of stars the gift can be converted to by the recipient
|
||||||
|
*/
|
||||||
|
get convertStars(): tl.Long {
|
||||||
|
return this.raw.convertStars
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For limited availability gifts,
|
||||||
|
* the number of remaining and total gifts available
|
||||||
|
*/
|
||||||
|
get availability(): { remains: number, total: number } | null {
|
||||||
|
if (!this.raw.availabilityRemains || !this.raw.availabilityTotal) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
remains: this.raw.availabilityRemains,
|
||||||
|
total: this.raw.availabilityTotal,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
makeInspectable(StarGift)
|
||||||
|
memoizeGetters(StarGift, ['sticker'])
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Information about a certain user's {@link StarGift}.
|
||||||
|
*/
|
||||||
|
export class UserStarGift {
|
||||||
|
constructor(
|
||||||
|
readonly raw: tl.RawUserStarGift,
|
||||||
|
readonly peers: PeersIndex,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
/** Whether the sender chose to appear anonymously */
|
||||||
|
get nameHidden(): boolean {
|
||||||
|
return this.raw.nameHidden!
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Whether this gift is not visible on the recipient's profile */
|
||||||
|
get hidden(): boolean {
|
||||||
|
return this.raw.unsaved!
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sender of the gift, if available */
|
||||||
|
get sender(): User | null {
|
||||||
|
return this.raw.fromId ? new User(this.peers.user(this.raw.fromId)) : null
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Message ID where the gift was sent, if available */
|
||||||
|
get messageId(): number | null {
|
||||||
|
return this.raw.msgId ?? null
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Date the gift was sent */
|
||||||
|
get date(): Date {
|
||||||
|
return new Date(this.raw.date * 1000)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The gift itself */
|
||||||
|
get gift(): StarGift {
|
||||||
|
return new StarGift(this.raw.gift)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Text attached to the gift */
|
||||||
|
get text(): TextWithEntities | null {
|
||||||
|
return this.raw.message ?? null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the gift was converted to stars, the amount of stars
|
||||||
|
* it was converted to
|
||||||
|
*/
|
||||||
|
get convertStars(): tl.Long | null {
|
||||||
|
return this.raw.convertStars ?? null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
makeInspectable(UserStarGift)
|
||||||
|
memoizeGetters(UserStarGift, ['sender', 'gift'])
|
|
@ -9,6 +9,8 @@ import type { User } from '../peers/user.js'
|
||||||
import { type MessageMedia, _messageMediaFromTl } from '../messages/message-media.js'
|
import { type MessageMedia, _messageMediaFromTl } from '../messages/message-media.js'
|
||||||
import { WebDocument } from '../files/web-document.js'
|
import { WebDocument } from '../files/web-document.js'
|
||||||
|
|
||||||
|
import { StarGift } from './stars-gift.js'
|
||||||
|
|
||||||
// ref: https://github.com/tdlib/td/blob/master/td/telegram/StarManager.cpp#L223
|
// ref: https://github.com/tdlib/td/blob/master/td/telegram/StarManager.cpp#L223
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -23,6 +25,7 @@ import { WebDocument } from '../files/web-document.js'
|
||||||
* - `gift`: This transaction is a gift from a user
|
* - `gift`: This transaction is a gift from a user
|
||||||
* - `bot_purchase`: This transaction is a purchase at a bot-operated store
|
* - `bot_purchase`: This transaction is a purchase at a bot-operated store
|
||||||
* - `channel_subscription`: This transaction is a subscription to a channel
|
* - `channel_subscription`: This transaction is a subscription to a channel
|
||||||
|
* - `star_gift`: This transaction is either a star gift to a user (if outgoing), or converting a star gift to stars (if incoming)
|
||||||
*/
|
*/
|
||||||
export type StarsTransactionType =
|
export type StarsTransactionType =
|
||||||
| { type: 'unsupported' }
|
| { type: 'unsupported' }
|
||||||
|
@ -113,6 +116,13 @@ export type StarsTransactionType =
|
||||||
/** ID of the message containing the giveaway where the stars were given */
|
/** ID of the message containing the giveaway where the stars were given */
|
||||||
messageId: number
|
messageId: number
|
||||||
}
|
}
|
||||||
|
| {
|
||||||
|
type: 'star_gift'
|
||||||
|
/** Related peer */
|
||||||
|
peer: Peer
|
||||||
|
/** The gift */
|
||||||
|
gift: StarGift
|
||||||
|
}
|
||||||
|
|
||||||
export class StarsTransaction {
|
export class StarsTransaction {
|
||||||
constructor(
|
constructor(
|
||||||
|
@ -201,6 +211,14 @@ export class StarsTransaction {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.raw.stargift) {
|
||||||
|
return {
|
||||||
|
type: 'star_gift',
|
||||||
|
peer,
|
||||||
|
gift: new StarGift(this.raw.stargift),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (this.raw.msgId) {
|
if (this.raw.msgId) {
|
||||||
if (this.raw.reaction) {
|
if (this.raw.reaction) {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -5,10 +5,10 @@ import type { Logger } from './logger.js'
|
||||||
export function reportUnknownError(log: Logger, error: tl.RpcError, method: string): void {
|
export function reportUnknownError(log: Logger, error: tl.RpcError, method: string): void {
|
||||||
if (typeof fetch !== 'function') return
|
if (typeof fetch !== 'function') return
|
||||||
|
|
||||||
fetch(`https://rpc.pwrtelegram.xyz/?code=${error.code}&method=${method}&error=${error.text}`)
|
fetch(`https://report-rpc-error.madelineproto.xyz/?code=${error.code}&method=${method}&error=${error.text}`)
|
||||||
.then(r => r.json())
|
.then(r => r.json())
|
||||||
.then((r) => {
|
.then((r) => {
|
||||||
if (r.ok) {
|
if (r.result) {
|
||||||
log.info('telerpc responded with error info for %s: %s', error.text, r.result)
|
log.info('telerpc responded with error info for %s: %s', error.text, r.result)
|
||||||
} else {
|
} else {
|
||||||
log.info(
|
log.info(
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "@mtcute/dispatcher",
|
"name": "@mtcute/dispatcher",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "0.17.0",
|
"version": "0.17.2",
|
||||||
"private": true,
|
"private": true,
|
||||||
"description": "Updates dispatcher and bot framework for @mtcute/client",
|
"description": "Updates dispatcher and bot framework for @mtcute/client",
|
||||||
"author": "alina sireneva <alina@tei.su>",
|
"author": "alina sireneva <alina@tei.su>",
|
||||||
|
|
|
@ -66,7 +66,7 @@ export class WizardScene<State extends object> extends Dispatcher<State & Wizard
|
||||||
if (step >= this._steps) {
|
if (step >= this._steps) {
|
||||||
await state.exit()
|
await state.exit()
|
||||||
} else {
|
} else {
|
||||||
await state.merge({ $step: step }, this._defaultState)
|
await state.merge({ $step: step }, { fallback: this._defaultState })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "@mtcute/html-parser",
|
"name": "@mtcute/html-parser",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "0.17.0",
|
"version": "0.17.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"description": "HTML entities parser for mtcute",
|
"description": "HTML entities parser for mtcute",
|
||||||
"author": "alina sireneva <alina@tei.su>",
|
"author": "alina sireneva <alina@tei.su>",
|
||||||
|
|
|
@ -361,6 +361,14 @@ describe('HtmlMessageEntityParser', () => {
|
||||||
test(htm`hewwo ${htm`<br>`} world`, [], 'hewwo \nworld')
|
test(htm`hewwo ${htm`<br>`} world`, [], 'hewwo \nworld')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should keep whitespaces in raw strings', () => {
|
||||||
|
const dot = ' ∙ '
|
||||||
|
const lf = '\n'
|
||||||
|
test(htm`this is${dot}some text${lf}xd`, [], 'this is ∙ some text\nxd')
|
||||||
|
|
||||||
|
test(htm`hewwo ${htm`<br>`} world`, [], 'hewwo \nworld')
|
||||||
|
})
|
||||||
|
|
||||||
it('should not ignore newlines and indentation in pre', () => {
|
it('should not ignore newlines and indentation in pre', () => {
|
||||||
test(
|
test(
|
||||||
htm`<pre>this is some text\n\nwith newlines</pre>`,
|
htm`<pre>this is some text\n\nwith newlines</pre>`,
|
||||||
|
|
|
@ -262,9 +262,11 @@ function parse(
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof it === 'string' || typeof it === 'number') {
|
if (typeof it === 'string') {
|
||||||
|
processPendingText()
|
||||||
pendingText += it
|
pendingText += it
|
||||||
} else if (Long.isLong(it)) {
|
processPendingText(false, true)
|
||||||
|
} else if (Long.isLong(it) || typeof it === 'number') {
|
||||||
pendingText += it.toString(10)
|
pendingText += it.toString(10)
|
||||||
} else {
|
} else {
|
||||||
// TextWithEntities or MessageEntity
|
// TextWithEntities or MessageEntity
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
TL schema and related utils used for mtcute.
|
TL schema and related utils used for mtcute.
|
||||||
|
|
||||||
Generated from TL layer **187** (last updated on 07.09.2024).
|
Generated from TL layer **189** (last updated on 05.10.2024).
|
||||||
|
|
||||||
## About
|
## About
|
||||||
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -138,7 +138,6 @@
|
||||||
"updateChatUserTyping": ["chat_id"],
|
"updateChatUserTyping": ["chat_id"],
|
||||||
"updateDeleteChannelMessages": ["channel_id"],
|
"updateDeleteChannelMessages": ["channel_id"],
|
||||||
"updateGroupCall": ["chat_id"],
|
"updateGroupCall": ["chat_id"],
|
||||||
"updateGroupInvitePrivacyForbidden": ["user_id"],
|
|
||||||
"updateInlineBotCallbackQuery": ["user_id"],
|
"updateInlineBotCallbackQuery": ["user_id"],
|
||||||
"updatePinnedChannelMessages": ["channel_id"],
|
"updatePinnedChannelMessages": ["channel_id"],
|
||||||
"updateReadChannelDiscussionInbox": ["channel_id", "broadcast_id"],
|
"updateReadChannelDiscussionInbox": ["channel_id", "broadcast_id"],
|
||||||
|
@ -157,6 +156,7 @@
|
||||||
"user": ["id"],
|
"user": ["id"],
|
||||||
"userEmpty": ["id"],
|
"userEmpty": ["id"],
|
||||||
"userFull": ["id", "personal_channel_id"],
|
"userFull": ["id", "personal_channel_id"],
|
||||||
|
"userStarGift": ["from_id"],
|
||||||
"userStories": ["user_id"],
|
"userStories": ["user_id"],
|
||||||
"webAuthorization": ["bot_id"],
|
"webAuthorization": ["bot_id"],
|
||||||
"_": "Dummy line teehee~"
|
"_": "Dummy line teehee~"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@mtcute/tl",
|
"name": "@mtcute/tl",
|
||||||
"version": "187.0.0",
|
"version": "189.0.0",
|
||||||
"description": "TL schema used for mtcute",
|
"description": "TL schema used for mtcute",
|
||||||
"author": "alina sireneva <alina@tei.su>",
|
"author": "alina sireneva <alina@tei.su>",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|
Loading…
Reference in a new issue