feat(client): chat event logs
also added support for chat locations and fixed ts errors
This commit is contained in:
parent
4ad562bf06
commit
f0eb95e4ba
8 changed files with 927 additions and 2 deletions
|
@ -27,6 +27,7 @@ import { deleteChatPhoto } from './methods/chats/delete-chat-photo'
|
||||||
import { deleteGroup } from './methods/chats/delete-group'
|
import { deleteGroup } from './methods/chats/delete-group'
|
||||||
import { deleteHistory } from './methods/chats/delete-history'
|
import { deleteHistory } from './methods/chats/delete-history'
|
||||||
import { deleteUserHistory } from './methods/chats/delete-user-history'
|
import { deleteUserHistory } from './methods/chats/delete-user-history'
|
||||||
|
import { getChatEventLog } from './methods/chats/get-chat-event-log'
|
||||||
import { getChatMember } from './methods/chats/get-chat-member'
|
import { getChatMember } from './methods/chats/get-chat-member'
|
||||||
import { getChatMembers } from './methods/chats/get-chat-members'
|
import { getChatMembers } from './methods/chats/get-chat-members'
|
||||||
import { getChatPreview } from './methods/chats/get-chat-preview'
|
import { getChatPreview } from './methods/chats/get-chat-preview'
|
||||||
|
@ -137,6 +138,8 @@ import { IMessageEntityParser } from './parser'
|
||||||
import { Readable } from 'stream'
|
import { Readable } from 'stream'
|
||||||
import {
|
import {
|
||||||
Chat,
|
Chat,
|
||||||
|
ChatEvent,
|
||||||
|
ChatInviteLink,
|
||||||
ChatMember,
|
ChatMember,
|
||||||
ChatPreview,
|
ChatPreview,
|
||||||
Dialog,
|
Dialog,
|
||||||
|
@ -673,6 +676,74 @@ export interface TelegramClient extends BaseTelegramClient {
|
||||||
chatId: InputPeerLike,
|
chatId: InputPeerLike,
|
||||||
userId: InputPeerLike
|
userId: InputPeerLike
|
||||||
): Promise<void>
|
): Promise<void>
|
||||||
|
/**
|
||||||
|
* Get chat event log ("Recent actions" in official
|
||||||
|
* clients).
|
||||||
|
*
|
||||||
|
* Only available for supergroups and channels, and
|
||||||
|
* requires (any) administrator rights.
|
||||||
|
*
|
||||||
|
* Results are returned in reverse chronological
|
||||||
|
* order (i.e. newest first) and event IDs are
|
||||||
|
* in direct chronological order (i.e. newer
|
||||||
|
* events have bigger event ID)
|
||||||
|
*
|
||||||
|
* @param chatId Chat ID
|
||||||
|
* @param params
|
||||||
|
*/
|
||||||
|
getChatEventLog(
|
||||||
|
chatId: InputPeerLike,
|
||||||
|
params?: {
|
||||||
|
/**
|
||||||
|
* Search query
|
||||||
|
*/
|
||||||
|
query?: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Minimum event ID to return
|
||||||
|
*/
|
||||||
|
minId?: tl.Long
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maximum event ID to return,
|
||||||
|
* can be used as a base offset
|
||||||
|
*/
|
||||||
|
maxId?: tl.Long
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of users whose actions to return
|
||||||
|
*/
|
||||||
|
users?: InputPeerLike[]
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event filters. Can be a TL object, or one or more
|
||||||
|
* action types.
|
||||||
|
*
|
||||||
|
* Note that some filters are grouped in TL
|
||||||
|
* (i.e. `info=true` will return `title_changed`,
|
||||||
|
* `username_changed` and many more),
|
||||||
|
* and when passing one or more action types,
|
||||||
|
* they will be filtered locally.
|
||||||
|
*/
|
||||||
|
filters?:
|
||||||
|
| tl.TypeChannelAdminLogEventsFilter
|
||||||
|
| MaybeArray<Exclude<ChatEvent.Action, null>['type']>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Limit the number of events returned.
|
||||||
|
*
|
||||||
|
* Defaults to `Infinity`, i.e. all events are returned
|
||||||
|
*/
|
||||||
|
limit?: number
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chunk size, usually not needed.
|
||||||
|
*
|
||||||
|
* Defaults to `100`
|
||||||
|
*/
|
||||||
|
chunkSize?: number
|
||||||
|
}
|
||||||
|
): AsyncIterableIterator<ChatEvent>
|
||||||
/**
|
/**
|
||||||
* Get information about a single chat member
|
* Get information about a single chat member
|
||||||
*
|
*
|
||||||
|
@ -2682,6 +2753,7 @@ export class TelegramClient extends BaseTelegramClient {
|
||||||
deleteGroup = deleteGroup
|
deleteGroup = deleteGroup
|
||||||
deleteHistory = deleteHistory
|
deleteHistory = deleteHistory
|
||||||
deleteUserHistory = deleteUserHistory
|
deleteUserHistory = deleteUserHistory
|
||||||
|
getChatEventLog = getChatEventLog
|
||||||
getChatMember = getChatMember
|
getChatMember = getChatMember
|
||||||
getChatMembers = getChatMembers
|
getChatMembers = getChatMembers
|
||||||
getChatPreview = getChatPreview
|
getChatPreview = getChatPreview
|
||||||
|
|
|
@ -33,7 +33,9 @@ import {
|
||||||
StickerSet,
|
StickerSet,
|
||||||
Poll,
|
Poll,
|
||||||
TypingStatus,
|
TypingStatus,
|
||||||
Photo
|
Photo,
|
||||||
|
ChatEvent,
|
||||||
|
ChatInviteLink
|
||||||
} from '../types'
|
} from '../types'
|
||||||
|
|
||||||
// @copy
|
// @copy
|
||||||
|
|
242
packages/client/src/methods/chats/get-chat-event-log.ts
Normal file
242
packages/client/src/methods/chats/get-chat-event-log.ts
Normal file
|
@ -0,0 +1,242 @@
|
||||||
|
import { TelegramClient } from '../../client'
|
||||||
|
import {
|
||||||
|
InputPeerLike,
|
||||||
|
MtCuteInvalidPeerTypeError,
|
||||||
|
ChatEvent,
|
||||||
|
} from '../../types'
|
||||||
|
import { tl } from '@mtcute/tl'
|
||||||
|
import { MaybeArray } from '@mtcute/core'
|
||||||
|
import bigInt from 'big-integer'
|
||||||
|
import {
|
||||||
|
createUsersChatsIndex,
|
||||||
|
normalizeToInputChannel,
|
||||||
|
normalizeToInputUser,
|
||||||
|
} from '../../utils/peer-utils'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get chat event log ("Recent actions" in official
|
||||||
|
* clients).
|
||||||
|
*
|
||||||
|
* Only available for supergroups and channels, and
|
||||||
|
* requires (any) administrator rights.
|
||||||
|
*
|
||||||
|
* Results are returned in reverse chronological
|
||||||
|
* order (i.e. newest first) and event IDs are
|
||||||
|
* in direct chronological order (i.e. newer
|
||||||
|
* events have bigger event ID)
|
||||||
|
*
|
||||||
|
* @param chatId Chat ID
|
||||||
|
* @param params
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
export async function* getChatEventLog(
|
||||||
|
this: TelegramClient,
|
||||||
|
chatId: InputPeerLike,
|
||||||
|
params?: {
|
||||||
|
/**
|
||||||
|
* Search query
|
||||||
|
*/
|
||||||
|
query?: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Minimum event ID to return
|
||||||
|
*/
|
||||||
|
minId?: tl.Long
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maximum event ID to return,
|
||||||
|
* can be used as a base offset
|
||||||
|
*/
|
||||||
|
maxId?: tl.Long
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of users whose actions to return
|
||||||
|
*/
|
||||||
|
users?: InputPeerLike[]
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event filters. Can be a TL object, or one or more
|
||||||
|
* action types.
|
||||||
|
*
|
||||||
|
* Note that some filters are grouped in TL
|
||||||
|
* (i.e. `info=true` will return `title_changed`,
|
||||||
|
* `username_changed` and many more),
|
||||||
|
* and when passing one or more action types,
|
||||||
|
* they will be filtered locally.
|
||||||
|
*/
|
||||||
|
filters?:
|
||||||
|
| tl.TypeChannelAdminLogEventsFilter
|
||||||
|
| MaybeArray<Exclude<ChatEvent.Action, null>['type']>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Limit the number of events returned.
|
||||||
|
*
|
||||||
|
* Defaults to `Infinity`, i.e. all events are returned
|
||||||
|
*/
|
||||||
|
limit?: number
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chunk size, usually not needed.
|
||||||
|
*
|
||||||
|
* Defaults to `100`
|
||||||
|
*/
|
||||||
|
chunkSize?: number
|
||||||
|
}
|
||||||
|
): AsyncIterableIterator<ChatEvent> {
|
||||||
|
if (!params) params = {}
|
||||||
|
|
||||||
|
const channel = normalizeToInputChannel(await this.resolvePeer(chatId))
|
||||||
|
if (!channel) throw new MtCuteInvalidPeerTypeError(chatId, 'channel')
|
||||||
|
|
||||||
|
let current = 0
|
||||||
|
let maxId = params.maxId ?? bigInt.zero
|
||||||
|
const minId = params.minId ?? bigInt.zero
|
||||||
|
const query = params.query ?? ''
|
||||||
|
|
||||||
|
const total = params.limit || Infinity
|
||||||
|
const chunkSize = Math.min(params.chunkSize ?? 100, total)
|
||||||
|
|
||||||
|
const admins: tl.TypeInputUser[] | undefined = params.users
|
||||||
|
? ((await Promise.all(
|
||||||
|
params.users
|
||||||
|
.map((u) => this.resolvePeer(u).then(normalizeToInputUser))
|
||||||
|
.filter(Boolean)
|
||||||
|
)) as tl.TypeInputUser[])
|
||||||
|
: undefined
|
||||||
|
|
||||||
|
let serverFilter:
|
||||||
|
| tl.Mutable<tl.TypeChannelAdminLogEventsFilter>
|
||||||
|
| undefined = undefined
|
||||||
|
let localFilter: Record<string, true> | undefined = undefined
|
||||||
|
if (params.filters) {
|
||||||
|
if (
|
||||||
|
typeof params.filters === 'string' ||
|
||||||
|
Array.isArray(params.filters)
|
||||||
|
) {
|
||||||
|
let input = params.filters
|
||||||
|
if (!Array.isArray(input)) input = [input]
|
||||||
|
|
||||||
|
serverFilter = {
|
||||||
|
_: 'channelAdminLogEventsFilter',
|
||||||
|
}
|
||||||
|
localFilter = {}
|
||||||
|
|
||||||
|
input.forEach((type) => {
|
||||||
|
localFilter![type] = true
|
||||||
|
switch (type) {
|
||||||
|
case 'user_joined':
|
||||||
|
serverFilter!.join = true
|
||||||
|
break
|
||||||
|
case 'user_left':
|
||||||
|
serverFilter!.leave = true
|
||||||
|
break
|
||||||
|
case 'user_invited':
|
||||||
|
serverFilter!.invite = true
|
||||||
|
break
|
||||||
|
case 'title_changed':
|
||||||
|
case 'description_changed':
|
||||||
|
case 'linked_chat_changed':
|
||||||
|
case 'location_changed':
|
||||||
|
case 'photo_changed':
|
||||||
|
case 'username_changed':
|
||||||
|
case 'stickerset_changed':
|
||||||
|
serverFilter!.info = true
|
||||||
|
break
|
||||||
|
case 'invites_toggled':
|
||||||
|
case 'history_toggled':
|
||||||
|
case 'signatures_toggled':
|
||||||
|
case 'def_perms_changed':
|
||||||
|
serverFilter!.settings = true
|
||||||
|
break
|
||||||
|
case 'msg_pinned':
|
||||||
|
serverFilter!.pinned = true
|
||||||
|
break
|
||||||
|
case 'msg_edited':
|
||||||
|
case 'poll_stopped':
|
||||||
|
serverFilter!.edit = true
|
||||||
|
break
|
||||||
|
case 'msg_deleted':
|
||||||
|
serverFilter!.delete = true
|
||||||
|
break
|
||||||
|
case 'user_perms_changed':
|
||||||
|
serverFilter!.ban = true
|
||||||
|
serverFilter!.unban = true
|
||||||
|
serverFilter!.kick = true
|
||||||
|
serverFilter!.unkick = true
|
||||||
|
break
|
||||||
|
case 'user_admin_perms_changed':
|
||||||
|
serverFilter!.promote = true
|
||||||
|
serverFilter!.demote = true
|
||||||
|
break
|
||||||
|
case 'slow_mode_changed':
|
||||||
|
case 'ttl_changed':
|
||||||
|
// not documented so idk, enable both
|
||||||
|
serverFilter!.settings = true
|
||||||
|
serverFilter!.info = true
|
||||||
|
break
|
||||||
|
case 'call_started':
|
||||||
|
case 'call_ended':
|
||||||
|
serverFilter!.groupCall = true
|
||||||
|
break
|
||||||
|
case 'call_setting_changed':
|
||||||
|
// not documented so idk, enable all
|
||||||
|
serverFilter!.groupCall = true
|
||||||
|
serverFilter!.settings = true
|
||||||
|
serverFilter!.info = true
|
||||||
|
break
|
||||||
|
case 'user_joined_invite':
|
||||||
|
// not documented so idk, enable all
|
||||||
|
serverFilter!.join = true
|
||||||
|
serverFilter!.invite = true
|
||||||
|
serverFilter!.invites = true
|
||||||
|
break
|
||||||
|
case 'invite_deleted':
|
||||||
|
case 'invite_edited':
|
||||||
|
case 'invite_revoked':
|
||||||
|
serverFilter!.invites = true
|
||||||
|
break
|
||||||
|
default: {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
const _: never = type
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
serverFilter = params.filters
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
const res = await this.call({
|
||||||
|
_: 'channels.getAdminLog',
|
||||||
|
channel,
|
||||||
|
q: query,
|
||||||
|
eventsFilter: serverFilter,
|
||||||
|
admins,
|
||||||
|
maxId,
|
||||||
|
minId,
|
||||||
|
limit: Math.min(chunkSize, total - current),
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!res.events.length) break
|
||||||
|
|
||||||
|
const { users, chats } = createUsersChatsIndex(res)
|
||||||
|
const last = res.events[res.events.length - 1]
|
||||||
|
maxId = last.id
|
||||||
|
|
||||||
|
for (const evt of res.events) {
|
||||||
|
const parsed = new ChatEvent(this, evt, users, chats)
|
||||||
|
|
||||||
|
if (
|
||||||
|
localFilter &&
|
||||||
|
(!parsed.action || !localFilter[parsed.action.type])
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
|
||||||
|
current += 1
|
||||||
|
yield parsed
|
||||||
|
|
||||||
|
if (current >= total) break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -563,7 +563,7 @@ export class Message {
|
||||||
*
|
*
|
||||||
* @param revoke Whether to "revoke" (i.e. delete for both sides). Only used for chats and private chats.
|
* @param revoke Whether to "revoke" (i.e. delete for both sides). Only used for chats and private chats.
|
||||||
*/
|
*/
|
||||||
delete(revoke = false): Promise<boolean> {
|
delete(revoke = false): Promise<void> {
|
||||||
return this.client.deleteMessages(this.chat.inputPeer, this.id, revoke)
|
return this.client.deleteMessages(this.chat.inputPeer, this.id, revoke)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
553
packages/client/src/types/peers/chat-event.ts
Normal file
553
packages/client/src/types/peers/chat-event.ts
Normal file
|
@ -0,0 +1,553 @@
|
||||||
|
import { makeInspectable } from '../utils'
|
||||||
|
import { TelegramClient } from '../../client'
|
||||||
|
import { tl } from '@mtcute/tl'
|
||||||
|
import { User } from './user'
|
||||||
|
import { ChatMember } from './chat-member'
|
||||||
|
import { Photo } from '../media'
|
||||||
|
import { Message } from '../messages'
|
||||||
|
import { ChatPermissions } from './chat-permissions'
|
||||||
|
import { ChatLocation } from './chat-location'
|
||||||
|
import { ChatInviteLink } from './chat-invite-link'
|
||||||
|
|
||||||
|
export namespace ChatEvent {
|
||||||
|
/** A user has joined the group (in the case of big groups, info of the user that has joined isn't shown) */
|
||||||
|
export interface ActionUserJoined {
|
||||||
|
type: 'user_joined'
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A user has joined the group using an invite link */
|
||||||
|
export interface ActionUserJoinedInvite {
|
||||||
|
type: 'user_joined_invite'
|
||||||
|
|
||||||
|
/** Invite link user to join */
|
||||||
|
link: ChatInviteLink
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A user has left the group (in the case of big groups, info of the user that has joined isn't shown) */
|
||||||
|
export interface ActionUserLeft {
|
||||||
|
type: 'user_left'
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A user was invited to the group */
|
||||||
|
export interface ActionUserInvited {
|
||||||
|
type: 'user_invited'
|
||||||
|
|
||||||
|
/** Member who has been invited */
|
||||||
|
member: ChatMember
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Group title has been changed */
|
||||||
|
export interface ActionTitleChanged {
|
||||||
|
type: 'title_changed'
|
||||||
|
|
||||||
|
/** Old chat title */
|
||||||
|
old: string
|
||||||
|
|
||||||
|
/** New chat title */
|
||||||
|
new: string
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Group description has been changed */
|
||||||
|
export interface ActionDescriptionChanged {
|
||||||
|
type: 'description_changed'
|
||||||
|
|
||||||
|
/** Old description */
|
||||||
|
old: string
|
||||||
|
|
||||||
|
/** New description */
|
||||||
|
new: string
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Group username has been changed */
|
||||||
|
export interface ActionUsernameChanged {
|
||||||
|
type: 'username_changed'
|
||||||
|
|
||||||
|
/** Old username */
|
||||||
|
old: string
|
||||||
|
|
||||||
|
/** New username */
|
||||||
|
new: string
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Group photo has been changed */
|
||||||
|
export interface ActionPhotoChanged {
|
||||||
|
type: 'photo_changed'
|
||||||
|
|
||||||
|
/** Old photo */
|
||||||
|
old: Photo
|
||||||
|
|
||||||
|
/** New photo */
|
||||||
|
new: Photo
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Invites were enabled/disabled */
|
||||||
|
export interface ActionInvitesToggled {
|
||||||
|
type: 'invites_toggled'
|
||||||
|
|
||||||
|
/** Old value */
|
||||||
|
old: boolean
|
||||||
|
|
||||||
|
/** New value */
|
||||||
|
new: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Signatures were enabled/disabled */
|
||||||
|
export interface ActionSignaturesToggled {
|
||||||
|
type: 'signatures_toggled'
|
||||||
|
|
||||||
|
/** Old value */
|
||||||
|
old: boolean
|
||||||
|
|
||||||
|
/** New value */
|
||||||
|
new: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A message has been pinned */
|
||||||
|
export interface ActionMessagePinned {
|
||||||
|
type: 'msg_pinned'
|
||||||
|
|
||||||
|
/** Message which was pinned */
|
||||||
|
message: Message
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A message has been edited */
|
||||||
|
export interface ActionMessageEdited {
|
||||||
|
type: 'msg_edited'
|
||||||
|
|
||||||
|
/** Old message */
|
||||||
|
old: Message
|
||||||
|
|
||||||
|
/** New message */
|
||||||
|
new: Message
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A message has been deleted */
|
||||||
|
export interface ActionMessageDeleted {
|
||||||
|
type: 'msg_deleted'
|
||||||
|
|
||||||
|
/** Message which was deleted */
|
||||||
|
message: Message
|
||||||
|
}
|
||||||
|
|
||||||
|
/** User's permissions were changed */
|
||||||
|
export interface ActionUserPermissionsChanged {
|
||||||
|
type: 'user_perms_changed'
|
||||||
|
|
||||||
|
/** Information about member before change */
|
||||||
|
old: ChatMember
|
||||||
|
|
||||||
|
/** Information about member after change */
|
||||||
|
new: ChatMember
|
||||||
|
}
|
||||||
|
|
||||||
|
/** User's admin permissions were changed */
|
||||||
|
export interface ActionUserAdminPermissionsChanged {
|
||||||
|
type: 'user_admin_perms_changed'
|
||||||
|
|
||||||
|
/** Information about member before change */
|
||||||
|
old: ChatMember
|
||||||
|
|
||||||
|
/** Information about member after change */
|
||||||
|
new: ChatMember
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Group stickerset has been changed */
|
||||||
|
export interface ActionStickersetChanged {
|
||||||
|
type: 'stickerset_changed'
|
||||||
|
|
||||||
|
/** Old stickerset */
|
||||||
|
old: tl.TypeInputStickerSet
|
||||||
|
|
||||||
|
/** New stickerset */
|
||||||
|
new: tl.TypeInputStickerSet
|
||||||
|
}
|
||||||
|
|
||||||
|
/** History visibility for new users has been toggled */
|
||||||
|
export interface ActionHistoryToggled {
|
||||||
|
type: 'history_toggled'
|
||||||
|
|
||||||
|
/** Old value (`false` if new users can see history) */
|
||||||
|
old: boolean
|
||||||
|
|
||||||
|
/** New value (`false` if new users can see history) */
|
||||||
|
new: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Group default permissions have been changed */
|
||||||
|
export interface ActionDefaultPermissionsChanged {
|
||||||
|
type: 'def_perms_changed'
|
||||||
|
|
||||||
|
/** Old default permissions */
|
||||||
|
old: ChatPermissions
|
||||||
|
|
||||||
|
/** New default permissions */
|
||||||
|
new: ChatPermissions
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Poll has been stopped */
|
||||||
|
export interface ActionPollStopped {
|
||||||
|
type: 'poll_stopped'
|
||||||
|
|
||||||
|
/** Message containing the poll */
|
||||||
|
message: Message
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Linked chat has been changed */
|
||||||
|
export interface ActionLinkedChatChanged {
|
||||||
|
type: 'linked_chat_changed'
|
||||||
|
|
||||||
|
/** ID of the old linked chat */
|
||||||
|
old: number
|
||||||
|
|
||||||
|
/** ID of the new linked chat */
|
||||||
|
new: number
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Group location has been changed */
|
||||||
|
export interface ActionLocationChanged {
|
||||||
|
type: 'location_changed'
|
||||||
|
|
||||||
|
/** Old location */
|
||||||
|
old: ChatLocation | null
|
||||||
|
|
||||||
|
/** New location */
|
||||||
|
new: ChatLocation | null
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Group slow mode delay has been changed */
|
||||||
|
export interface ActionSlowModeChanged {
|
||||||
|
type: 'slow_mode_changed'
|
||||||
|
|
||||||
|
/** Old delay (can be 0) */
|
||||||
|
old: number
|
||||||
|
|
||||||
|
/** New delay (can be 0) */
|
||||||
|
new: number
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Group call has been started */
|
||||||
|
export interface ActionCallStarted {
|
||||||
|
type: 'call_started'
|
||||||
|
|
||||||
|
/** TL object representing the call */
|
||||||
|
call: tl.TypeInputGroupCall
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Group call has ended */
|
||||||
|
export interface ActionCallEnded {
|
||||||
|
type: 'call_ended'
|
||||||
|
|
||||||
|
/** TL object representing the call */
|
||||||
|
call: tl.TypeInputGroupCall
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Group call "join muted" setting has been changed */
|
||||||
|
export interface ActionCallSettingChanged {
|
||||||
|
type: 'call_setting_changed'
|
||||||
|
|
||||||
|
/** Whether new call participants should join muted */
|
||||||
|
joinMuted: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Invite link has been deleted */
|
||||||
|
export interface ActionInviteLinkDeleted {
|
||||||
|
type: 'invite_deleted'
|
||||||
|
|
||||||
|
/** Invite link which was deleted */
|
||||||
|
link: ChatInviteLink
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Invite link has been edited */
|
||||||
|
export interface ActionInviteLinkEdited {
|
||||||
|
type: 'invite_edited'
|
||||||
|
|
||||||
|
/** Old invite link */
|
||||||
|
old: ChatInviteLink
|
||||||
|
|
||||||
|
/** New invite link */
|
||||||
|
new: ChatInviteLink
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Invite link has been revoked */
|
||||||
|
export interface ActionInviteLinkRevoked {
|
||||||
|
type: 'invite_revoked'
|
||||||
|
|
||||||
|
/** Invite link which was revoked */
|
||||||
|
link: ChatInviteLink
|
||||||
|
}
|
||||||
|
|
||||||
|
/** History TTL has been changed */
|
||||||
|
export interface ActionTtlChanged {
|
||||||
|
type: 'ttl_changed'
|
||||||
|
|
||||||
|
/** Old TTL value (can be 0) */
|
||||||
|
old: number
|
||||||
|
|
||||||
|
/** New TTL value (can be 0) */
|
||||||
|
new: number
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Chat event action (`null` if unsupported) */
|
||||||
|
export type Action =
|
||||||
|
| ActionUserJoined
|
||||||
|
| ActionUserLeft
|
||||||
|
| ActionUserInvited
|
||||||
|
| ActionTitleChanged
|
||||||
|
| ActionDescriptionChanged
|
||||||
|
| ActionUsernameChanged
|
||||||
|
| ActionPhotoChanged
|
||||||
|
| ActionInvitesToggled
|
||||||
|
| ActionSignaturesToggled
|
||||||
|
| ActionMessagePinned
|
||||||
|
| ActionMessageEdited
|
||||||
|
| ActionMessageDeleted
|
||||||
|
| ActionUserPermissionsChanged
|
||||||
|
| ActionUserAdminPermissionsChanged
|
||||||
|
| ActionStickersetChanged
|
||||||
|
| ActionHistoryToggled
|
||||||
|
| ActionDefaultPermissionsChanged
|
||||||
|
| ActionPollStopped
|
||||||
|
| ActionLinkedChatChanged
|
||||||
|
| ActionLocationChanged
|
||||||
|
| ActionSlowModeChanged
|
||||||
|
| ActionCallStarted
|
||||||
|
| ActionCallEnded
|
||||||
|
| ActionCallSettingChanged
|
||||||
|
| ActionUserJoinedInvite
|
||||||
|
| ActionInviteLinkDeleted
|
||||||
|
| ActionInviteLinkEdited
|
||||||
|
| ActionInviteLinkRevoked
|
||||||
|
| ActionTtlChanged
|
||||||
|
| null
|
||||||
|
}
|
||||||
|
|
||||||
|
function _actionFromTl(
|
||||||
|
this: ChatEvent,
|
||||||
|
e: tl.TypeChannelAdminLogEventAction
|
||||||
|
): ChatEvent.Action {
|
||||||
|
switch (e._) {
|
||||||
|
case 'channelAdminLogEventActionParticipantJoin':
|
||||||
|
return { type: 'user_joined' }
|
||||||
|
case 'channelAdminLogEventActionChangeTitle':
|
||||||
|
return {
|
||||||
|
type: 'title_changed',
|
||||||
|
old: e.prevValue,
|
||||||
|
new: e.newValue,
|
||||||
|
}
|
||||||
|
case 'channelAdminLogEventActionChangeAbout':
|
||||||
|
return {
|
||||||
|
type: 'description_changed',
|
||||||
|
old: e.prevValue,
|
||||||
|
new: e.newValue,
|
||||||
|
}
|
||||||
|
case 'channelAdminLogEventActionChangeUsername':
|
||||||
|
return {
|
||||||
|
type: 'username_changed',
|
||||||
|
old: e.prevValue,
|
||||||
|
new: e.newValue,
|
||||||
|
}
|
||||||
|
case 'channelAdminLogEventActionChangePhoto':
|
||||||
|
return {
|
||||||
|
type: 'photo_changed',
|
||||||
|
old: new Photo(this.client, e.prevPhoto as tl.RawPhoto),
|
||||||
|
new: new Photo(this.client, e.newPhoto as tl.RawPhoto)
|
||||||
|
}
|
||||||
|
case 'channelAdminLogEventActionToggleInvites':
|
||||||
|
return {
|
||||||
|
type: 'invites_toggled',
|
||||||
|
old: !e.newValue,
|
||||||
|
new: e.newValue
|
||||||
|
}
|
||||||
|
case 'channelAdminLogEventActionToggleSignatures':
|
||||||
|
return {
|
||||||
|
type: 'signatures_toggled',
|
||||||
|
old: !e.newValue,
|
||||||
|
new: e.newValue
|
||||||
|
}
|
||||||
|
case 'channelAdminLogEventActionUpdatePinned':
|
||||||
|
return {
|
||||||
|
type: 'msg_pinned',
|
||||||
|
message: new Message(this.client, e.message, this._users, this._chats)
|
||||||
|
}
|
||||||
|
case 'channelAdminLogEventActionEditMessage':
|
||||||
|
return {
|
||||||
|
type: 'msg_edited',
|
||||||
|
old: new Message(this.client, e.prevMessage, this._users, this._chats),
|
||||||
|
new: new Message(this.client, e.newMessage, this._users, this._chats)
|
||||||
|
}
|
||||||
|
case 'channelAdminLogEventActionDeleteMessage':
|
||||||
|
return {
|
||||||
|
type: 'msg_deleted',
|
||||||
|
message: new Message(this.client, e.message, this._users, this._chats)
|
||||||
|
}
|
||||||
|
case 'channelAdminLogEventActionParticipantLeave':
|
||||||
|
return { type: 'user_left' }
|
||||||
|
case 'channelAdminLogEventActionParticipantInvite':
|
||||||
|
return {
|
||||||
|
type: 'user_invited',
|
||||||
|
member: new ChatMember(this.client, e.participant, this._users),
|
||||||
|
}
|
||||||
|
case 'channelAdminLogEventActionParticipantToggleBan':
|
||||||
|
return {
|
||||||
|
type: 'user_perms_changed',
|
||||||
|
old: new ChatMember(this.client, e.prevParticipant, this._users),
|
||||||
|
new: new ChatMember(this.client, e.newParticipant, this._users)
|
||||||
|
}
|
||||||
|
case 'channelAdminLogEventActionParticipantToggleAdmin':
|
||||||
|
return {
|
||||||
|
type: 'user_admin_perms_changed',
|
||||||
|
old: new ChatMember(this.client, e.prevParticipant, this._users),
|
||||||
|
new: new ChatMember(this.client, e.newParticipant, this._users)
|
||||||
|
}
|
||||||
|
case 'channelAdminLogEventActionChangeStickerSet':
|
||||||
|
return {
|
||||||
|
type: 'stickerset_changed',
|
||||||
|
old: e.prevStickerset,
|
||||||
|
new: e.newStickerset
|
||||||
|
}
|
||||||
|
case 'channelAdminLogEventActionTogglePreHistoryHidden':
|
||||||
|
return {
|
||||||
|
type: 'history_toggled',
|
||||||
|
old: !e.newValue,
|
||||||
|
new: e.newValue
|
||||||
|
}
|
||||||
|
case 'channelAdminLogEventActionDefaultBannedRights':
|
||||||
|
return {
|
||||||
|
type: 'def_perms_changed',
|
||||||
|
old: new ChatPermissions(e.prevBannedRights),
|
||||||
|
new: new ChatPermissions(e.newBannedRights)
|
||||||
|
}
|
||||||
|
case 'channelAdminLogEventActionStopPoll':
|
||||||
|
return {
|
||||||
|
type: 'poll_stopped',
|
||||||
|
message: new Message(this.client, e.message, this._users, this._chats)
|
||||||
|
}
|
||||||
|
case 'channelAdminLogEventActionChangeLinkedChat':
|
||||||
|
return {
|
||||||
|
type: 'linked_chat_changed',
|
||||||
|
old: e.prevValue,
|
||||||
|
new: e.newValue
|
||||||
|
}
|
||||||
|
case 'channelAdminLogEventActionChangeLocation':
|
||||||
|
return {
|
||||||
|
type: 'location_changed',
|
||||||
|
old: e.prevValue._ === 'channelLocationEmpty' ? null : new ChatLocation(this.client, e.prevValue),
|
||||||
|
new: e.newValue._ === 'channelLocationEmpty' ? null : new ChatLocation(this.client, e.newValue),
|
||||||
|
}
|
||||||
|
case 'channelAdminLogEventActionToggleSlowMode':
|
||||||
|
return {
|
||||||
|
type: 'slow_mode_changed',
|
||||||
|
old: e.prevValue,
|
||||||
|
new: e.newValue
|
||||||
|
}
|
||||||
|
case 'channelAdminLogEventActionStartGroupCall':
|
||||||
|
return {
|
||||||
|
type: 'call_started',
|
||||||
|
call: e.call
|
||||||
|
}
|
||||||
|
case 'channelAdminLogEventActionDiscardGroupCall':
|
||||||
|
return {
|
||||||
|
type: 'call_ended',
|
||||||
|
call: e.call
|
||||||
|
}
|
||||||
|
case 'channelAdminLogEventActionParticipantMute':
|
||||||
|
case 'channelAdminLogEventActionParticipantUnmute':
|
||||||
|
case 'channelAdminLogEventActionParticipantVolume':
|
||||||
|
// todo
|
||||||
|
return null
|
||||||
|
case 'channelAdminLogEventActionToggleGroupCallSetting':
|
||||||
|
return {
|
||||||
|
type: 'call_setting_changed',
|
||||||
|
joinMuted: e.joinMuted
|
||||||
|
}
|
||||||
|
case 'channelAdminLogEventActionParticipantJoinByInvite':
|
||||||
|
return {
|
||||||
|
type: 'user_joined_invite',
|
||||||
|
link: new ChatInviteLink(this.client, e.invite, this._users)
|
||||||
|
}
|
||||||
|
case 'channelAdminLogEventActionExportedInviteDelete':
|
||||||
|
return {
|
||||||
|
type: 'invite_deleted',
|
||||||
|
link: new ChatInviteLink(this.client, e.invite, this._users)
|
||||||
|
}
|
||||||
|
case 'channelAdminLogEventActionExportedInviteRevoke':
|
||||||
|
return {
|
||||||
|
type: 'invite_revoked',
|
||||||
|
link: new ChatInviteLink(this.client, e.invite, this._users)
|
||||||
|
}
|
||||||
|
case 'channelAdminLogEventActionExportedInviteEdit':
|
||||||
|
return {
|
||||||
|
type: 'invite_edited',
|
||||||
|
old: new ChatInviteLink(this.client, e.prevInvite, this._users),
|
||||||
|
new: new ChatInviteLink(this.client, e.newInvite, this._users)
|
||||||
|
}
|
||||||
|
case 'channelAdminLogEventActionChangeHistoryTTL':
|
||||||
|
return {
|
||||||
|
type: 'ttl_changed',
|
||||||
|
old: e.prevValue,
|
||||||
|
new: e.newValue
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ChatEvent {
|
||||||
|
readonly client: TelegramClient
|
||||||
|
readonly raw: tl.TypeChannelAdminLogEvent
|
||||||
|
|
||||||
|
readonly _users: Record<number, tl.TypeUser>
|
||||||
|
readonly _chats: Record<number, tl.TypeChat>
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
client: TelegramClient,
|
||||||
|
raw: tl.TypeChannelAdminLogEvent,
|
||||||
|
users: Record<number, tl.TypeUser>,
|
||||||
|
chats: Record<number, tl.TypeChat>
|
||||||
|
) {
|
||||||
|
this.client = client
|
||||||
|
this.raw = raw
|
||||||
|
this._users = users
|
||||||
|
this._chats = chats
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event ID.
|
||||||
|
*
|
||||||
|
* Event IDs are generated in direct chronological order
|
||||||
|
* (i.e. newer events have bigger event ID)
|
||||||
|
*/
|
||||||
|
get id(): tl.Long {
|
||||||
|
return this.raw.id
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Date of the event
|
||||||
|
*/
|
||||||
|
get date(): Date {
|
||||||
|
return new Date(this.raw.date * 1000)
|
||||||
|
}
|
||||||
|
|
||||||
|
private _actor?: User
|
||||||
|
/**
|
||||||
|
* Actor of the event
|
||||||
|
*/
|
||||||
|
get actor(): User {
|
||||||
|
if (!this._actor) {
|
||||||
|
this._actor = new User(this.client, this._users[this.raw.userId])
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._actor
|
||||||
|
}
|
||||||
|
|
||||||
|
private _action?: ChatEvent.Action
|
||||||
|
get action(): ChatEvent.Action {
|
||||||
|
if (!this._action) {
|
||||||
|
this._action = _actionFromTl.call(this, this.raw.action)
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._action!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
makeInspectable(ChatEvent)
|
38
packages/client/src/types/peers/chat-location.ts
Normal file
38
packages/client/src/types/peers/chat-location.ts
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
import { TelegramClient } from '../../client'
|
||||||
|
import { tl } from '@mtcute/tl'
|
||||||
|
import { Location } from '../media'
|
||||||
|
import { makeInspectable } from '../utils'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Geolocation of a supergroup
|
||||||
|
*/
|
||||||
|
export class ChatLocation {
|
||||||
|
readonly client: TelegramClient
|
||||||
|
readonly raw: tl.RawChannelLocation
|
||||||
|
|
||||||
|
constructor (client: TelegramClient, raw: tl.RawChannelLocation) {
|
||||||
|
this.client = client
|
||||||
|
this.raw = raw
|
||||||
|
}
|
||||||
|
|
||||||
|
private _location?: Location
|
||||||
|
/**
|
||||||
|
* Location of the chat
|
||||||
|
*/
|
||||||
|
get location(): Location {
|
||||||
|
if (!this._location) {
|
||||||
|
this._location = new Location(this.client, this.raw.geoPoint as tl.RawGeoPoint)
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._location
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Textual description of the address
|
||||||
|
*/
|
||||||
|
get address(): string {
|
||||||
|
return this.raw.address
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
makeInspectable(ChatLocation)
|
|
@ -6,6 +6,7 @@ import { getMarkedPeerId, MaybeArray } from '@mtcute/core'
|
||||||
import { MtCuteArgumentError, MtCuteTypeAssertionError } from '../errors'
|
import { MtCuteArgumentError, MtCuteTypeAssertionError } from '../errors'
|
||||||
import { makeInspectable } from '../utils'
|
import { makeInspectable } from '../utils'
|
||||||
import { InputPeerLike, User } from './index'
|
import { InputPeerLike, User } from './index'
|
||||||
|
import { ChatLocation } from './chat-location'
|
||||||
|
|
||||||
export namespace Chat {
|
export namespace Chat {
|
||||||
/**
|
/**
|
||||||
|
@ -409,6 +410,22 @@ export class Chat {
|
||||||
*/
|
*/
|
||||||
readonly distance?: number
|
readonly distance?: number
|
||||||
|
|
||||||
|
private _location?: ChatLocation
|
||||||
|
/**
|
||||||
|
* Location of the chat.
|
||||||
|
* Returned only in {@link TelegramClient.getFullChat}
|
||||||
|
*/
|
||||||
|
get location(): ChatLocation | null {
|
||||||
|
if (!this.fullPeer || this.fullPeer._ !== 'channelFull' || this.fullPeer.location?._ !== 'channelLocation')
|
||||||
|
return null
|
||||||
|
|
||||||
|
if (!this._location) {
|
||||||
|
this._location = new ChatLocation(this.client, this.fullPeer.location)
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._location
|
||||||
|
}
|
||||||
|
|
||||||
private _linkedChat?: Chat
|
private _linkedChat?: Chat
|
||||||
/**
|
/**
|
||||||
* The linked discussion group (in case of channels)
|
* The linked discussion group (in case of channels)
|
||||||
|
|
|
@ -5,6 +5,7 @@ export * from './chat'
|
||||||
export * from './chat-preview'
|
export * from './chat-preview'
|
||||||
export { InputChatPermissions } from './chat-permissions'
|
export { InputChatPermissions } from './chat-permissions'
|
||||||
export * from './chat-member'
|
export * from './chat-member'
|
||||||
|
export * from './chat-event'
|
||||||
export * from './chat-invite-link'
|
export * from './chat-invite-link'
|
||||||
export * from './typing-status'
|
export * from './typing-status'
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue