feat: more stories-related stuff
i forgor 💀
This commit is contained in:
parent
c13cb93b97
commit
15b76aab60
12 changed files with 224 additions and 2 deletions
|
@ -229,6 +229,7 @@ import {
|
|||
} from './methods/updates'
|
||||
import { blockUser } from './methods/users/block-user'
|
||||
import { deleteProfilePhotos } from './methods/users/delete-profile-photos'
|
||||
import { editCloseFriends, editCloseFriendsRaw } from './methods/users/edit-close-friends'
|
||||
import { getCommonChats } from './methods/users/get-common-chats'
|
||||
import { getGlobalTtl } from './methods/users/get-global-ttl'
|
||||
import { getMe } from './methods/users/get-me'
|
||||
|
@ -266,6 +267,7 @@ import {
|
|||
ChosenInlineResult,
|
||||
Conversation,
|
||||
DeleteMessageUpdate,
|
||||
DeleteStoryUpdate,
|
||||
Dialog,
|
||||
FileDownloadParameters,
|
||||
FormattedString,
|
||||
|
@ -307,6 +309,7 @@ import {
|
|||
StoriesStealthMode,
|
||||
Story,
|
||||
StoryInteractions,
|
||||
StoryUpdate,
|
||||
StoryViewer,
|
||||
StoryViewersList,
|
||||
TakeoutSession,
|
||||
|
@ -464,6 +467,20 @@ export interface TelegramClient extends BaseTelegramClient {
|
|||
* @param handler Pre checkout query handler
|
||||
*/
|
||||
on(name: 'pre_checkout_query', handler: (upd: PreCheckoutQuery) => void): this
|
||||
/**
|
||||
* Register a story update handler
|
||||
*
|
||||
* @param name Event name
|
||||
* @param handler Story update handler
|
||||
*/
|
||||
on(name: 'story', handler: (upd: StoryUpdate) => void): this
|
||||
/**
|
||||
* Register a delete story handler
|
||||
*
|
||||
* @param name Event name
|
||||
* @param handler Delete story handler
|
||||
*/
|
||||
on(name: 'delete_story', handler: (upd: DeleteStoryUpdate) => void): this
|
||||
/**
|
||||
* Accept the given TOS
|
||||
*
|
||||
|
@ -4139,6 +4156,8 @@ export interface TelegramClient extends BaseTelegramClient {
|
|||
* - `{ can: false }` if the user can't apply boost
|
||||
* - `.reason == "already_boosting"` if the user is already boosting this channel
|
||||
* - `.reason == "need_premium"` if the user needs Premium to boost this channel
|
||||
* - `.reason == "timeout"` if the user has recently boosted a channel and needs to wait
|
||||
* (`.until` contains the date until which the user needs to wait)
|
||||
*/
|
||||
canApplyBoost(peerId: InputPeerLike): Promise<CanApplyBoostResult>
|
||||
/**
|
||||
|
@ -4730,6 +4749,18 @@ export interface TelegramClient extends BaseTelegramClient {
|
|||
* @param ids ID(s) of the photos. Can be file IDs or raw TL objects
|
||||
*/
|
||||
deleteProfilePhotos(ids: MaybeArray<string | tl.TypeInputPhoto>): Promise<void>
|
||||
/**
|
||||
* Edit "close friends" list directly using user IDs
|
||||
*
|
||||
* @param ids User IDs
|
||||
*/
|
||||
editCloseFriendsRaw(ids: number[]): Promise<void>
|
||||
/**
|
||||
* Edit "close friends" list using `InputPeerLike`s
|
||||
*
|
||||
* @param ids User IDs
|
||||
*/
|
||||
editCloseFriends(ids: InputPeerLike[]): Promise<void>
|
||||
/**
|
||||
* Get a list of common chats you have with a given user
|
||||
*
|
||||
|
@ -5211,6 +5242,8 @@ export class TelegramClient extends BaseTelegramClient {
|
|||
_keepAliveAction = _keepAliveAction
|
||||
blockUser = blockUser
|
||||
deleteProfilePhotos = deleteProfilePhotos
|
||||
editCloseFriendsRaw = editCloseFriendsRaw
|
||||
editCloseFriends = editCloseFriends
|
||||
getCommonChats = getCommonChats
|
||||
getGlobalTtl = getGlobalTtl
|
||||
getMe = getMe
|
||||
|
|
|
@ -31,6 +31,7 @@ import {
|
|||
ChosenInlineResult,
|
||||
Conversation,
|
||||
DeleteMessageUpdate,
|
||||
DeleteStoryUpdate,
|
||||
Dialog,
|
||||
FileDownloadParameters,
|
||||
FormattedString,
|
||||
|
@ -72,6 +73,7 @@ import {
|
|||
StoriesStealthMode,
|
||||
Story,
|
||||
StoryInteractions,
|
||||
StoryUpdate,
|
||||
StoryViewer,
|
||||
StoryViewersList,
|
||||
TakeoutSession,
|
||||
|
|
|
@ -192,6 +192,14 @@ export async function _normalizeInputMedia(
|
|||
}
|
||||
}
|
||||
|
||||
if (media.type === 'story') {
|
||||
return {
|
||||
_: 'inputMediaStory',
|
||||
peer: await this.resolvePeer(media.peer),
|
||||
id: media.id,
|
||||
}
|
||||
}
|
||||
|
||||
let inputFile: tl.TypeInputFile | undefined = undefined
|
||||
let thumb: tl.TypeInputFile | undefined = undefined
|
||||
let mime = 'application/octet-stream'
|
||||
|
|
35
packages/client/src/methods/users/edit-close-friends.ts
Normal file
35
packages/client/src/methods/users/edit-close-friends.ts
Normal file
|
@ -0,0 +1,35 @@
|
|||
import { TelegramClient } from '../../client'
|
||||
import { InputPeerLike } from '../../types'
|
||||
import { normalizeToInputUser } from '../../utils'
|
||||
|
||||
/**
|
||||
* Edit "close friends" list directly using user IDs
|
||||
*
|
||||
* @param ids User IDs
|
||||
* @internal
|
||||
*/
|
||||
export async function editCloseFriendsRaw(this: TelegramClient, ids: number[]): Promise<void> {
|
||||
await this.call({
|
||||
_: 'contacts.editCloseFriends',
|
||||
id: ids,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit "close friends" list using `InputPeerLike`s
|
||||
*
|
||||
* @param ids User IDs
|
||||
* @internal
|
||||
*/
|
||||
export async function editCloseFriends(this: TelegramClient, ids: InputPeerLike[]): Promise<void> {
|
||||
await this.call({
|
||||
_: 'contacts.editCloseFriends',
|
||||
id: await this.resolvePeerMany(ids, normalizeToInputUser).then((r) =>
|
||||
r.map((u) => {
|
||||
if ('userId' in u) return u.userId
|
||||
|
||||
return 0
|
||||
}),
|
||||
),
|
||||
})
|
||||
}
|
|
@ -2,6 +2,7 @@ import { MaybeArray, tl } from '@mtcute/core'
|
|||
|
||||
import { InputFileLike } from '../files'
|
||||
import { FormattedString } from '../parser'
|
||||
import { InputPeerLike } from '../peers'
|
||||
import { VenueSource } from './venue'
|
||||
|
||||
export interface CaptionMixin {
|
||||
|
@ -539,6 +540,23 @@ export interface InputMediaQuiz extends Omit<InputMediaPoll, 'type'> {
|
|||
solutionEntities?: tl.TypeMessageEntity[]
|
||||
}
|
||||
|
||||
/**
|
||||
* A story to be sent
|
||||
*/
|
||||
export interface InputMediaStory extends CaptionMixin {
|
||||
type: 'story'
|
||||
|
||||
/**
|
||||
* Owner of the story
|
||||
*/
|
||||
peer: InputPeerLike
|
||||
|
||||
/**
|
||||
* ID of the story
|
||||
*/
|
||||
id: number
|
||||
}
|
||||
|
||||
/**
|
||||
* Input media that can be sent somewhere.
|
||||
*
|
||||
|
@ -565,6 +583,7 @@ export type InputMediaLike =
|
|||
| InputMediaInvoice
|
||||
| InputMediaPoll
|
||||
| InputMediaQuiz
|
||||
| InputMediaStory
|
||||
| tl.TypeInputMedia
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-namespace
|
||||
|
@ -801,6 +820,18 @@ export namespace InputMedia {
|
|||
return ret
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a story to be sent
|
||||
*
|
||||
* @param params Story parameters
|
||||
*/
|
||||
export function story(params: OmitTypeAndFile<InputMediaStory>): InputMediaStory {
|
||||
const ret = params as tl.Mutable<InputMediaStory>
|
||||
ret.type = 'story'
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a document to be sent, which subtype
|
||||
* is inferred automatically by file contents.
|
||||
|
|
|
@ -318,6 +318,15 @@ export class Message {
|
|||
return this.raw.replyTo.replyToTopId ?? null
|
||||
}
|
||||
|
||||
/**
|
||||
* For replies, information about the story that is being replied to
|
||||
*/
|
||||
get replyToStoryId(): tl.RawMessageReplyStoryHeader | null {
|
||||
if (this.raw.replyTo?._ !== 'messageReplyStoryHeader') return null
|
||||
|
||||
return this.raw.replyTo
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this message contains mention of the current user
|
||||
*/
|
||||
|
|
|
@ -202,6 +202,20 @@ export class Chat {
|
|||
return this.peer._ === 'user' && this.peer.contact!
|
||||
}
|
||||
|
||||
/** Whether this peer is a forum supergroup */
|
||||
get isForum(): boolean {
|
||||
return this.peer._ === 'channel' && this.peer.forum!
|
||||
}
|
||||
|
||||
/** Whether you have hidden (arhived) this chat's stories */
|
||||
get storiesHidden(): boolean {
|
||||
return 'storiesHidden' in this.peer ? this.peer.storiesHidden! : false
|
||||
}
|
||||
|
||||
get storiesUnavailable(): boolean {
|
||||
return 'storiesUnavailable' in this.peer ? this.peer.storiesUnavailable! : false
|
||||
}
|
||||
|
||||
/** Whether this group is a channel/supergroup with join requests enabled */
|
||||
get hasJoinRequests(): boolean {
|
||||
return this.peer._ === 'channel' && this.peer.joinRequest!
|
||||
|
@ -451,6 +465,19 @@ export class Chat {
|
|||
return this.fullPeer?.ttlPeriod ?? null
|
||||
}
|
||||
|
||||
/**
|
||||
* Maximum ID of stories this chat has (or 0 if none)
|
||||
*/
|
||||
get storiesMaxId(): number {
|
||||
switch (this.peer._) {
|
||||
case 'channel':
|
||||
case 'user':
|
||||
return this.peer.storiesMaxId ?? 0
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
private _user?: User
|
||||
/**
|
||||
* Get a {@link User} from this chat.
|
||||
|
|
|
@ -5,6 +5,7 @@ import { TelegramClient } from '../../client'
|
|||
import { makeInspectable } from '../../utils'
|
||||
import { InputMediaLike } from '../media'
|
||||
import { FormattedString } from '../parser'
|
||||
import { EmojiStatus } from '../reactions/emoji-status'
|
||||
import { ChatPhoto } from './chat-photo'
|
||||
|
||||
/**
|
||||
|
@ -60,6 +61,11 @@ export class User {
|
|||
return this.raw.mutualContact!
|
||||
}
|
||||
|
||||
/** Whether this user is in yout "close friends" list */
|
||||
get isCloseFriend(): boolean {
|
||||
return this.raw.closeFriend!
|
||||
}
|
||||
|
||||
/** Whether this user is deleted */
|
||||
get isDeleted(): boolean {
|
||||
return this.raw.deleted!
|
||||
|
@ -70,6 +76,26 @@ export class User {
|
|||
return this.raw.bot!
|
||||
}
|
||||
|
||||
/** Whether this user is a bot that has access to all messages */
|
||||
get isBotWithHistory(): boolean {
|
||||
return this.raw.botChatHistory!
|
||||
}
|
||||
|
||||
/** Whether this user is a bot that can't be added to chats */
|
||||
get isBotWithoutChats(): boolean {
|
||||
return this.raw.botNochats!
|
||||
}
|
||||
|
||||
/** Whether this bot offers an attachment menu web app */
|
||||
get isBotWithAttachmentMenu(): boolean {
|
||||
return this.raw.botAttachMenu!
|
||||
}
|
||||
|
||||
/** Whether this bot can be edited by the current user */
|
||||
get isBotEditable(): boolean {
|
||||
return this.raw.botCanEdit!
|
||||
}
|
||||
|
||||
/** Whether this user has been verified by Telegram */
|
||||
get isVerified(): boolean {
|
||||
return this.raw.verified!
|
||||
|
@ -279,6 +305,32 @@ export class User {
|
|||
return this.firstName
|
||||
}
|
||||
|
||||
private _emojiStatus?: EmojiStatus
|
||||
/**
|
||||
* User's emoji status, if any.
|
||||
*/
|
||||
get emojiStatus(): EmojiStatus | null {
|
||||
if (!this.raw.emojiStatus || this.raw.emojiStatus._ === 'emojiStatusEmpty') return null
|
||||
|
||||
return (this._emojiStatus ??= new EmojiStatus(this.raw.emojiStatus))
|
||||
}
|
||||
|
||||
/** Whether you have hidden (arhived) this user's stories */
|
||||
get storiesHidden(): boolean {
|
||||
return this.raw.storiesHidden!
|
||||
}
|
||||
|
||||
get storiesUnavailable(): boolean {
|
||||
return this.raw.storiesUnavailable!
|
||||
}
|
||||
|
||||
/**
|
||||
* Maximum ID of stories this user has (or 0 if none)
|
||||
*/
|
||||
get storiesMaxId(): number {
|
||||
return this.raw.storiesMaxId ?? 0
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a mention for the user.
|
||||
*
|
||||
|
|
24
packages/client/src/types/reactions/emoji-status.ts
Normal file
24
packages/client/src/types/reactions/emoji-status.ts
Normal file
|
@ -0,0 +1,24 @@
|
|||
import { tl } from '@mtcute/core'
|
||||
|
||||
import { makeInspectable } from '../../utils'
|
||||
|
||||
/**
|
||||
* Information about user's emoji status
|
||||
*/
|
||||
export class EmojiStatus {
|
||||
constructor(readonly raw: Exclude<tl.TypeEmojiStatus, tl.RawEmojiStatusEmpty>) {}
|
||||
|
||||
/** ID of the custom emoji */
|
||||
get emoji(): tl.Long {
|
||||
return this.raw.documentId
|
||||
}
|
||||
|
||||
/** This status is valid at most until this date */
|
||||
get expireDate(): Date | null {
|
||||
if (this.raw._ === 'emojiStatus') return null
|
||||
|
||||
return new Date(this.raw.until * 1000)
|
||||
}
|
||||
}
|
||||
|
||||
makeInspectable(EmojiStatus)
|
File diff suppressed because one or more lines are too long
|
@ -153,6 +153,7 @@
|
|||
"account.initTakeoutSession": ["file_max_size"],
|
||||
"account.registerDevice": ["other_uids"],
|
||||
"account.unregisterDevice": ["other_uids"],
|
||||
"contacts.editCloseFriends": ["id"],
|
||||
"messages.addChatUser": ["chat_id"],
|
||||
"messages.deleteChat": ["chat_id"],
|
||||
"messages.deleteChatUser": ["chat_id"],
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
"docs-cli": "ts-node scripts/documentation.ts",
|
||||
"gen-code": "ts-node scripts/gen-code.ts",
|
||||
"gen-rsa": "ts-node scripts/gen-rsa-keys.ts",
|
||||
"fetch-and-gen": "yarn fetch-api && yarn gen-code"
|
||||
"fetch-and-gen": "pnpm run fetch-api && pnpm run gen-code"
|
||||
},
|
||||
"dependencies": {
|
||||
"long": "5.2.3"
|
||||
|
|
Loading…
Reference in a new issue