feat(client): deleteUserHistory method, also properly handle messages.affectedHistory
i suppose? this is an incredibly bad hack but i guess it works so who cares?
This commit is contained in:
parent
c678a0ef6a
commit
f3e4a34eab
7 changed files with 125 additions and 17 deletions
|
@ -26,6 +26,7 @@ import { deleteChannel } from './methods/chats/delete-channel'
|
|||
import { deleteChatPhoto } from './methods/chats/delete-chat-photo'
|
||||
import { deleteGroup } from './methods/chats/delete-group'
|
||||
import { deleteHistory } from './methods/chats/delete-history'
|
||||
import { deleteUserHistory } from './methods/chats/delete-user-history'
|
||||
import { getChatMember } from './methods/chats/get-chat-member'
|
||||
import { getChatMembers } from './methods/chats/get-chat-members'
|
||||
import { getChatPreview } from './methods/chats/get-chat-preview'
|
||||
|
@ -662,6 +663,16 @@ export interface TelegramClient extends BaseTelegramClient {
|
|||
mode?: 'delete' | 'clear' | 'revoke',
|
||||
maxId?: number
|
||||
): Promise<void>
|
||||
/**
|
||||
* Delete all messages of a user in a supergroup
|
||||
*
|
||||
* @param chatId Chat ID
|
||||
* @param userId User ID
|
||||
*/
|
||||
deleteUserHistory(
|
||||
chatId: InputPeerLike,
|
||||
userId: InputPeerLike
|
||||
): Promise<void>
|
||||
/**
|
||||
* Get information about a single chat member
|
||||
*
|
||||
|
@ -1271,7 +1282,7 @@ export interface TelegramClient extends BaseTelegramClient {
|
|||
* > **Note**: each administrator has their own primary invite link,
|
||||
* > and bots by default don't have one.
|
||||
*
|
||||
* @param chatId Chat ID
|
||||
* @param chatId Chat IDs
|
||||
*/
|
||||
exportInviteLink(chatId: InputPeerLike): Promise<ChatInviteLink>
|
||||
/**
|
||||
|
@ -1369,7 +1380,7 @@ export interface TelegramClient extends BaseTelegramClient {
|
|||
chatId: InputPeerLike,
|
||||
ids: MaybeArray<number>,
|
||||
revoke?: boolean
|
||||
): Promise<boolean>
|
||||
): Promise<void>
|
||||
/**
|
||||
* Edit sent inline message text, media and reply markup.
|
||||
*
|
||||
|
@ -2670,6 +2681,7 @@ export class TelegramClient extends BaseTelegramClient {
|
|||
deleteChatPhoto = deleteChatPhoto
|
||||
deleteGroup = deleteGroup
|
||||
deleteHistory = deleteHistory
|
||||
deleteUserHistory = deleteUserHistory
|
||||
getChatMember = getChatMember
|
||||
getChatMembers = getChatMembers
|
||||
getChatPreview = getChatPreview
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import { TelegramClient } from '../../client'
|
||||
import { InputPeerLike } from '../../types'
|
||||
import { normalizeToInputPeer } from '../../utils/peer-utils'
|
||||
import { normalizeToInputChannel, normalizeToInputPeer } from '../../utils/peer-utils'
|
||||
import { createDummyUpdate } from '../../utils/updates-utils'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
/**
|
||||
* Delete communication history (for private chats
|
||||
|
@ -23,11 +25,20 @@ export async function deleteHistory(
|
|||
mode: 'delete' | 'clear' | 'revoke' = 'delete',
|
||||
maxId = 0
|
||||
): Promise<void> {
|
||||
await this.call({
|
||||
const peer = normalizeToInputPeer(await this.resolvePeer(chat))
|
||||
|
||||
const res = await this.call({
|
||||
_: 'messages.deleteHistory',
|
||||
justClear: mode === 'clear',
|
||||
revoke: mode === 'revoke',
|
||||
peer: normalizeToInputPeer(await this.resolvePeer(chat)),
|
||||
peer,
|
||||
maxId
|
||||
})
|
||||
|
||||
const channel = normalizeToInputChannel(peer)
|
||||
if (channel) {
|
||||
this._handleUpdate(createDummyUpdate(res.pts, res.ptsCount, (channel as tl.RawInputChannel).channelId))
|
||||
} else {
|
||||
this._handleUpdate(createDummyUpdate(res.pts, res.ptsCount))
|
||||
}
|
||||
}
|
||||
|
|
41
packages/client/src/methods/chats/delete-user-history.ts
Normal file
41
packages/client/src/methods/chats/delete-user-history.ts
Normal file
|
@ -0,0 +1,41 @@
|
|||
import { TelegramClient } from '../../client'
|
||||
import { InputPeerLike, MtCuteInvalidPeerTypeError } from '../../types'
|
||||
import {
|
||||
normalizeToInputChannel,
|
||||
normalizeToInputUser,
|
||||
} from '../../utils/peer-utils'
|
||||
import { tl } from '@mtcute/tl'
|
||||
import { createDummyUpdate } from '../../utils/updates-utils'
|
||||
|
||||
/**
|
||||
* Delete all messages of a user in a supergroup
|
||||
*
|
||||
* @param chatId Chat ID
|
||||
* @param userId User ID
|
||||
* @internal
|
||||
*/
|
||||
export async function deleteUserHistory(
|
||||
this: TelegramClient,
|
||||
chatId: InputPeerLike,
|
||||
userId: InputPeerLike
|
||||
): Promise<void> {
|
||||
const channel = normalizeToInputChannel(await this.resolvePeer(chatId))
|
||||
if (!channel) throw new MtCuteInvalidPeerTypeError(chatId, 'channel')
|
||||
|
||||
const user = normalizeToInputUser(await this.resolvePeer(userId))
|
||||
if (!user) throw new MtCuteInvalidPeerTypeError(userId, 'user')
|
||||
|
||||
const res = await this.call({
|
||||
_: 'channels.deleteUserHistory',
|
||||
channel,
|
||||
userId: user,
|
||||
})
|
||||
|
||||
this._handleUpdate(
|
||||
createDummyUpdate(
|
||||
res.pts,
|
||||
res.ptsCount,
|
||||
(channel as tl.RawInputChannel).channelId
|
||||
)
|
||||
)
|
||||
}
|
|
@ -2,6 +2,8 @@ import { TelegramClient } from '../../client'
|
|||
import { InputPeerLike } from '../../types'
|
||||
import { MaybeArray } from '@mtcute/core'
|
||||
import { normalizeToInputChannel, normalizeToInputPeer } from '../../utils/peer-utils'
|
||||
import { createDummyUpdate } from '../../utils/updates-utils'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
/**
|
||||
* Delete messages, including service messages.
|
||||
|
@ -16,28 +18,29 @@ export async function deleteMessages(
|
|||
chatId: InputPeerLike,
|
||||
ids: MaybeArray<number>,
|
||||
revoke = true
|
||||
): Promise<boolean> {
|
||||
): Promise<void> {
|
||||
if (!Array.isArray(ids)) ids = [ids]
|
||||
|
||||
const peer = await this.resolvePeer(chatId)
|
||||
const inputPeer = normalizeToInputPeer(peer)
|
||||
|
||||
let res
|
||||
let upd
|
||||
if (inputPeer._ === 'inputPeerChannel') {
|
||||
res = await this.call({
|
||||
const channel = normalizeToInputChannel(peer)!
|
||||
const res = await this.call({
|
||||
_: 'channels.deleteMessages',
|
||||
channel: normalizeToInputChannel(peer)!,
|
||||
channel,
|
||||
id: ids
|
||||
})
|
||||
upd = createDummyUpdate(res.pts, res.ptsCount, (channel as tl.RawInputChannel).channelId)
|
||||
} else {
|
||||
res = await this.call({
|
||||
const res = await this.call({
|
||||
_: 'messages.deleteMessages',
|
||||
id: ids,
|
||||
revoke
|
||||
})
|
||||
upd = createDummyUpdate(res.pts, res.ptsCount)
|
||||
}
|
||||
|
||||
this._pts = res.pts
|
||||
|
||||
return !!res.ptsCount
|
||||
this._handleUpdate(upd)
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import { extractChannelIdFromUpdate } from '../utils/misc-utils'
|
|||
import { Lock } from '../utils/lock'
|
||||
import bigInt from 'big-integer'
|
||||
import { MAX_CHANNEL_ID } from '@mtcute/core'
|
||||
import { isDummyUpdate, isDummyUpdates } from '../utils/updates-utils'
|
||||
|
||||
const debug = require('debug')('mtcute:upds')
|
||||
|
||||
|
@ -488,7 +489,7 @@ export function _handleUpdate(
|
|||
}
|
||||
}
|
||||
|
||||
if (!noDispatch) {
|
||||
if (!isDummyUpdate(upd) && !noDispatch) {
|
||||
this.dispatchUpdate(upd, users, chats)
|
||||
}
|
||||
|
||||
|
@ -502,8 +503,10 @@ export function _handleUpdate(
|
|||
}
|
||||
}
|
||||
|
||||
if (!isDummyUpdates(update)) {
|
||||
// this._seq = update.seq
|
||||
this._date = update.date
|
||||
}
|
||||
} else if (update._ === 'updateShort') {
|
||||
const upd = update.update
|
||||
if (upd._ === 'updateDcOptions' && this._config) {
|
||||
|
|
|
@ -25,7 +25,7 @@ export function extractChannelIdFromUpdate(
|
|||
upd: tl.TypeUpdate
|
||||
): number | undefined {
|
||||
// holy shit
|
||||
return 'channelId' in upd
|
||||
const res = 'channelId' in upd
|
||||
? upd.channelId
|
||||
: 'message' in upd &&
|
||||
typeof upd.message !== 'string' &&
|
||||
|
@ -34,6 +34,8 @@ export function extractChannelIdFromUpdate(
|
|||
'channelId' in upd.message.peerId
|
||||
? upd.message.peerId.channelId
|
||||
: undefined
|
||||
if (res === 0) return undefined
|
||||
return res
|
||||
}
|
||||
|
||||
export function normalizeDate(
|
||||
|
|
36
packages/client/src/utils/updates-utils.ts
Normal file
36
packages/client/src/utils/updates-utils.ts
Normal file
|
@ -0,0 +1,36 @@
|
|||
import { tl } from '@mtcute/tl'
|
||||
|
||||
// dummy updates which are used for methods that return messages.affectedHistory.
|
||||
// that is not an update, but it carries info about pts, and we need to handle it
|
||||
|
||||
/** @internal */
|
||||
export function createDummyUpdate(pts: number, ptsCount: number, channelId = 0): tl.TypeUpdates {
|
||||
return {
|
||||
_: 'updates',
|
||||
seq: 0,
|
||||
date: 0,
|
||||
chats: [],
|
||||
users: [],
|
||||
updates: [
|
||||
{
|
||||
_: 'updatePinnedChannelMessages',
|
||||
channelId,
|
||||
pts,
|
||||
ptsCount,
|
||||
// since message id cant be negative, using negative 42
|
||||
// here makes it distinctive from real updates
|
||||
messages: [-42]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function isDummyUpdate(upd: tl.TypeUpdate): boolean {
|
||||
return upd._ === 'updatePinnedChannelMessages' && upd.messages.length === 1 && upd.messages[0] === -42
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function isDummyUpdates(upd: tl.TypeUpdates): boolean {
|
||||
return upd._ === 'updates' && upd.updates.length === 1 && isDummyUpdate(upd.updates[0])
|
||||
}
|
Loading…
Reference in a new issue