feat(core): stars transactions
This commit is contained in:
parent
df15f1a280
commit
b1ddb8e346
9 changed files with 484 additions and 6 deletions
|
@ -13,7 +13,7 @@ import { MtUnsupportedError } from '../types/index.js'
|
||||||
import type { BaseTelegramClientOptions } from './base.js'
|
import type { BaseTelegramClientOptions } from './base.js'
|
||||||
import { BaseTelegramClient } from './base.js'
|
import { BaseTelegramClient } from './base.js'
|
||||||
import type { ITelegramClient } from './client.types.js'
|
import type { ITelegramClient } from './client.types.js'
|
||||||
import type { AllStories, ArrayPaginated, ArrayWithTotal, Boost, BoostSlot, BoostStats, BotChatJoinRequestUpdate, BotCommands, BotReactionCountUpdate, BotReactionUpdate, BotStoppedUpdate, BusinessCallbackQuery, BusinessChatLink, BusinessConnection, BusinessMessage, BusinessWorkHoursDay, CallbackQuery, Chat, ChatEvent, ChatInviteLink, ChatInviteLinkMember, ChatJoinRequestUpdate, ChatMember, ChatMemberUpdate, ChatPreview, ChatlistPreview, ChosenInlineResult, CollectibleInfo, DeleteBusinessMessageUpdate, DeleteMessageUpdate, DeleteStoryUpdate, Dialog, FactCheck, FileDownloadLocation, FileDownloadParameters, ForumTopic, FullChat, GameHighScore, HistoryReadUpdate, InlineCallbackQuery, InlineQuery, InputChatEventFilters, InputDialogFolder, InputFileLike, InputInlineResult, InputMediaLike, InputMediaSticker, InputMessageId, InputPeerLike, InputPrivacyRule, InputReaction, InputStickerSet, InputStickerSetItem, InputText, MaybeDynamic, Message, MessageEffect, MessageMedia, MessageReactions, ParametersSkip2, ParsedUpdate, PeerReaction, PeerStories, PeersIndex, Photo, Poll, PollUpdate, PollVoteUpdate, PreCheckoutQuery, RawDocument, ReplyMarkup, SentCode, Sticker, StickerSet, StickerSourceType, StickerType, StoriesStealthMode, Story, StoryInteractions, StoryUpdate, StoryViewer, StoryViewersList, TakeoutSession, TextWithEntities, TypingStatus, UploadFileLike, UploadedFile, User, UserStatusUpdate, UserTypingUpdate } from './types/index.js'
|
import type { AllStories, ArrayPaginated, ArrayWithTotal, Boost, BoostSlot, BoostStats, BotChatJoinRequestUpdate, BotCommands, BotReactionCountUpdate, BotReactionUpdate, BotStoppedUpdate, BusinessCallbackQuery, BusinessChatLink, BusinessConnection, BusinessMessage, BusinessWorkHoursDay, CallbackQuery, Chat, ChatEvent, ChatInviteLink, ChatInviteLinkMember, ChatJoinRequestUpdate, ChatMember, ChatMemberUpdate, ChatPreview, ChatlistPreview, ChosenInlineResult, CollectibleInfo, DeleteBusinessMessageUpdate, DeleteMessageUpdate, DeleteStoryUpdate, Dialog, FactCheck, FileDownloadLocation, FileDownloadParameters, ForumTopic, FullChat, GameHighScore, HistoryReadUpdate, InlineCallbackQuery, InlineQuery, InputChatEventFilters, InputDialogFolder, InputFileLike, InputInlineResult, InputMediaLike, InputMediaSticker, InputMessageId, InputPeerLike, InputPrivacyRule, InputReaction, InputStickerSet, InputStickerSetItem, InputText, MaybeDynamic, Message, MessageEffect, MessageMedia, MessageReactions, ParametersSkip2, ParsedUpdate, PeerReaction, PeerStories, PeersIndex, Photo, Poll, PollUpdate, PollVoteUpdate, PreCheckoutQuery, RawDocument, ReplyMarkup, SentCode, StarsStatus, StarsTransaction, Sticker, StickerSet, StickerSourceType, StickerType, StoriesStealthMode, Story, StoryInteractions, StoryUpdate, StoryViewer, StoryViewersList, TakeoutSession, TextWithEntities, TypingStatus, UploadFileLike, UploadedFile, User, UserStatusUpdate, UserTypingUpdate } from './types/index.js'
|
||||||
import type { StringSessionData } from './utils/string-session.js'
|
import type { StringSessionData } from './utils/string-session.js'
|
||||||
import type { ITelegramStorageProvider } from './storage/provider.js'
|
import type { ITelegramStorageProvider } from './storage/provider.js'
|
||||||
import { Conversation } from './types/conversation.js'
|
import { Conversation } from './types/conversation.js'
|
||||||
|
@ -216,7 +216,9 @@ import { getBoosts } from './methods/premium/get-boosts.js'
|
||||||
import { getBusinessChatLinks } from './methods/premium/get-business-chat-links.js'
|
import { getBusinessChatLinks } from './methods/premium/get-business-chat-links.js'
|
||||||
import { getBusinessConnection } from './methods/premium/get-business-connection.js'
|
import { getBusinessConnection } from './methods/premium/get-business-connection.js'
|
||||||
import { getMyBoostSlots } from './methods/premium/get-my-boost-slots.js'
|
import { getMyBoostSlots } from './methods/premium/get-my-boost-slots.js'
|
||||||
|
import { getStarsTransactions } from './methods/premium/get-stars-transactions.js'
|
||||||
import { iterBoosters } from './methods/premium/iter-boosters.js'
|
import { iterBoosters } from './methods/premium/iter-boosters.js'
|
||||||
|
import { iterStarsTransactions } from './methods/premium/iter-stars-transactions.js'
|
||||||
import { setBusinessIntro } from './methods/premium/set-business-intro.js'
|
import { setBusinessIntro } from './methods/premium/set-business-intro.js'
|
||||||
import { setBusinessWorkHours } from './methods/premium/set-business-work-hours.js'
|
import { setBusinessWorkHours } from './methods/premium/set-business-work-hours.js'
|
||||||
import { addStickerToSet } from './methods/stickers/add-sticker-to-set.js'
|
import { addStickerToSet } from './methods/stickers/add-sticker-to-set.js'
|
||||||
|
@ -4593,13 +4595,46 @@ export interface TelegramClient extends ITelegramClient {
|
||||||
*/
|
*/
|
||||||
getMyBoostSlots(): Promise<BoostSlot[]>
|
getMyBoostSlots(): Promise<BoostSlot[]>
|
||||||
/**
|
/**
|
||||||
* Iterate over boosters of a channel.
|
* Get Telegram Stars transactions for a given peer.
|
||||||
*
|
*
|
||||||
* Wrapper over {@link getBoosters}
|
* You can either pass `self` to get your own transactions,
|
||||||
|
* or a chat/bot ID to get transactions of that peer.
|
||||||
*
|
*
|
||||||
* **Available**: ✅ both users and bots
|
* **Available**: ✅ both users and bots
|
||||||
*
|
*
|
||||||
* @returns IDs of stories that were removed
|
* @param peerId Peer ID
|
||||||
|
* @param params Additional parameters
|
||||||
|
*/
|
||||||
|
getStarsTransactions(
|
||||||
|
peerId: InputPeerLike,
|
||||||
|
params?: {
|
||||||
|
/**
|
||||||
|
* If passed, only transactions of this direction will be returned
|
||||||
|
*/
|
||||||
|
direction?: 'incoming' | 'outgoing'
|
||||||
|
/**
|
||||||
|
* Direction to sort transactions date by (default: desc)
|
||||||
|
*/
|
||||||
|
sort?: 'asc' | 'desc'
|
||||||
|
/**
|
||||||
|
* If passed, will only return transactions related to this subscription ID
|
||||||
|
*/
|
||||||
|
subscriptionId?: string
|
||||||
|
/** Pagination offset */
|
||||||
|
offset?: string
|
||||||
|
/**
|
||||||
|
* Pagination limit
|
||||||
|
*
|
||||||
|
* @default 100
|
||||||
|
*/
|
||||||
|
limit?: number
|
||||||
|
}): Promise<StarsStatus>
|
||||||
|
/**
|
||||||
|
* Iterate over boosters of a channel.
|
||||||
|
*
|
||||||
|
* Wrapper over {@link getBoosters}
|
||||||
|
* **Available**: ✅ both users and bots
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
iterBoosters(
|
iterBoosters(
|
||||||
peerId: InputPeerLike,
|
peerId: InputPeerLike,
|
||||||
|
@ -4619,6 +4654,37 @@ export interface TelegramClient extends ITelegramClient {
|
||||||
*/
|
*/
|
||||||
chunkSize?: number
|
chunkSize?: number
|
||||||
}): AsyncIterableIterator<Boost>
|
}): AsyncIterableIterator<Boost>
|
||||||
|
/**
|
||||||
|
* Iterate over Telegram Stars transactions for a given peer.
|
||||||
|
*
|
||||||
|
* You can either pass `self` to get your own transactions,
|
||||||
|
* or a chat/bot ID to get transactions of that peer.
|
||||||
|
*
|
||||||
|
* Wrapper over {@link getStarsTransactions}
|
||||||
|
*
|
||||||
|
* **Available**: ✅ both users and bots
|
||||||
|
*
|
||||||
|
* @param peerId Peer ID
|
||||||
|
* @param params Additional parameters
|
||||||
|
*/
|
||||||
|
iterStarsTransactions(
|
||||||
|
peerId: InputPeerLike,
|
||||||
|
params?: Parameters<typeof getStarsTransactions>[2] & {
|
||||||
|
/**
|
||||||
|
* Total number of boosters to fetch
|
||||||
|
*
|
||||||
|
* @default Infinity, i.e. fetch all boosters
|
||||||
|
*/
|
||||||
|
limit?: number
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of boosters to fetch per request
|
||||||
|
* Usually you don't need to change this
|
||||||
|
*
|
||||||
|
* @default 100
|
||||||
|
*/
|
||||||
|
chunkSize?: number
|
||||||
|
}): AsyncIterableIterator<StarsTransaction>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set current user's business introduction.
|
* Set current user's business introduction.
|
||||||
|
@ -6314,9 +6380,15 @@ TelegramClient.prototype.getBusinessConnection = function (...args) {
|
||||||
TelegramClient.prototype.getMyBoostSlots = function (...args) {
|
TelegramClient.prototype.getMyBoostSlots = function (...args) {
|
||||||
return getMyBoostSlots(this._client, ...args)
|
return getMyBoostSlots(this._client, ...args)
|
||||||
}
|
}
|
||||||
|
TelegramClient.prototype.getStarsTransactions = function (...args) {
|
||||||
|
return getStarsTransactions(this._client, ...args)
|
||||||
|
}
|
||||||
TelegramClient.prototype.iterBoosters = function (...args) {
|
TelegramClient.prototype.iterBoosters = function (...args) {
|
||||||
return iterBoosters(this._client, ...args)
|
return iterBoosters(this._client, ...args)
|
||||||
}
|
}
|
||||||
|
TelegramClient.prototype.iterStarsTransactions = function (...args) {
|
||||||
|
return iterStarsTransactions(this._client, ...args)
|
||||||
|
}
|
||||||
TelegramClient.prototype.setBusinessIntro = function (...args) {
|
TelegramClient.prototype.setBusinessIntro = function (...args) {
|
||||||
return setBusinessIntro(this._client, ...args)
|
return setBusinessIntro(this._client, ...args)
|
||||||
}
|
}
|
||||||
|
|
|
@ -213,7 +213,9 @@ 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 { 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 { iterStarsTransactions } from './methods/premium/iter-stars-transactions.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'
|
||||||
|
|
|
@ -87,6 +87,8 @@ import {
|
||||||
RawDocument,
|
RawDocument,
|
||||||
ReplyMarkup,
|
ReplyMarkup,
|
||||||
SentCode,
|
SentCode,
|
||||||
|
StarsStatus,
|
||||||
|
StarsTransaction,
|
||||||
Sticker,
|
Sticker,
|
||||||
StickerSet,
|
StickerSet,
|
||||||
StickerSourceType,
|
StickerSourceType,
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
import type { ITelegramClient } from '../../client.types.js'
|
||||||
|
import type { InputPeerLike } from '../../types/index.js'
|
||||||
|
import { StarsStatus } from '../../types/premium/stars-status.js'
|
||||||
|
import { resolvePeer } from '../users/resolve-peer.js'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Telegram Stars transactions for a given peer.
|
||||||
|
*
|
||||||
|
* You can either pass `self` to get your own transactions,
|
||||||
|
* or a chat/bot ID to get transactions of that peer.
|
||||||
|
*
|
||||||
|
* @param peerId Peer ID
|
||||||
|
* @param params Additional parameters
|
||||||
|
*/
|
||||||
|
export async function getStarsTransactions(
|
||||||
|
client: ITelegramClient,
|
||||||
|
peerId: InputPeerLike,
|
||||||
|
params?: {
|
||||||
|
/**
|
||||||
|
* If passed, only transactions of this direction will be returned
|
||||||
|
*/
|
||||||
|
direction?: 'incoming' | 'outgoing'
|
||||||
|
/**
|
||||||
|
* Direction to sort transactions date by (default: desc)
|
||||||
|
*/
|
||||||
|
sort?: 'asc' | 'desc'
|
||||||
|
/**
|
||||||
|
* If passed, will only return transactions related to this subscription ID
|
||||||
|
*/
|
||||||
|
subscriptionId?: string
|
||||||
|
/** Pagination offset */
|
||||||
|
offset?: string
|
||||||
|
/**
|
||||||
|
* Pagination limit
|
||||||
|
*
|
||||||
|
* @default 100
|
||||||
|
*/
|
||||||
|
limit?: number
|
||||||
|
},
|
||||||
|
): Promise<StarsStatus> {
|
||||||
|
const { direction, sort, subscriptionId, offset = '', limit = 100 } = params ?? {}
|
||||||
|
|
||||||
|
const res = await client.call({
|
||||||
|
_: 'payments.getStarsTransactions',
|
||||||
|
peer: await resolvePeer(client, peerId),
|
||||||
|
offset,
|
||||||
|
limit,
|
||||||
|
outbound: direction === 'outgoing',
|
||||||
|
inbound: direction === 'incoming',
|
||||||
|
ascending: sort === 'asc',
|
||||||
|
subscriptionId,
|
||||||
|
})
|
||||||
|
|
||||||
|
return new StarsStatus(res)
|
||||||
|
}
|
|
@ -9,8 +9,6 @@ import { getBoosts } from './get-boosts.js'
|
||||||
* Iterate over boosters of a channel.
|
* Iterate over boosters of a channel.
|
||||||
*
|
*
|
||||||
* Wrapper over {@link getBoosters}
|
* Wrapper over {@link getBoosters}
|
||||||
*
|
|
||||||
* @returns IDs of stories that were removed
|
|
||||||
*/
|
*/
|
||||||
export async function* iterBoosters(
|
export async function* iterBoosters(
|
||||||
client: ITelegramClient,
|
client: ITelegramClient,
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
import type { ITelegramClient } from '../../client.types.js'
|
||||||
|
import type { InputPeerLike, StarsTransaction } from '../../types/index.js'
|
||||||
|
import { resolvePeer } from '../users/resolve-peer.js'
|
||||||
|
|
||||||
|
import { getStarsTransactions } from './get-stars-transactions.js'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Iterate over Telegram Stars transactions for a given peer.
|
||||||
|
*
|
||||||
|
* You can either pass `self` to get your own transactions,
|
||||||
|
* or a chat/bot ID to get transactions of that peer.
|
||||||
|
*
|
||||||
|
* Wrapper over {@link getStarsTransactions}
|
||||||
|
*
|
||||||
|
* @param peerId Peer ID
|
||||||
|
* @param params Additional parameters
|
||||||
|
*/
|
||||||
|
export async function* iterStarsTransactions(
|
||||||
|
client: ITelegramClient,
|
||||||
|
peerId: InputPeerLike,
|
||||||
|
params?: Parameters<typeof getStarsTransactions>[2] & {
|
||||||
|
/**
|
||||||
|
* Total number of boosters to fetch
|
||||||
|
*
|
||||||
|
* @default Infinity, i.e. fetch all boosters
|
||||||
|
*/
|
||||||
|
limit?: number
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of boosters to fetch per request
|
||||||
|
* Usually you don't need to change this
|
||||||
|
*
|
||||||
|
* @default 100
|
||||||
|
*/
|
||||||
|
chunkSize?: number
|
||||||
|
},
|
||||||
|
): AsyncIterableIterator<StarsTransaction> {
|
||||||
|
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 getStarsTransactions(client, peer, {
|
||||||
|
offset,
|
||||||
|
limit: Math.min(limit - current, chunkSize),
|
||||||
|
})
|
||||||
|
|
||||||
|
for (const transaction of res.transactions) {
|
||||||
|
yield transaction
|
||||||
|
|
||||||
|
if (++current >= limit) return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!res.transactionsNextOffset) return
|
||||||
|
offset = res.transactionsNextOffset
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,3 +6,5 @@ export * from './business-chat-link.js'
|
||||||
export * from './business-connection.js'
|
export * from './business-connection.js'
|
||||||
export * from './business-intro.js'
|
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-status.js'
|
||||||
|
|
36
packages/core/src/highlevel/types/premium/stars-status.ts
Normal file
36
packages/core/src/highlevel/types/premium/stars-status.ts
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
import type { tl } from '@mtcute/tl'
|
||||||
|
|
||||||
|
import { makeInspectable } from '../../utils/inspectable.js'
|
||||||
|
import { memoizeGetters } from '../../utils/memoize.js'
|
||||||
|
import { PeersIndex } from '../peers/peers-index.js'
|
||||||
|
|
||||||
|
import { StarsTransaction } from './stars-transaction.js'
|
||||||
|
|
||||||
|
export class StarsStatus {
|
||||||
|
readonly peers: PeersIndex
|
||||||
|
constructor(
|
||||||
|
readonly raw: tl.payments.RawStarsStatus,
|
||||||
|
) {
|
||||||
|
this.peers = PeersIndex.from(raw)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Current Telegram Stars balance */
|
||||||
|
get balance(): tl.Long {
|
||||||
|
return this.raw.balance
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* History of Telegram Stars transactions
|
||||||
|
*/
|
||||||
|
get transactions(): StarsTransaction[] {
|
||||||
|
return this.raw.history?.map(it => new StarsTransaction(it, this.peers)) ?? []
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Next offset of {@link transactions} for pagination */
|
||||||
|
get transactionsNextOffset(): string | null {
|
||||||
|
return this.raw.nextOffset ?? null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
makeInspectable(StarsStatus)
|
||||||
|
memoizeGetters(StarsStatus, ['transactions'])
|
250
packages/core/src/highlevel/types/premium/stars-transaction.ts
Normal file
250
packages/core/src/highlevel/types/premium/stars-transaction.ts
Normal file
|
@ -0,0 +1,250 @@
|
||||||
|
import type { tl } from '@mtcute/tl'
|
||||||
|
|
||||||
|
import type { PeersIndex } from '../peers/peers-index.js'
|
||||||
|
import { makeInspectable } from '../../utils/inspectable.js'
|
||||||
|
import { memoizeGetters } from '../../utils/memoize.js'
|
||||||
|
import type { Peer } from '../peers/peer.js'
|
||||||
|
import { parsePeer } from '../peers/peer.js'
|
||||||
|
import type { User } from '../peers/user.js'
|
||||||
|
import { type MessageMedia, _messageMediaFromTl } from '../messages/message-media.js'
|
||||||
|
import { WebDocument } from '../files/web-document.js'
|
||||||
|
|
||||||
|
// ref: https://github.com/tdlib/td/blob/master/td/telegram/StarManager.cpp#L223
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type of the transaction.
|
||||||
|
*
|
||||||
|
* - `unsupported`: This transaction is not supported by the current version of client
|
||||||
|
* - `app_store`, `play_market`, `premium_bot`, `fragment`: This transaction is a purchase
|
||||||
|
* through App Store, Play Market, Premium Bot or Fragment respectively
|
||||||
|
* - `fragment_withdraw`: This transaction is a withdrawal via Fragment
|
||||||
|
* - `ads`: This transaction is with the Telegram Ads platform
|
||||||
|
* - `reaction`: This transaction is a paid reaction in a chat
|
||||||
|
* - `gift`: This transaction is a gift from a user
|
||||||
|
* - `bot_purchase`: This transaction is a purchase at a bot-operated store
|
||||||
|
* - `channel_subscription`: This transaction is a subscription to a channel
|
||||||
|
*/
|
||||||
|
export type StarsTransactionType =
|
||||||
|
| { type: 'unsupported' }
|
||||||
|
| { type: 'app_store' }
|
||||||
|
| { type: 'play_market' }
|
||||||
|
| { type: 'premium_bot' }
|
||||||
|
| { type: 'fragment' }
|
||||||
|
| {
|
||||||
|
type: 'fragment_withdraw'
|
||||||
|
status: 'pending' | 'success' | 'failed'
|
||||||
|
/** If successful, date of the withdrawal */
|
||||||
|
date?: Date
|
||||||
|
/** If successful, URL of the withdrawal transaction */
|
||||||
|
url?: string
|
||||||
|
}
|
||||||
|
| { type: 'ads' }
|
||||||
|
| {
|
||||||
|
type: 'reaction'
|
||||||
|
/**
|
||||||
|
* Related peer
|
||||||
|
*
|
||||||
|
* - For incoming transactions - user who sent the reaction
|
||||||
|
* - For outgoing transactions - channel which received the reaction
|
||||||
|
*/
|
||||||
|
peer: Peer
|
||||||
|
/** ID of the message containing the reaction */
|
||||||
|
messageId: number
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: 'gift'
|
||||||
|
/** User who sent the gift */
|
||||||
|
user: User
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: 'media_purchase'
|
||||||
|
/**
|
||||||
|
* Related peer
|
||||||
|
*
|
||||||
|
* - For incoming transactions - user who bought the media
|
||||||
|
* - For outgoing transactions - seller of the media
|
||||||
|
*/
|
||||||
|
peer: Peer
|
||||||
|
/** ID of the message containing the media */
|
||||||
|
messageId: number
|
||||||
|
/** The bought media (available if not refunded) */
|
||||||
|
media?: MessageMedia[]
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: 'bot_purchase'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Related user
|
||||||
|
*
|
||||||
|
* - For incoming transactions - user who bought the item
|
||||||
|
* - For outgoing transactions - the seller bot
|
||||||
|
*/
|
||||||
|
user: User
|
||||||
|
|
||||||
|
/** Photo of the item, if available */
|
||||||
|
photo?: WebDocument
|
||||||
|
|
||||||
|
/** Title of the item */
|
||||||
|
title: string
|
||||||
|
|
||||||
|
/** Description of the item */
|
||||||
|
description?: string
|
||||||
|
|
||||||
|
/** Custom payload of the item */
|
||||||
|
payload?: Uint8Array
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: 'channel_subscription'
|
||||||
|
/**
|
||||||
|
* Related peer
|
||||||
|
*
|
||||||
|
* - For incoming transactions - user who subscribed to the channel
|
||||||
|
* - For outgoing transactions - channel which was subscribed to
|
||||||
|
*/
|
||||||
|
peer: Peer
|
||||||
|
|
||||||
|
/** Period of the subscription, in seconds */
|
||||||
|
period: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export class StarsTransaction {
|
||||||
|
constructor(
|
||||||
|
readonly raw: tl.RawStarsTransaction,
|
||||||
|
readonly peers: PeersIndex,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
/** ID of the transaction */
|
||||||
|
get id(): string {
|
||||||
|
return this.raw.id
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Whether this transaction is a refund */
|
||||||
|
get isRefund(): boolean {
|
||||||
|
return this.raw.refund!
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether this transaction is outgoing or incoming
|
||||||
|
*/
|
||||||
|
get direction(): 'incoming' | 'outgoing' {
|
||||||
|
let isNegative = this.raw.stars.isNegative()
|
||||||
|
if (this.raw.refund) isNegative = !isNegative
|
||||||
|
|
||||||
|
return isNegative ? 'outgoing' : 'incoming'
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Absolute amount of stars in the transaction */
|
||||||
|
get amount(): tl.Long {
|
||||||
|
let res = this.raw.stars
|
||||||
|
|
||||||
|
if (res.isNegative()) {
|
||||||
|
res = res.negate()
|
||||||
|
}
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Date of the transaction */
|
||||||
|
get date(): Date {
|
||||||
|
return new Date(this.raw.date * 1000)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Type of this transaction */
|
||||||
|
get type(): StarsTransactionType {
|
||||||
|
switch (this.raw.peer._) {
|
||||||
|
case 'starsTransactionPeerAppStore':
|
||||||
|
return { type: 'app_store' }
|
||||||
|
case 'starsTransactionPeerPlayMarket':
|
||||||
|
return { type: 'play_market' }
|
||||||
|
case 'starsTransactionPeerPremiumBot':
|
||||||
|
return { type: 'premium_bot' }
|
||||||
|
case 'starsTransactionPeerFragment': {
|
||||||
|
if (this.raw.gift) {
|
||||||
|
return { type: 'fragment' }
|
||||||
|
}
|
||||||
|
|
||||||
|
let status
|
||||||
|
if (this.raw.pending) {
|
||||||
|
status = 'pending' as const
|
||||||
|
} else if (this.raw.failed) {
|
||||||
|
status = 'failed' as const
|
||||||
|
} else {
|
||||||
|
status = 'success' as const
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: 'fragment_withdraw',
|
||||||
|
status,
|
||||||
|
date: this.raw.transactionDate
|
||||||
|
? new Date(this.raw.transactionDate * 1000)
|
||||||
|
: undefined,
|
||||||
|
url: this.raw.transactionUrl,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case 'starsTransactionPeerAds':
|
||||||
|
return { type: 'ads' }
|
||||||
|
case 'starsTransactionPeer': {
|
||||||
|
const peer = parsePeer(this.raw.peer.peer, this.peers)
|
||||||
|
|
||||||
|
if (this.raw.msgId) {
|
||||||
|
if (this.raw.reaction) {
|
||||||
|
return {
|
||||||
|
type: 'reaction',
|
||||||
|
peer,
|
||||||
|
messageId: this.raw.msgId,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: 'media_purchase',
|
||||||
|
peer,
|
||||||
|
messageId: this.raw.msgId,
|
||||||
|
media: this.raw.extendedMedia
|
||||||
|
? this.raw.extendedMedia.map(it => _messageMediaFromTl(this.peers, it))
|
||||||
|
: undefined,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.raw.subscriptionPeriod) {
|
||||||
|
return {
|
||||||
|
type: 'channel_subscription',
|
||||||
|
peer,
|
||||||
|
period: this.raw.subscriptionPeriod,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (peer.type === 'user') {
|
||||||
|
if (this.raw.gift && !peer.isBot) {
|
||||||
|
return { type: 'gift', user: peer }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.raw.title
|
||||||
|
|| this.raw.description
|
||||||
|
|| this.raw.photo
|
||||||
|
|| this.raw.botPayload) {
|
||||||
|
return {
|
||||||
|
type: 'bot_purchase',
|
||||||
|
user: peer,
|
||||||
|
title: this.raw.title ?? '',
|
||||||
|
description: this.raw.description,
|
||||||
|
payload: this.raw.botPayload,
|
||||||
|
photo: this.raw.photo
|
||||||
|
? new WebDocument(this.raw.photo)
|
||||||
|
: undefined,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { type: 'unsupported' }
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo
|
||||||
|
return { type: 'unsupported' }
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return { type: 'unsupported' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
makeInspectable(StarsTransaction)
|
||||||
|
memoizeGetters(StarsTransaction, ['amount', 'type'])
|
Loading…
Reference in a new issue