feat(core): message effects
This commit is contained in:
parent
f84da0dce8
commit
710ef3f211
12 changed files with 146 additions and 1 deletions
|
@ -132,6 +132,7 @@ import { editInlineMessage } from './methods/messages/edit-inline-message.js'
|
||||||
import { editMessage } from './methods/messages/edit-message.js'
|
import { editMessage } from './methods/messages/edit-message.js'
|
||||||
import { ForwardMessageOptions, forwardMessages, forwardMessagesById } from './methods/messages/forward-messages.js'
|
import { ForwardMessageOptions, forwardMessages, forwardMessagesById } from './methods/messages/forward-messages.js'
|
||||||
import { getAllScheduledMessages } from './methods/messages/get-all-scheduled-messages.js'
|
import { getAllScheduledMessages } from './methods/messages/get-all-scheduled-messages.js'
|
||||||
|
import { getAvailableMessageEffects } from './methods/messages/get-available-effects.js'
|
||||||
import { getCallbackQueryMessage } from './methods/messages/get-callback-query-message.js'
|
import { getCallbackQueryMessage } from './methods/messages/get-callback-query-message.js'
|
||||||
import { getDiscussionMessage } from './methods/messages/get-discussion-message.js'
|
import { getDiscussionMessage } from './methods/messages/get-discussion-message.js'
|
||||||
import { getFactCheck } from './methods/messages/get-fact-check.js'
|
import { getFactCheck } from './methods/messages/get-fact-check.js'
|
||||||
|
@ -302,6 +303,7 @@ import {
|
||||||
InputText,
|
InputText,
|
||||||
MaybeDynamic,
|
MaybeDynamic,
|
||||||
Message,
|
Message,
|
||||||
|
MessageEffect,
|
||||||
MessageMedia,
|
MessageMedia,
|
||||||
MessageReactions,
|
MessageReactions,
|
||||||
ParametersSkip2,
|
ParametersSkip2,
|
||||||
|
@ -3245,6 +3247,13 @@ export interface TelegramClient extends ITelegramClient {
|
||||||
*/
|
*/
|
||||||
getAllScheduledMessages(chatId: InputPeerLike): Promise<Message[]>
|
getAllScheduledMessages(chatId: InputPeerLike): Promise<Message[]>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of available message effects
|
||||||
|
* **Available**: 👤 users only
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
getAvailableMessageEffects(): Promise<MessageEffect[]>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the message containing the button being clicked
|
* Get the message containing the button being clicked
|
||||||
* in the given callback query.
|
* in the given callback query.
|
||||||
|
@ -5916,6 +5925,9 @@ TelegramClient.prototype.forwardMessages = function (...args) {
|
||||||
TelegramClient.prototype.getAllScheduledMessages = function (...args) {
|
TelegramClient.prototype.getAllScheduledMessages = function (...args) {
|
||||||
return getAllScheduledMessages(this._client, ...args)
|
return getAllScheduledMessages(this._client, ...args)
|
||||||
}
|
}
|
||||||
|
TelegramClient.prototype.getAvailableMessageEffects = function (...args) {
|
||||||
|
return getAvailableMessageEffects(this._client, ...args)
|
||||||
|
}
|
||||||
TelegramClient.prototype.getCallbackQueryMessage = function (...args) {
|
TelegramClient.prototype.getCallbackQueryMessage = function (...args) {
|
||||||
return getCallbackQueryMessage(this._client, ...args)
|
return getCallbackQueryMessage(this._client, ...args)
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,6 +130,7 @@ export type { ForwardMessageOptions } from './methods/messages/forward-messages.
|
||||||
export { forwardMessagesById } from './methods/messages/forward-messages.js'
|
export { forwardMessagesById } from './methods/messages/forward-messages.js'
|
||||||
export { forwardMessages } from './methods/messages/forward-messages.js'
|
export { forwardMessages } from './methods/messages/forward-messages.js'
|
||||||
export { getAllScheduledMessages } from './methods/messages/get-all-scheduled-messages.js'
|
export { getAllScheduledMessages } from './methods/messages/get-all-scheduled-messages.js'
|
||||||
|
export { getAvailableMessageEffects } from './methods/messages/get-available-effects.js'
|
||||||
export { getCallbackQueryMessage } from './methods/messages/get-callback-query-message.js'
|
export { getCallbackQueryMessage } from './methods/messages/get-callback-query-message.js'
|
||||||
export { getDiscussionMessage } from './methods/messages/get-discussion-message.js'
|
export { getDiscussionMessage } from './methods/messages/get-discussion-message.js'
|
||||||
export { getFactCheck } from './methods/messages/get-fact-check.js'
|
export { getFactCheck } from './methods/messages/get-fact-check.js'
|
||||||
|
|
|
@ -69,6 +69,7 @@ import {
|
||||||
InputText,
|
InputText,
|
||||||
MaybeDynamic,
|
MaybeDynamic,
|
||||||
Message,
|
Message,
|
||||||
|
MessageEffect,
|
||||||
MessageMedia,
|
MessageMedia,
|
||||||
MessageReactions,
|
MessageReactions,
|
||||||
ParametersSkip2,
|
ParametersSkip2,
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { tl } from '@mtcute/tl'
|
import { tl } from '@mtcute/tl'
|
||||||
|
|
||||||
import { RpcCallOptions } from '../../../network/network-manager.js'
|
import { RpcCallOptions } from '../../../network/network-manager.js'
|
||||||
|
import { MustEqual } from '../../../types/utils.js'
|
||||||
import { LruMap } from '../../../utils/lru-map.js'
|
import { LruMap } from '../../../utils/lru-map.js'
|
||||||
import { ITelegramClient } from '../../client.types.js'
|
import { ITelegramClient } from '../../client.types.js'
|
||||||
import { getBusinessConnection } from '../premium/get-business-connection.js'
|
import { getBusinessConnection } from '../premium/get-business-connection.js'
|
||||||
|
@ -26,7 +27,7 @@ const getDcMap = (client: ITelegramClient): LruMap<string, number> => {
|
||||||
export async function _maybeInvokeWithBusinessConnection<T extends tl.RpcMethod>(
|
export async function _maybeInvokeWithBusinessConnection<T extends tl.RpcMethod>(
|
||||||
client: ITelegramClient,
|
client: ITelegramClient,
|
||||||
businessConnectionId: string | undefined,
|
businessConnectionId: string | undefined,
|
||||||
request: T,
|
request: MustEqual<T, tl.RpcMethod>,
|
||||||
params?: RpcCallOptions,
|
params?: RpcCallOptions,
|
||||||
): Promise<tl.RpcCallReturn[T['_']]> {
|
): Promise<tl.RpcCallReturn[T['_']]> {
|
||||||
if (!businessConnectionId) {
|
if (!businessConnectionId) {
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
import { tl } from '@mtcute/tl'
|
||||||
|
|
||||||
|
import { LongMap } from '../../../utils/long-utils.js'
|
||||||
|
import { assertTypeIsNot } from '../../../utils/type-assertions.js'
|
||||||
|
import { ITelegramClient } from '../../client.types.js'
|
||||||
|
import { MessageEffect } from '../../types/index.js'
|
||||||
|
|
||||||
|
// @available=user
|
||||||
|
/**
|
||||||
|
* Get a list of available message effects
|
||||||
|
*/
|
||||||
|
export async function getAvailableMessageEffects(client: ITelegramClient): Promise<MessageEffect[]> {
|
||||||
|
const res = await client.call({
|
||||||
|
_: 'messages.getAvailableEffects',
|
||||||
|
hash: 0,
|
||||||
|
})
|
||||||
|
|
||||||
|
assertTypeIsNot('getAvailableMessageEffects', res, 'messages.availableEffectsNotModified')
|
||||||
|
|
||||||
|
const documentsMap = new LongMap<tl.RawDocument>()
|
||||||
|
|
||||||
|
for (const doc of res.documents) {
|
||||||
|
if (doc._ !== 'document') continue
|
||||||
|
documentsMap.set(doc.id, doc)
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.effects.map((effect) => new MessageEffect(effect, documentsMap))
|
||||||
|
}
|
|
@ -117,6 +117,13 @@ export interface CommonSendParams {
|
||||||
* the message will be sent
|
* the message will be sent
|
||||||
*/
|
*/
|
||||||
businessConnectionId?: string
|
businessConnectionId?: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ID of a message effect to use when sending the message
|
||||||
|
* (see {@link TelegramClient.getAvailableMessageEffects})
|
||||||
|
*/
|
||||||
|
effect?: tl.Long
|
||||||
|
// todo: once we have a caching layer, we can accept an emoji here
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -114,6 +114,7 @@ export async function sendMediaGroup(
|
||||||
sendAs: params.sendAs ? await resolvePeer(client, params.sendAs) : undefined,
|
sendAs: params.sendAs ? await resolvePeer(client, params.sendAs) : undefined,
|
||||||
invertMedia: params.invertMedia,
|
invertMedia: params.invertMedia,
|
||||||
quickReplyShortcut,
|
quickReplyShortcut,
|
||||||
|
effect: params.effect,
|
||||||
},
|
},
|
||||||
{ chainId },
|
{ chainId },
|
||||||
)
|
)
|
||||||
|
|
|
@ -107,6 +107,7 @@ export async function sendMedia(
|
||||||
sendAs: params.sendAs ? await resolvePeer(client, params.sendAs) : undefined,
|
sendAs: params.sendAs ? await resolvePeer(client, params.sendAs) : undefined,
|
||||||
invertMedia: params.invert,
|
invertMedia: params.invert,
|
||||||
quickReplyShortcut,
|
quickReplyShortcut,
|
||||||
|
effect: params.effect,
|
||||||
},
|
},
|
||||||
{ chainId },
|
{ chainId },
|
||||||
)
|
)
|
||||||
|
|
|
@ -81,6 +81,7 @@ export async function sendText(
|
||||||
sendAs: params.sendAs ? await resolvePeer(client, params.sendAs) : undefined,
|
sendAs: params.sendAs ? await resolvePeer(client, params.sendAs) : undefined,
|
||||||
invertMedia: params.invertMedia,
|
invertMedia: params.invertMedia,
|
||||||
quickReplyShortcut,
|
quickReplyShortcut,
|
||||||
|
effect: params.effect,
|
||||||
},
|
},
|
||||||
{ chainId },
|
{ chainId },
|
||||||
)
|
)
|
||||||
|
|
|
@ -4,6 +4,7 @@ export * from './fact-check.js'
|
||||||
export * from './input-message-id.js'
|
export * from './input-message-id.js'
|
||||||
export * from './message.js'
|
export * from './message.js'
|
||||||
export * from './message-action.js'
|
export * from './message-action.js'
|
||||||
|
export * from './message-effect.js'
|
||||||
export * from './message-entity.js'
|
export * from './message-entity.js'
|
||||||
export * from './message-forward.js'
|
export * from './message-forward.js'
|
||||||
export * from './message-media.js'
|
export * from './message-media.js'
|
||||||
|
|
82
packages/core/src/highlevel/types/messages/message-effect.ts
Normal file
82
packages/core/src/highlevel/types/messages/message-effect.ts
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
import { tl } from '@mtcute/tl'
|
||||||
|
|
||||||
|
import { MtTypeAssertionError } from '../../../types/errors.js'
|
||||||
|
import { LongMap } from '../../../utils/long-utils.js'
|
||||||
|
import { makeInspectable } from '../../utils/inspectable.js'
|
||||||
|
import { memoizeGetters } from '../../utils/memoize.js'
|
||||||
|
import { parseSticker } from '../media/document-utils.js'
|
||||||
|
import { Sticker } from '../media/sticker.js'
|
||||||
|
|
||||||
|
export class MessageEffect {
|
||||||
|
constructor(
|
||||||
|
readonly raw: tl.RawAvailableEffect,
|
||||||
|
readonly documentsMap: LongMap<tl.RawDocument>,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
/** Whether Telegram Premium is required to use this effect */
|
||||||
|
get isPremiumRequired(): boolean {
|
||||||
|
return this.raw.premiumRequired!
|
||||||
|
}
|
||||||
|
|
||||||
|
/** ID of this effect */
|
||||||
|
get id(): tl.Long {
|
||||||
|
return this.raw.id
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Emoji representint this reaction */
|
||||||
|
get emoji(): string {
|
||||||
|
return this.raw.emoticon
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sticker representing a static icon for this effect (if any) */
|
||||||
|
get staticIcon(): Sticker | null {
|
||||||
|
if (!this.raw.staticIconId) return null
|
||||||
|
|
||||||
|
const document = this.documentsMap.get(this.raw.staticIconId)
|
||||||
|
if (!document) return null
|
||||||
|
|
||||||
|
const parsed = parseSticker(document)
|
||||||
|
|
||||||
|
if (!parsed) {
|
||||||
|
throw new MtTypeAssertionError('MessageEffect.staticIcon', 'sticker', 'null')
|
||||||
|
}
|
||||||
|
|
||||||
|
return parsed
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Animated icon representing the effect */
|
||||||
|
get icon(): Sticker {
|
||||||
|
const document = this.documentsMap.get(this.raw.effectStickerId)
|
||||||
|
|
||||||
|
if (!document) {
|
||||||
|
throw new MtTypeAssertionError('MessageEffect.effect', 'document', 'null')
|
||||||
|
}
|
||||||
|
|
||||||
|
const parsed = parseSticker(document)
|
||||||
|
|
||||||
|
if (!parsed) {
|
||||||
|
throw new MtTypeAssertionError('MessageEffect.effect', 'sticker', 'null')
|
||||||
|
}
|
||||||
|
|
||||||
|
return parsed
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The animation itself */
|
||||||
|
get animation(): Sticker | null {
|
||||||
|
if (!this.raw.effectAnimationId) return null
|
||||||
|
|
||||||
|
const document = this.documentsMap.get(this.raw.effectAnimationId)
|
||||||
|
if (!document) return null
|
||||||
|
|
||||||
|
const parsed = parseSticker(document)
|
||||||
|
|
||||||
|
if (!parsed) {
|
||||||
|
throw new MtTypeAssertionError('MessageEffect.effectAnimation', 'sticker', 'null')
|
||||||
|
}
|
||||||
|
|
||||||
|
return parsed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memoizeGetters(MessageEffect, ['staticIcon', 'icon', 'animation'])
|
||||||
|
makeInspectable(MessageEffect)
|
|
@ -484,6 +484,15 @@ export class Message {
|
||||||
return new FactCheck(this.raw.factcheck)
|
return new FactCheck(this.raw.factcheck)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If this message was sent with a message effect, ID of the effect
|
||||||
|
*/
|
||||||
|
get effectId(): tl.Long | null {
|
||||||
|
if (this.raw._ === 'messageService') return null
|
||||||
|
|
||||||
|
return this.raw.effect ?? null
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generated permalink to this message, only for groups and channels
|
* Generated permalink to this message, only for groups and channels
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in a new issue