mirror of
https://github.com/LonamiWebs/Telethon.git
synced 2025-02-21 14:05:17 +03:00
Handle all entity types on isinstance checks
Only the uses of `isinstance` against `InputPeer*` types were reviewed. Notably, `utils` is exempt on this because it needs to deal with everything on a case-by-case basis. Since the addition of `*FromMessage` peers, any manual `isinstance` checks to determine the type were prone to breaking or being forgotten to be updated, so a common `helpers._entity_type()` method was made to share this logic. Since the conversion to `Peer` would be too expensive, a simpler check against the name is made, which should be fast and cheap.
This commit is contained in:
parent
627e176f8e
commit
fa736f81af
|
@ -108,8 +108,8 @@ class _ParticipantsIter(RequestIter):
|
||||||
filter = filter()
|
filter = filter()
|
||||||
|
|
||||||
entity = await self.client.get_input_entity(entity)
|
entity = await self.client.get_input_entity(entity)
|
||||||
if search and (filter
|
ty = helpers._entity_type(entity)
|
||||||
or not isinstance(entity, types.InputPeerChannel)):
|
if search and (filter or ty != helpers._EntityType.CHANNEL):
|
||||||
# We need to 'search' ourselves unless we have a PeerChannel
|
# We need to 'search' ourselves unless we have a PeerChannel
|
||||||
search = search.casefold()
|
search = search.casefold()
|
||||||
|
|
||||||
|
@ -123,7 +123,7 @@ class _ParticipantsIter(RequestIter):
|
||||||
# Only used for channels, but we should always set the attribute
|
# Only used for channels, but we should always set the attribute
|
||||||
self.requests = []
|
self.requests = []
|
||||||
|
|
||||||
if isinstance(entity, types.InputPeerChannel):
|
if ty == helpers._EntityType.CHANNEL:
|
||||||
self.total = (await self.client(
|
self.total = (await self.client(
|
||||||
functions.channels.GetFullChannelRequest(entity)
|
functions.channels.GetFullChannelRequest(entity)
|
||||||
)).full_chat.participants_count
|
)).full_chat.participants_count
|
||||||
|
@ -149,7 +149,7 @@ class _ParticipantsIter(RequestIter):
|
||||||
hash=0
|
hash=0
|
||||||
))
|
))
|
||||||
|
|
||||||
elif isinstance(entity, types.InputPeerChat):
|
elif ty == helpers._EntityType.CHAT:
|
||||||
full = await self.client(
|
full = await self.client(
|
||||||
functions.messages.GetFullChatRequest(entity.chat_id))
|
functions.messages.GetFullChatRequest(entity.chat_id))
|
||||||
if not isinstance(
|
if not isinstance(
|
||||||
|
@ -281,7 +281,8 @@ class _ProfilePhotoIter(RequestIter):
|
||||||
self, entity, offset, max_id
|
self, entity, offset, max_id
|
||||||
):
|
):
|
||||||
entity = await self.client.get_input_entity(entity)
|
entity = await self.client.get_input_entity(entity)
|
||||||
if isinstance(entity, (types.InputPeerUser, types.InputPeerSelf)):
|
ty = helpers._entity_type(entity)
|
||||||
|
if ty == helpers._EntityType.USER:
|
||||||
self.request = functions.photos.GetUserPhotosRequest(
|
self.request = functions.photos.GetUserPhotosRequest(
|
||||||
entity,
|
entity,
|
||||||
offset=offset,
|
offset=offset,
|
||||||
|
@ -864,7 +865,8 @@ class ChatMethods:
|
||||||
"""
|
"""
|
||||||
entity = await self.get_input_entity(entity)
|
entity = await self.get_input_entity(entity)
|
||||||
user = await self.get_input_entity(user)
|
user = await self.get_input_entity(user)
|
||||||
if not isinstance(user, (types.InputPeerUser, types.InputPeerSelf)):
|
ty = helpers._entity_type(user)
|
||||||
|
if ty != helpers._EntityType.USER:
|
||||||
raise ValueError('You must pass a user entity')
|
raise ValueError('You must pass a user entity')
|
||||||
|
|
||||||
perm_names = (
|
perm_names = (
|
||||||
|
@ -872,7 +874,8 @@ class ChatMethods:
|
||||||
'ban_users', 'invite_users', 'pin_messages', 'add_admins'
|
'ban_users', 'invite_users', 'pin_messages', 'add_admins'
|
||||||
)
|
)
|
||||||
|
|
||||||
if isinstance(entity, types.InputPeerChannel):
|
ty = helpers._entity_type(entity)
|
||||||
|
if ty == helpers._EntityType.CHANNEL:
|
||||||
# If we try to set these permissions in a megagroup, we
|
# If we try to set these permissions in a megagroup, we
|
||||||
# would get a RIGHT_FORBIDDEN. However, it makes sense
|
# would get a RIGHT_FORBIDDEN. However, it makes sense
|
||||||
# that an admin can post messages, so we want to avoid the error
|
# that an admin can post messages, so we want to avoid the error
|
||||||
|
@ -894,7 +897,7 @@ class ChatMethods:
|
||||||
for name in perm_names
|
for name in perm_names
|
||||||
}), rank=title or ''))
|
}), rank=title or ''))
|
||||||
|
|
||||||
elif isinstance(entity, types.InputPeerChat):
|
elif ty == helpers._EntityType.CHAT:
|
||||||
# If the user passed any permission in a small
|
# If the user passed any permission in a small
|
||||||
# group chat, they must be a full admin to have it.
|
# group chat, they must be a full admin to have it.
|
||||||
if is_admin is None:
|
if is_admin is None:
|
||||||
|
@ -1015,7 +1018,8 @@ class ChatMethods:
|
||||||
await client.edit_permissions(chat, user)
|
await client.edit_permissions(chat, user)
|
||||||
"""
|
"""
|
||||||
entity = await self.get_input_entity(entity)
|
entity = await self.get_input_entity(entity)
|
||||||
if not isinstance(entity, types.InputPeerChannel):
|
ty = helpers._entity_type(entity)
|
||||||
|
if ty != helpers._EntityType.CHANNEL:
|
||||||
raise ValueError('You must pass either a channel or a supergroup')
|
raise ValueError('You must pass either a channel or a supergroup')
|
||||||
|
|
||||||
rights = types.ChatBannedRights(
|
rights = types.ChatBannedRights(
|
||||||
|
@ -1040,12 +1044,13 @@ class ChatMethods:
|
||||||
))
|
))
|
||||||
|
|
||||||
user = await self.get_input_entity(user)
|
user = await self.get_input_entity(user)
|
||||||
|
ty = helpers._entity_type(user)
|
||||||
|
if ty != helpers._EntityType.USER:
|
||||||
|
raise ValueError('You must pass a user entity')
|
||||||
|
|
||||||
if isinstance(user, types.InputPeerSelf):
|
if isinstance(user, types.InputPeerSelf):
|
||||||
raise ValueError('You cannot restrict yourself')
|
raise ValueError('You cannot restrict yourself')
|
||||||
|
|
||||||
if not isinstance(user, types.InputPeerUser):
|
|
||||||
raise ValueError('You must pass a user entity')
|
|
||||||
|
|
||||||
return await self(functions.channels.EditBannedRequest(
|
return await self(functions.channels.EditBannedRequest(
|
||||||
channel=entity,
|
channel=entity,
|
||||||
user_id=user,
|
user_id=user,
|
||||||
|
@ -1086,12 +1091,13 @@ class ChatMethods:
|
||||||
"""
|
"""
|
||||||
entity = await self.get_input_entity(entity)
|
entity = await self.get_input_entity(entity)
|
||||||
user = await self.get_input_entity(user)
|
user = await self.get_input_entity(user)
|
||||||
if not isinstance(user, (types.InputPeerUser, types.InputPeerSelf)):
|
if helpers._entity_type(user) != helpers._EntityType.USER:
|
||||||
raise ValueError('You must pass a user entity')
|
raise ValueError('You must pass a user entity')
|
||||||
|
|
||||||
if isinstance(entity, types.InputPeerChat):
|
ty = helpers._entity_type(entity)
|
||||||
|
if ty == helpers._EntityType.CHAT:
|
||||||
await self(functions.messages.DeleteChatUserRequest(entity.chat_id, user))
|
await self(functions.messages.DeleteChatUserRequest(entity.chat_id, user))
|
||||||
elif isinstance(entity, types.InputPeerChannel):
|
elif ty == helpers._EntityType.CHANNEL:
|
||||||
if isinstance(user, types.InputPeerSelf):
|
if isinstance(user, types.InputPeerSelf):
|
||||||
await self(functions.channels.LeaveChannelRequest(entity))
|
await self(functions.channels.LeaveChannelRequest(entity))
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -3,7 +3,7 @@ import inspect
|
||||||
import itertools
|
import itertools
|
||||||
import typing
|
import typing
|
||||||
|
|
||||||
from .. import utils, hints
|
from .. import helpers, utils, hints
|
||||||
from ..requestiter import RequestIter
|
from ..requestiter import RequestIter
|
||||||
from ..tl import types, functions, custom
|
from ..tl import types, functions, custom
|
||||||
|
|
||||||
|
@ -436,10 +436,11 @@ class DialogMethods:
|
||||||
await client.delete_dialog('username')
|
await client.delete_dialog('username')
|
||||||
"""
|
"""
|
||||||
entity = await self.get_input_entity(entity)
|
entity = await self.get_input_entity(entity)
|
||||||
if isinstance(entity, types.InputPeerChannel):
|
ty = helpers._entity_type(entity)
|
||||||
|
if ty == helpers._EntityType.CHANNEL:
|
||||||
return await self(functions.channels.LeaveChannelRequest(entity))
|
return await self(functions.channels.LeaveChannelRequest(entity))
|
||||||
|
|
||||||
if isinstance(entity, types.InputPeerChat):
|
if ty == helpers._EntityType.CHAT:
|
||||||
result = await self(functions.messages.DeleteChatUserRequest(
|
result = await self(functions.messages.DeleteChatUserRequest(
|
||||||
entity.chat_id, types.InputUserSelf()))
|
entity.chat_id, types.InputUserSelf()))
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -257,7 +257,8 @@ class DownloadMethods:
|
||||||
# See issue #500, Android app fails as of v4.6.0 (1155).
|
# See issue #500, Android app fails as of v4.6.0 (1155).
|
||||||
# The fix seems to be using the full channel chat photo.
|
# The fix seems to be using the full channel chat photo.
|
||||||
ie = await self.get_input_entity(entity)
|
ie = await self.get_input_entity(entity)
|
||||||
if isinstance(ie, types.InputPeerChannel):
|
ty = helpers._entity_type(ie)
|
||||||
|
if ty == helpers._EntityType.CHANNEL:
|
||||||
full = await self(functions.channels.GetFullChannelRequest(ie))
|
full = await self(functions.channels.GetFullChannelRequest(ie))
|
||||||
return await self._download_photo(
|
return await self._download_photo(
|
||||||
full.full_chat.chat_photo, file,
|
full.full_chat.chat_photo, file,
|
||||||
|
|
|
@ -2,7 +2,7 @@ import itertools
|
||||||
import re
|
import re
|
||||||
import typing
|
import typing
|
||||||
|
|
||||||
from .. import utils
|
from .. import helpers, utils
|
||||||
from ..tl import types
|
from ..tl import types
|
||||||
|
|
||||||
if typing.TYPE_CHECKING:
|
if typing.TYPE_CHECKING:
|
||||||
|
@ -134,7 +134,7 @@ class MessageParseMethods:
|
||||||
id_to_message[update.message.id] = update.message
|
id_to_message[update.message.id] = update.message
|
||||||
|
|
||||||
elif (isinstance(update, types.UpdateEditMessage)
|
elif (isinstance(update, types.UpdateEditMessage)
|
||||||
and not isinstance(request.peer, types.InputPeerChannel)):
|
and helpers._entity_type(request.peer) != helpers._EntityType.CHANNEL):
|
||||||
if request.id == update.message.id:
|
if request.id == update.message.id:
|
||||||
update.message._finish_init(self, entities, input_chat)
|
update.message._finish_init(self, entities, input_chat)
|
||||||
return update.message
|
return update.message
|
||||||
|
|
|
@ -2,7 +2,7 @@ import inspect
|
||||||
import itertools
|
import itertools
|
||||||
import typing
|
import typing
|
||||||
|
|
||||||
from .. import utils, errors, hints
|
from .. import helpers, utils, errors, hints
|
||||||
from ..requestiter import RequestIter
|
from ..requestiter import RequestIter
|
||||||
from ..tl import types, functions
|
from ..tl import types, functions
|
||||||
|
|
||||||
|
@ -57,8 +57,8 @@ class _MessagesIter(RequestIter):
|
||||||
|
|
||||||
if from_user:
|
if from_user:
|
||||||
from_user = await self.client.get_input_entity(from_user)
|
from_user = await self.client.get_input_entity(from_user)
|
||||||
if not isinstance(from_user, (
|
ty = helpers._entity_type(from_user)
|
||||||
types.InputPeerUser, types.InputPeerSelf)):
|
if ty != helpers._EntityType.USER:
|
||||||
from_user = None # Ignore from_user unless it's a user
|
from_user = None # Ignore from_user unless it's a user
|
||||||
|
|
||||||
if from_user:
|
if from_user:
|
||||||
|
@ -86,8 +86,8 @@ class _MessagesIter(RequestIter):
|
||||||
filter = types.InputMessagesFilterEmpty()
|
filter = types.InputMessagesFilterEmpty()
|
||||||
|
|
||||||
# Telegram completely ignores `from_id` in private chats
|
# Telegram completely ignores `from_id` in private chats
|
||||||
if isinstance(
|
ty = helpers._entity_type(self.entity)
|
||||||
self.entity, (types.InputPeerUser, types.InputPeerSelf)):
|
if ty == helpers._EntityType.USER:
|
||||||
# Don't bother sending `from_user` (it's ignored anyway),
|
# Don't bother sending `from_user` (it's ignored anyway),
|
||||||
# but keep `from_id` defined above to check it locally.
|
# but keep `from_id` defined above to check it locally.
|
||||||
from_user = None
|
from_user = None
|
||||||
|
@ -246,6 +246,7 @@ class _IDsIter(RequestIter):
|
||||||
self._ids = list(reversed(ids)) if self.reverse else ids
|
self._ids = list(reversed(ids)) if self.reverse else ids
|
||||||
self._offset = 0
|
self._offset = 0
|
||||||
self._entity = (await self.client.get_input_entity(entity)) if entity else None
|
self._entity = (await self.client.get_input_entity(entity)) if entity else None
|
||||||
|
self._ty = helpers._EntityType(self._entity) if self._entity else None
|
||||||
|
|
||||||
# 30s flood wait every 300 messages (3 requests of 100 each, 30 of 10, etc.)
|
# 30s flood wait every 300 messages (3 requests of 100 each, 30 of 10, etc.)
|
||||||
if self.wait_time is None:
|
if self.wait_time is None:
|
||||||
|
@ -259,7 +260,7 @@ class _IDsIter(RequestIter):
|
||||||
self._offset += _MAX_CHUNK_SIZE
|
self._offset += _MAX_CHUNK_SIZE
|
||||||
|
|
||||||
from_id = None # By default, no need to validate from_id
|
from_id = None # By default, no need to validate from_id
|
||||||
if isinstance(self._entity, (types.InputChannel, types.InputPeerChannel)):
|
if self._ty == helpers._EntityType.CHANNEL:
|
||||||
try:
|
try:
|
||||||
r = await self.client(
|
r = await self.client(
|
||||||
functions.channels.GetMessagesRequest(self._entity, ids))
|
functions.channels.GetMessagesRequest(self._entity, ids))
|
||||||
|
@ -1108,7 +1109,7 @@ class MessageMethods:
|
||||||
)
|
)
|
||||||
|
|
||||||
entity = await self.get_input_entity(entity) if entity else None
|
entity = await self.get_input_entity(entity) if entity else None
|
||||||
if isinstance(entity, types.InputPeerChannel):
|
if helpers._entity_type(entity) == helpers._EntityType.CHANNEL:
|
||||||
return await self([functions.channels.DeleteMessagesRequest(
|
return await self([functions.channels.DeleteMessagesRequest(
|
||||||
entity, list(c)) for c in utils.chunks(message_ids)])
|
entity, list(c)) for c in utils.chunks(message_ids)])
|
||||||
else:
|
else:
|
||||||
|
@ -1181,7 +1182,7 @@ class MessageMethods:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if max_id is not None:
|
if max_id is not None:
|
||||||
if isinstance(entity, types.InputPeerChannel):
|
if helpers._entity_type(entity) == helpers._EntityType.CHANNEL:
|
||||||
return await self(functions.channels.ReadHistoryRequest(
|
return await self(functions.channels.ReadHistoryRequest(
|
||||||
utils.get_input_channel(entity), max_id=max_id))
|
utils.get_input_channel(entity), max_id=max_id))
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -4,7 +4,7 @@ import itertools
|
||||||
import time
|
import time
|
||||||
import typing
|
import typing
|
||||||
|
|
||||||
from .. import errors, utils, hints
|
from .. import errors, helpers, utils, hints
|
||||||
from ..errors import MultiError, RPCError
|
from ..errors import MultiError, RPCError
|
||||||
from ..helpers import retry_range
|
from ..helpers import retry_range
|
||||||
from ..tl import TLRequest, types, functions
|
from ..tl import TLRequest, types, functions
|
||||||
|
@ -258,12 +258,20 @@ class UserMethods:
|
||||||
else:
|
else:
|
||||||
inputs.append(await self.get_input_entity(x))
|
inputs.append(await self.get_input_entity(x))
|
||||||
|
|
||||||
users = [x for x in inputs
|
lists = {
|
||||||
if isinstance(x, (types.InputPeerUser, types.InputPeerSelf))]
|
helpers._EntityType.USER: [],
|
||||||
chats = [x.chat_id for x in inputs
|
helpers._EntityType.CHAT: [],
|
||||||
if isinstance(x, types.InputPeerChat)]
|
helpers._EntityType.CHANNEL: [],
|
||||||
channels = [x for x in inputs
|
}
|
||||||
if isinstance(x, types.InputPeerChannel)]
|
for x in inputs:
|
||||||
|
try:
|
||||||
|
lists[helpers._entity_type(x)].append(x)
|
||||||
|
except TypeError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
users = lists[helpers._EntityType.USER]
|
||||||
|
chats = lists[helpers._EntityType.CHAT]
|
||||||
|
channels = lists[helpers._EntityType.CHANNEL]
|
||||||
if users:
|
if users:
|
||||||
# GetUsersRequest has a limit of 200 per call
|
# GetUsersRequest has a limit of 200 per call
|
||||||
tmp = []
|
tmp = []
|
||||||
|
|
|
@ -1,10 +1,17 @@
|
||||||
"""Various helpers not related to the Telegram API itself"""
|
"""Various helpers not related to the Telegram API itself"""
|
||||||
import asyncio
|
import asyncio
|
||||||
|
import enum
|
||||||
import os
|
import os
|
||||||
import struct
|
import struct
|
||||||
from hashlib import sha1
|
from hashlib import sha1
|
||||||
|
|
||||||
|
|
||||||
|
class _EntityType(enum.Enum):
|
||||||
|
USER = 0
|
||||||
|
CHAT = 1
|
||||||
|
CHANNEL = 2
|
||||||
|
|
||||||
|
|
||||||
# region Multiple utilities
|
# region Multiple utilities
|
||||||
|
|
||||||
|
|
||||||
|
@ -131,6 +138,41 @@ def _sync_exit(self, *args):
|
||||||
return loop.run_until_complete(self.__aexit__(*args))
|
return loop.run_until_complete(self.__aexit__(*args))
|
||||||
|
|
||||||
|
|
||||||
|
def _entity_type(entity):
|
||||||
|
# This could be a `utils` method that just ran a few `isinstance` on
|
||||||
|
# `utils.get_peer(...)`'s result. However, there are *a lot* of auto
|
||||||
|
# casts going on, plenty of calls and temporary short-lived objects.
|
||||||
|
#
|
||||||
|
# So we just check if a string is in the class name.
|
||||||
|
# Still, assert that it's the right type to not return false results.
|
||||||
|
try:
|
||||||
|
if entity.SUBCLASS_OF_ID not in (
|
||||||
|
0x2d45687, # crc32(b'Peer')
|
||||||
|
0xc91c90b6, # crc32(b'InputPeer')
|
||||||
|
0xe669bf46, # crc32(b'InputUser')
|
||||||
|
0x40f202fd, # crc32(b'InputChannel')
|
||||||
|
0x2da17977, # crc32(b'User')
|
||||||
|
0xc5af5d94, # crc32(b'Chat')
|
||||||
|
0x1f4661b9, # crc32(b'UserFull')
|
||||||
|
0xd49a2697, # crc32(b'ChatFull')
|
||||||
|
):
|
||||||
|
raise TypeError('{} does not have any entity type'.format(entity))
|
||||||
|
except AttributeError:
|
||||||
|
raise TypeError('{} is not a TLObject, cannot determine entity type'.format(entity))
|
||||||
|
|
||||||
|
name = entity.__class__.__name__
|
||||||
|
if 'User' in name:
|
||||||
|
return _EntityType.USER
|
||||||
|
elif 'Chat' in name:
|
||||||
|
return _EntityType.CHAT
|
||||||
|
elif 'Channel' in name:
|
||||||
|
return _EntityType.CHANNEL
|
||||||
|
elif 'Self' in name:
|
||||||
|
return _EntityType.USER
|
||||||
|
|
||||||
|
# 'Empty' in name or not found, we don't care, not a valid entity.
|
||||||
|
raise TypeError('{} does not have any entity type'.format(entity))
|
||||||
|
|
||||||
# endregion
|
# endregion
|
||||||
|
|
||||||
# region Cryptographic related utils
|
# region Cryptographic related utils
|
||||||
|
|
|
@ -149,6 +149,7 @@ MESSAGE_IDS_EMPTY,400,No message ids were provided
|
||||||
MESSAGE_ID_INVALID,400,"The specified message ID is invalid or you can't do that operation on such message"
|
MESSAGE_ID_INVALID,400,"The specified message ID is invalid or you can't do that operation on such message"
|
||||||
MESSAGE_NOT_MODIFIED,400,Content of the message was not modified
|
MESSAGE_NOT_MODIFIED,400,Content of the message was not modified
|
||||||
MESSAGE_TOO_LONG,400,Message was too long. Current maximum length is 4096 UTF-8 characters
|
MESSAGE_TOO_LONG,400,Message was too long. Current maximum length is 4096 UTF-8 characters
|
||||||
|
MSG_ID_INVALID,400,The message ID used in the peer was invalid
|
||||||
MSG_WAIT_FAILED,400,A waiting call returned an error
|
MSG_WAIT_FAILED,400,A waiting call returned an error
|
||||||
MT_SEND_QUEUE_TOO_LONG,500,
|
MT_SEND_QUEUE_TOO_LONG,500,
|
||||||
NEED_CHAT_INVALID,500,The provided chat is invalid
|
NEED_CHAT_INVALID,500,The provided chat is invalid
|
||||||
|
|
|
|
@ -238,7 +238,7 @@ messages.sendEncryptedFile,user,MSG_WAIT_FAILED
|
||||||
messages.sendEncryptedService,user,DATA_INVALID ENCRYPTION_DECLINED MSG_WAIT_FAILED USER_IS_BLOCKED
|
messages.sendEncryptedService,user,DATA_INVALID ENCRYPTION_DECLINED MSG_WAIT_FAILED USER_IS_BLOCKED
|
||||||
messages.sendInlineBotResult,user,CHAT_SEND_INLINE_FORBIDDEN CHAT_WRITE_FORBIDDEN INLINE_RESULT_EXPIRED PEER_ID_INVALID QUERY_ID_EMPTY SCHEDULE_DATE_TOO_LATE SCHEDULE_TOO_MUCH WEBPAGE_CURL_FAILED WEBPAGE_MEDIA_EMPTY
|
messages.sendInlineBotResult,user,CHAT_SEND_INLINE_FORBIDDEN CHAT_WRITE_FORBIDDEN INLINE_RESULT_EXPIRED PEER_ID_INVALID QUERY_ID_EMPTY SCHEDULE_DATE_TOO_LATE SCHEDULE_TOO_MUCH WEBPAGE_CURL_FAILED WEBPAGE_MEDIA_EMPTY
|
||||||
messages.sendMedia,both,BOT_PAYMENTS_DISABLED BOT_POLLS_DISABLED CHANNEL_INVALID CHANNEL_PRIVATE CHAT_ADMIN_REQUIRED CHAT_SEND_MEDIA_FORBIDDEN CHAT_WRITE_FORBIDDEN EXTERNAL_URL_INVALID FILE_PARTS_INVALID FILE_PART_LENGTH_INVALID INPUT_USER_DEACTIVATED MEDIA_CAPTION_TOO_LONG MEDIA_EMPTY PAYMENT_PROVIDER_INVALID PEER_ID_INVALID PHOTO_EXT_INVALID PHOTO_INVALID_DIMENSIONS PHOTO_SAVE_FILE_INVALID POLL_OPTION_DUPLICATE RANDOM_ID_DUPLICATE SCHEDULE_DATE_TOO_LATE SCHEDULE_TOO_MUCH STORAGE_CHECK_FAILED Timeout USER_BANNED_IN_CHANNEL USER_IS_BLOCKED USER_IS_BOT VIDEO_CONTENT_TYPE_INVALID WEBPAGE_CURL_FAILED WEBPAGE_MEDIA_EMPTY
|
messages.sendMedia,both,BOT_PAYMENTS_DISABLED BOT_POLLS_DISABLED CHANNEL_INVALID CHANNEL_PRIVATE CHAT_ADMIN_REQUIRED CHAT_SEND_MEDIA_FORBIDDEN CHAT_WRITE_FORBIDDEN EXTERNAL_URL_INVALID FILE_PARTS_INVALID FILE_PART_LENGTH_INVALID INPUT_USER_DEACTIVATED MEDIA_CAPTION_TOO_LONG MEDIA_EMPTY PAYMENT_PROVIDER_INVALID PEER_ID_INVALID PHOTO_EXT_INVALID PHOTO_INVALID_DIMENSIONS PHOTO_SAVE_FILE_INVALID POLL_OPTION_DUPLICATE RANDOM_ID_DUPLICATE SCHEDULE_DATE_TOO_LATE SCHEDULE_TOO_MUCH STORAGE_CHECK_FAILED Timeout USER_BANNED_IN_CHANNEL USER_IS_BLOCKED USER_IS_BOT VIDEO_CONTENT_TYPE_INVALID WEBPAGE_CURL_FAILED WEBPAGE_MEDIA_EMPTY
|
||||||
messages.sendMessage,both,AUTH_KEY_DUPLICATED BUTTON_DATA_INVALID BUTTON_TYPE_INVALID BUTTON_URL_INVALID CHANNEL_INVALID CHANNEL_PRIVATE CHAT_ADMIN_REQUIRED CHAT_ID_INVALID CHAT_RESTRICTED CHAT_WRITE_FORBIDDEN ENTITIES_TOO_LONG ENTITY_MENTION_USER_INVALID INPUT_USER_DEACTIVATED MESSAGE_EMPTY MESSAGE_TOO_LONG PEER_ID_INVALID RANDOM_ID_DUPLICATE REPLY_MARKUP_INVALID REPLY_MARKUP_TOO_LONG SCHEDULE_BOT_NOT_ALLOWED SCHEDULE_DATE_TOO_LATE SCHEDULE_TOO_MUCH Timeout USER_BANNED_IN_CHANNEL USER_IS_BLOCKED USER_IS_BOT YOU_BLOCKED_USER
|
messages.sendMessage,both,AUTH_KEY_DUPLICATED BUTTON_DATA_INVALID BUTTON_TYPE_INVALID BUTTON_URL_INVALID CHANNEL_INVALID CHANNEL_PRIVATE CHAT_ADMIN_REQUIRED CHAT_ID_INVALID CHAT_RESTRICTED CHAT_WRITE_FORBIDDEN ENTITIES_TOO_LONG ENTITY_MENTION_USER_INVALID INPUT_USER_DEACTIVATED MESSAGE_EMPTY MESSAGE_TOO_LONG MSG_ID_INVALID PEER_ID_INVALID RANDOM_ID_DUPLICATE REPLY_MARKUP_INVALID REPLY_MARKUP_TOO_LONG SCHEDULE_BOT_NOT_ALLOWED SCHEDULE_DATE_TOO_LATE SCHEDULE_TOO_MUCH Timeout USER_BANNED_IN_CHANNEL USER_IS_BLOCKED USER_IS_BOT YOU_BLOCKED_USER
|
||||||
messages.sendMultiMedia,both,SCHEDULE_DATE_TOO_LATE SCHEDULE_TOO_MUCH
|
messages.sendMultiMedia,both,SCHEDULE_DATE_TOO_LATE SCHEDULE_TOO_MUCH
|
||||||
messages.sendReaction,User,REACTION_INVALID
|
messages.sendReaction,User,REACTION_INVALID
|
||||||
messages.sendVote,user,
|
messages.sendVote,user,
|
||||||
|
|
|
Loading…
Reference in New Issue
Block a user