コード例 #1
0
    def __init__(self, bot):
        self.bot = bot
        self.no_threads = True
        self.phone = None
        self.bot_token = None

        if self.bot.config['bindings_token'].startswith('+'):
            self.phone = self.bot.config['bindings_token']
        else:
            self.bot_token = self.bot.config['bindings_token']

        self.client = Telegram(
            api_id=self.bot.config['api_keys']['telegram_app_id'],
            api_hash=self.bot.config['api_keys']['telegram_api_hash'],
            phone=self.phone,
            bot_token=self.bot_token,
            database_encryption_key=self.bot.config['api_keys']
            ['database_encryption_key'],
            library_path='/usr/local/lib/libtdjson.so',
            files_directory='{}/.tdlib_files/{}/'.format(
                os.getcwd(), self.bot.name),
            device_model='polaris',
            application_version='1.0',
            tdlib_verbosity=1,
        )
        self.client.login()
コード例 #2
0
async def main():
    session_files = [
        session_file_name
        for session_file_name in os.listdir(TELETHON_SESSIONS_FOLDER_NAME)
        if os.path.splitext(session_file_name)[1] == ".session"
    ]
    context = Context(amount_of_accounts_to_process=len(session_files))
    for session_file_name in session_files:
        client = telethon.TelegramClient(
            os.path.join(TELETHON_SESSIONS_FOLDER_NAME, session_file_name),
            api_id=CONFIG["api_id"], api_hash=CONFIG["api_hash"]
        )
        await client.connect()
        try:
            phone = (await client.get_me()).phone
        except AttributeError:  # 'NoneType' object has no attribute 'phone'
            print(f"`{session_file_name}` isn't logged in! Skipping it.")
            continue
        tdlib_session = Telegram(
            api_hash=CONFIG["api_hash"],
            api_id=CONFIG["api_id"],
            database_encryption_key=CONFIG["tdlib_database_encryption_key"],
            files_directory=os.path.join(TDLIB_SESSIONS_FOLDER_NAME, phone),
            phone=phone, tdlib_verbosity=0
        )
        tdlib_session.login(blocking=False)
        client.add_event_handler(
            functools.partial(
                check_incoming_tg_message, context, client, tdlib_session
            ), event=NewMessage()
        )
        # noinspection PyTypeChecker,PyUnresolvedReferences
        await client.start()
コード例 #3
0
def init_telegram():
    t = Telegram(api_id=app_config.app_id,
                 api_hash=app_config.api_hash,
                 phone=app_config.phone,
                 database_encryption_key=app_config.database_encryption_key,
                 tdlib_verbosity=app_config.tdlib_verbosity)

    t.login()
    chats = t.get_chats()
    chats.wait()

    return t
コード例 #4
0
def delete_api_messages(chat_id: int, api_messages_list, telegram: Telegram):

    if len(api_messages_list) is 0:
        return

    telegram.call_method(
        'deleteMessages', {
            'chat_id':
            chat_id,
            'message_ids':
            list(set([api_message['id'] for api_message in api_messages_list]))
        })
コード例 #5
0
def login():
    tg = Telegram(
        api_id=api_id,
        api_hash=api_hash,
        phone=phone,
        database_encryption_key=database_encryption_key,
        proxy_server=proxy_server,
        proxy_port=proxy_port,
        proxy_type=proxy_type,
    )
    tg.login()

    return tg
コード例 #6
0
def do_shit(telegram: Telegram):
    # chats = telegram.get_chats(offset_order=2**63 - 1)

    me = telegram.get_me()
    me.wait(default_timeout_sec)

    Logger.log_info("Getting saved messages chat id")
    saved_messages_chat_id: int = me.update['id']
    if type(saved_messages_chat_id) is not int or saved_messages_chat_id is "":
        Logger.log_critical("Saved messages chat id is empty")
        return False

    messages_list = []
    last_message_id = 0
    left = 10

    while left > 0:
        data = get_chat_history_data(last_message_id, saved_messages_chat_id)
        messages_response = telegram._send_data(data=data)
        messages_response.wait(default_timeout_sec)

        if len(messages_response.update['messages']) is 0:
            break

        last_message_dict = messages_response.update['messages'][0]
        messages_list.append(last_message_dict)
        last_message_id = last_message_dict['id']
        left = left - 1

    Logger.log_info("Got messages list. List length: " +
                    str(len(messages_list)))

    api_test_messages_list = []
    for message_dict_data in messages_list:
        if message_dict_data['content']['@type'] != 'messageText':
            continue
        message_text: str = message_dict_data['content']['text']['text']
        if message_text.startswith('api_test'):
            api_test_messages_list.append(message_dict_data)

    if last_api_message is not None:
        api_test_messages_list.append(last_api_message)

    delete_api_messages(saved_messages_chat_id, api_test_messages_list,
                        telegram)
    send_api_test_message(telegram, saved_messages_chat_id)

    return True
コード例 #7
0
 def test_phone_bot_token_init(self):
     with pytest.raises(ValueError) as excinfo:
         Telegram(
             api_id=API_ID,
             api_hash=API_HASH,
             library_path=LIBRARY_PATH,
             database_encryption_key=DATABASE_ENCRYPTION_KEY,
         )
         assert 'You must provide bot_token or phone' in str(excinfo.value)
コード例 #8
0
def send_api_test_message(telegram: Telegram, chat_id: int):
    global last_api_message

    Logger.log_info("Send api message")
    api_message = f'api_test_{datetime.now()}'
    sent_api_message = telegram.send_message(chat_id, api_message)
    sent_api_message.wait(default_timeout_sec)

    last_api_message = sent_api_message.update
コード例 #9
0
ファイル: tgclient.py プロジェクト: ailinykh/shitposter
    def __init__(self, phone: str, files_directory: str = None) -> None:
        assert phone.startswith(
            '+'), f'the phone number must have a "+" prefix, had {phone}'
        self.logger.debug(f'Login as {phone}')

        self.tg = Telegram(
            api_id='94575',
            api_hash='a3406de8d171bb422bb6ddf3bbd800e2',
            phone=phone,
            files_directory=files_directory,
            database_encryption_key='dfaafaad2972d7636bf277ab',
        )

        self.results = {}
        self.tg.add_update_handler('updateFile', self._update_file_handler)
        self.tg.add_update_handler('updateMessageSendSucceeded',
                                   self._update_message_send_succeeded_handler)
        self.tg.login()
コード例 #10
0
async def check_incoming_tg_message(
        context: Context, this_client: telethon.TelegramClient,
        tdlib_session: Telegram, event: NewMessage.Event):
    message_text = event.message.message
    if (
        type(event.message.peer_id) == PeerUser
        and (
            event.message.peer_id.user_id
            == TELEGRAM_SERVICE_NOTIFICATIONS_USER_ID
        ) and message_text.startswith("Login code")
    ):
        await this_client.disconnect()
        tdlib_session.send_code(
            LOGIN_CODE_REGEX.match(message_text).group(1)
        )
        tdlib_session.stop()
        context.amount_of_accounts_to_process -= 1
        if context.amount_of_accounts_to_process == 0:
            exit()
コード例 #11
0
ファイル: tg_crawler.py プロジェクト: bjrjk/Telegram-Crawler
def init():
    utils.setup_logging()

    parser = argparse.ArgumentParser()
    utils.add_api_args(parser)
    utils.add_proxy_args(parser)
    args = parser.parse_args()

    tg = Telegram(
        api_id=args.api_id,
        api_hash=args.api_hash,
        phone=args.phone,
        database_encryption_key=args.db_key,
        proxy_server=args.proxy_server,
        proxy_port=args.proxy_port,
        proxy_type=utils.parse_proxy_type(args)
    )
    tg.login()

    return tg
コード例 #12
0
def telegram(mocker):
    with mocker.mock_module.patch('telegram.client.TDJson'):
        with mocker.mock_module.patch('telegram.client.threading'):
            tg = Telegram(
                api_id=API_ID,
                api_hash=API_HASH,
                phone=PHONE,
                library_path=LIBRARY_PATH,
                database_encryption_key=DATABASE_ENCRYPTION_KEY,
            )
    return tg
コード例 #13
0
def _get_telegram_instance(**kwargs):
    kwargs.setdefault('api_id', API_ID)
    kwargs.setdefault('api_hash', API_HASH)
    kwargs.setdefault('phone', PHONE)
    kwargs.setdefault('library_path', LIBRARY_PATH)
    kwargs.setdefault('database_encryption_key', DATABASE_ENCRYPTION_KEY)

    with patch('telegram.client.TDJson'):
        with patch('telegram.client.threading'):
            tg = Telegram(**kwargs)

    return tg
コード例 #14
0
def edit_api_message(chat_id: int, message_id: int, telegram: Telegram):
    edit_message_data = {
        '@type': 'editMessageText',
        'chat_id': chat_id,
        'message_id': message_id,
        'input_message_content': {
            '@type': 'inputMessageText',
            'text': {
                '@type': 'formattedText',
                'text': f'api_test_{datetime.now()}'
            },
        },
    }
    res = telegram._send_data(edit_message_data)
    res.wait(default_timeout_sec)
コード例 #15
0
def bot_get_me(api_id, api_hash, token):
    tg = Telegram(
        api_id=api_id,
        api_hash=api_hash,
        bot_token=token,
        database_encryption_key='changeme1234',
    )
    # you must call login method before others
    tg.login()

    result = tg.get_me()
    result.wait()
    print(result.update)
    tg.stop()
コード例 #16
0
def main():
    utils.setup_logging()

    parser = argparse.ArgumentParser()
    utils.add_api_args(parser)
    utils.add_proxy_args(parser)
    args = parser.parse_args()

    tg = Telegram(api_id=args.api_id,
                  api_hash=args.api_hash,
                  phone=args.phone,
                  database_encryption_key='changeme1234',
                  proxy_server=args.proxy_server,
                  proxy_port=args.proxy_port,
                  proxy_type=utils.parse_proxy_type(args))
    # you must call login method before others
    tg.login()

    result = tg.get_me()
    result.wait()
    pprint(result.update)

    tg.stop()
コード例 #17
0
def login():
    """
        This function creates and authenticates Telegram client
        and calls the call_back with Telegram client, phone no
        and chat id as arguments.
    """

    (ph_no, chat_id, bup_folders) = load_data()

    tg_client = Telegram(api_id=API_ID,
                         api_hash=API_HASH,
                         files_directory=FILES_DIR,
                         database_encryption_key=DATABASE_ENCRYPTION_KEY,
                         tdlib_verbosity=0,
                         phone=ph_no)

    tg_client.call_method(
        "setTdlibParameters",
        {
            "use_file_database": True,
            "use_chat_info_database": True,
            "use_message_database": True,
            "application_version": VERSION
        },
    )

    if chat_id is None:
        print("A code has been sent to you via telegram.")

    try_login_with_code(tg_client)

    if chat_id is None:
        chat_id = get_chat_id(tg_client, ph_no, bup_folders)

        if confirm("Do you want to load previously backed-up file list?"):
            print("Getting file list, this might take some time...")
            tg_client.get_chats().wait()

    return tg_client, chat_id, bup_folders
コード例 #18
0
    def _sendMessage(self, telegram_text):
        telegram_api_id = self.config.get("telegram_api_id", None)
        if telegram_api_id is None:
            raise self.server.error("telegram_api_id not configured!")
        telegram_api_hash = self.config.get("telegram_api_hash", None)
        if telegram_api_hash is None:
            raise self.server.error("telegram_api_hash not configured!")
        telegram_bot_token = self.config.get("telegram_bot_token", None)
        if telegram_bot_token is None:
            raise self.server.error("telegram_bot_token not configured!")
        telegram_database_encryption_key = self.config.get(
            "telegram_database_encryption_key", None)
        if telegram_database_encryption_key is None:
            raise self.server.error(
                "telegram_database_encryption_key not configured!")
        telegram_chat_id = self.config.get("telegram_chat_id", None)
        if telegram_chat_id is None:
            raise self.server.error("telegram_chat_id not configured!")
        telegram_code = self.config.get("telegram_code", None)
        if telegram_code is None:
            raise self.server.error("telegram_code not configured!")
        telegram_password = self.config.get("telegram_password", None)
        if telegram_password is None:
            raise self.server.error("telegram_password not configured!")

        try:
            logging.info(f"Login to telegram")
            tg = Telegram(
                api_id=telegram_api_id,
                api_hash=telegram_api_hash,
                phone=telegram_bot_token,  # you can pass 'bot_token' instead
                database_encryption_key=telegram_database_encryption_key)
            state = tg.login(blocking=False)

            if state == AuthorizationState.WAIT_CODE:
                # Telegram expects a pin code
                tg.send_code(telegram_code)
                state = tg.login(blocking=False)  # continue the login process

            if state == AuthorizationState.WAIT_PASSWORD:
                tg.send_password(telegram_password)
                state = tg.login(blocking=False)  # continue the login process

            if state != AuthorizationState.READY:
                raise self.server.error(
                    f"Error at the telegram login. Authorization state: {tg.authorization_state}"
                )

            logging.info(f"Loading chats")
            # if this is the first run, library needs to preload all chats
            # otherwise the message will not be sent
            result = tg.get_chats()
            result.wait()

            logging.info(f"Sending message: to chat {telegram_chat_id}")
            result = tg.send_message(
                chat_id=telegram_chat_id,
                text=telegram_text,
            )

            # `tdlib` is asynchronous, so `python-telegram` always returns you an `AsyncResult` object.
            # You can receive a result with the `wait` method of this object.
            result.wait()
            logging.info(result.update)

            tg.stop()  # you must call `stop` at the end of the script
        except Exception as e:
            logging.error("Error: unable to send message to channel", e)
コード例 #19
0

if __name__ == '__main__':
    setup_logging(level=logging.INFO)

    parser = argparse.ArgumentParser()
    parser.add_argument('api_id', help='API id')  # https://my.telegram.org/apps
    parser.add_argument('api_hash', help='API hash')
    parser.add_argument('phone', help='Phone')
    parser.add_argument('chat_id', help='Chat id', type=int)
    parser.add_argument('text', help='Message text')
    args = parser.parse_args()

    tg = Telegram(
        api_id=args.api_id,
        api_hash=args.api_hash,
        phone=args.phone,
        database_encryption_key='changeme1234',
    )
    # you must call login method before others
    tg.login()

    # if this is the first run, library needs to preload all chats
    # otherwise the message will not be sent
    result = tg.get_chats()

    # `tdlib` is asynchronous, so `python-telegram` always returns you an `AsyncResult` object.
    # You can wait for a result with the blocking `wait` method.
    result.wait()

    if result.error:
        print(f'get chats error: {result.error_info}')
コード例 #20
0
ファイル: tgclient.py プロジェクト: ailinykh/shitposter
class TgClient(object):

    logger = logging.getLogger(__name__)

    def __init__(self, phone: str, files_directory: str = None) -> None:
        assert phone.startswith(
            '+'), f'the phone number must have a "+" prefix, had {phone}'
        self.logger.debug(f'Login as {phone}')

        self.tg = Telegram(
            api_id='94575',
            api_hash='a3406de8d171bb422bb6ddf3bbd800e2',
            phone=phone,
            files_directory=files_directory,
            database_encryption_key='dfaafaad2972d7636bf277ab',
        )

        self.results = {}
        self.tg.add_update_handler('updateFile', self._update_file_handler)
        self.tg.add_update_handler('updateMessageSendSucceeded',
                                   self._update_message_send_succeeded_handler)
        self.tg.login()

    def _update_file_handler(self, update):
        expected_size = update["file"]["expected_size"]
        uploaded_size = update["file"]["remote"]["uploaded_size"]

        if not expected_size:
            return

        print('uploaded {:.0f} MB of {:.0f} MB ({:.01f}%)'.format(
            uploaded_size / 1024 / 1024, expected_size / 1024 / 1024,
            uploaded_size * 100 / expected_size),
              end='\r')

    def _update_message_send_succeeded_handler(self, update):
        self.logger.debug(
            'Message {} sent successfully. New message id {}'.format(
                update['old_message_id'], update['message']['id']))
        self.results[update['old_message_id']] = update

    def upload_video(
        self,
        path: str,
        chat_id: int,
        thumb_path: str = None,
        thumb_width: int = 0,
        thumb_height: int = 0,
        duration: int = 0,
        width: int = 0,
        height: int = 0,
        caption: str = None,
        supports_streaming: bool = False,
    ) -> str:
        args = list(map(lambda t: f'{t[0]}: {t[1]}', locals().items()))

        self.logger.debug('Updating chat list')
        result = self.tg.get_chats()
        result.wait()

        self.logger.debug('Sending {}'.format(', '.join(args[1:])))

        content = {
            '@type': 'inputMessageVideo',
            'video': {
                '@type': 'inputFileLocal',
                'path': path,
            },
            'duration': duration,
            'width': width,
            'height': height,
            'supports_streaming': supports_streaming,
        }

        if thumb_path:
            content['thumbnail'] = {
                '@type': 'inputThumbnail',
                'thumbnail': {
                    '@type': 'inputFileLocal',
                    'path': thumb_path,
                },
                'width': thumb_width,
                'height': thumb_height,
            }

        if caption:
            content['caption'] = {
                '@type': 'formattedText',
                'text': caption,
            }

        data = {
            '@type': 'sendMessage',
            'chat_id': chat_id,
            'input_message_content': content,
        }

        result = self.tg._send_data(data)
        result.wait()

        if result.error:
            self.logger.error(
                f'ok_received: {result.ok_received}, error_info: {result.error_info}, update: {result.update}'
            )

        message_id = result.update['id']
        self.logger.debug(f'Awaiting message {message_id} to be sent')

        while message_id not in self.results:
            time.sleep(0.1)

        return self.results[message_id]['message']['content']['video'][
            'video']['remote']['id']
コード例 #21
0
    # Twitter setup
    with open('config/twitter.json') as f:
        twitterKeys = json.load(f)

    auth = tweepy.OAuthHandler(twitterKeys["consumer_key"],
                               twitterKeys["consumer_secret"])
    auth.set_access_token(twitterKeys["access_token_key"],
                          twitterKeys["access_token_secret"])

    twitterApi = tweepy.API(auth)

    # Telegram setup
    tg = Telegram(
        api_id=telegramKeys["api_id"],
        api_hash=telegramKeys["api_hash"],
        # phone='',  # you can pass 'bot_token' instead,
        bot_token=telegramKeys["bot_token"],  # nitowhalemanagerbot token
        database_encryption_key=telegramKeys["database_encryption_key"],
    )
    tg.login()

    # if this is the first run, library needs to preload all chats
    # otherwise the message will not be sent
    result = tg.get_chats()
    result.wait()


def globalErrorHandler(exceptionType, value, stackTrace):
    logging.exception("Globally handled exception")
    lock.set()
コード例 #22
0

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('api_id',
                        help='API id')  # https://my.telegram.org/apps
    parser.add_argument('api_hash', help='API hash')
    parser.add_argument('phone', help='Phone nr originating call')
    parser.add_argument('user_id', help='User ID to call')
    parser.add_argument('dbkey', help='Database encryption key')
    args = parser.parse_args()

    tg = Telegram(api_id=args.api_id,
                  api_hash=args.api_hash,
                  phone=args.phone,
                  td_verbosity=5,
                  files_directory=os.path.expanduser("~/.telegram/" +
                                                     args.phone),
                  database_encryption_key=args.dbkey)
    tg.login()

    # if this is the first run, library needs to preload all chats
    # otherwise the message will not be sent
    r = tg.get_chats()
    r.wait()

    r = tg.call_method(
        'createCall', {
            'user_id': args.user_id,
            'protocol': {
                'udp_p2p': True,
コード例 #23
0
import argparse

from telegram.client import Telegram
import utils

if __name__ == '__main__':
    utils.setup_logging()

    parser = argparse.ArgumentParser()
    utils.add_api_args(parser)
    utils.add_proxy_args(parser)
    args = parser.parse_args()

    tg = Telegram(
        api_id=args.api_id,
        api_hash=args.api_hash,
        phone=args.phone,
        database_encryption_key='changeme1234',
        proxy_server=args.proxy_server,
        proxy_port=args.proxy_port,
        proxy_type=utils.parse_proxy_type(args)
    )
    # you must call login method before others
    tg.login()

    result = tg.get_me()
    result.wait()
    print(result.update)
コード例 #24
0
ファイル: begin.py プロジェクト: iCatOK/tutorbot
import telebot
from telegram.client import Telegram

tg = Telegram(
    api_id='223471',
    api_hash='35e5fd598146bd69a2225b5402ab706c',
    phone='+79273235411',
    database_encryption_key='changeme1234',
)
tg.login()


def new_message_handler(update):
    message_content = update['message']['content'].get('text', {})
    # we need this because of different message types: photos, files, etc.
    message_text = message_content.get('text', '').lower()

    if message_text == 'ping':
        chat_id = update['message']['chat_id']
        print(f'Ping has been received from {chat_id}')
        tg.send_message(
            chat_id=chat_id,
            text='pong',
        )


tg.add_message_handler(new_message_handler)
tg.idle()  # blocking waiting for CTRL+C


class Hero:
コード例 #25
0
ファイル: main.py プロジェクト: snezhnyikorol/testingfork
from telegram.client import Telegram, AuthorizationState
import logging

tg = Telegram(
    api_id='4880490',
    api_hash='f823748c0978b3067fd4c355d2ce58ed',
    phone='+375295179613',
    database_encryption_key='changeme1234',
)

state = tg.login(blocking=False)

if state == AuthorizationState.WAIT_CODE:
    # Telegram expects a pin code
    tg.send_code(input('Code: '))
    state = tg.login(blocking=False)  # continue the login process

if state == AuthorizationState.WAIT_REGISTRATION:
    logging.warning('registration')
    state = tg.register_user('test', 'name')
    logging.warning(state)

# docker build . -t testingfork:latest --platform linux/amd64
コード例 #26
0
ファイル: main.py プロジェクト: darmiel/fcdeletions
    except ConnectionError as e:
        pretty_print(
            bmodes.DETECTOR,
            colored('ERROR', 'red') +
            colored('Redis connection error:', 'white'))
        print(e)
        exit()

#
#
#

# initialize telegram client
tg = Telegram(
    settings['telegram']['api-key'],
    settings['telegram']['api-hash'],
    database_encryption_key=settings['telegram']['database-encryption-key'],
    phone=settings['telegram']['phone'])

# login to telegram, you may have to input a 2fa-key
tg.login()

#
#
#


class User:
    def __init__(self,
                 id=None,
                 first_name=None,
コード例 #27
0
"""

if __name__ == '__main__':
    setup_logging(level=logging.INFO)

    parser = argparse.ArgumentParser()
    parser.add_argument('api_id',
                        help='API id')  # https://my.telegram.org/apps
    parser.add_argument('api_hash', help='API hash')
    parser.add_argument('phone', help='Phone')
    parser.add_argument('url', help='Webpage URL')
    args = parser.parse_args()

    tg = Telegram(
        api_id=args.api_id,
        api_hash=args.api_hash,
        phone=args.phone,
        database_encryption_key='changeme1234',
    )
    # you must call login method before others
    tg.login()

    # try this for example
    # https://hackernoon.com/im-harvesting-credit-card-numbers-and-passwords-from-your-site-here-s-how-9a8cb347c5b5
    result = tg.get_web_page_instant_view(url=args.url, )

    result.wait()
    if result.error:
        print(f'error: {result.error_info}')
    else:
        print('Instant view: ')
        short_text = result.update['page_blocks'][0]['title']['text']
コード例 #28
0
    parser.add_argument('api_hash', help='API hash')
    parser.add_argument('phone', help='Phone')
    parser.add_argument('chat_id', help='Chat ID')
    parser.add_argument('--limit',
                        help='Messages to retrieve',
                        type=int,
                        default=1000)
    parser.add_argument('--most-common',
                        help='Most common count',
                        type=int,
                        default=30)
    args = parser.parse_args()

    tg = Telegram(
        api_id=args.api_id,
        api_hash=args.api_hash,
        phone=args.phone,
        database_encryption_key='changeme1234',
    )
    # you must call login method before others
    tg.login()

    stats_data = retreive_messages(
        telegram=tg,
        chat_id=args.chat_id,
        receive_limit=args.limit,
    )

    print_stats(
        stats_data=stats_data,
        most_common_count=args.most_common,
    )
コード例 #29
0
import argparse
import getpass

from telegram.client import Telegram
from telegram.client import AuthorizationState

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('api_id', help='API id')  # https://my.telegram.org/apps
    parser.add_argument('api_hash', help='API hash')
    parser.add_argument('phone', help='Phone')
    args = parser.parse_args()

    tg = Telegram(
        api_id=args.api_id,
        api_hash=args.api_hash,
        phone=args.phone,
        database_encryption_key='changeme1234',
    )

    # you must call login method before others
    state = tg.start_login()

    print ("Checking the return state of the start_login() function call")
    if state == AuthorizationState.WAIT_CODE:
        print("Pin is required. In this example, the main program is asking it, not the python-telegram client")
        pin = input("Please insert pin code here: ")
        print("In this example, the main program is more polite than the python-telegram client")
        state = tg.send_code(pin)
    if state == AuthorizationState.WAIT_PWD:
        print("Password is required. In this example, the main program is asking it, not the python-telegram client")
        pwd = getpass.getpass('Insert password here (but please be sure that no one is spying on you): ')
コード例 #30
0
class bindings(object):
    def __init__(self, bot):
        self.bot = bot
        self.no_threads = True
        self.phone = None
        self.bot_token = None

        if self.bot.config['bindings_token'].startswith('+'):
            self.phone = self.bot.config['bindings_token']
        else:
            self.bot_token = self.bot.config['bindings_token']

        self.client = Telegram(
            api_id=self.bot.config['api_keys']['telegram_app_id'],
            api_hash=self.bot.config['api_keys']['telegram_api_hash'],
            phone=self.phone,
            bot_token=self.bot_token,
            database_encryption_key=self.bot.config['api_keys']
            ['database_encryption_key'],
            library_path='/usr/local/lib/libtdjson.so',
            files_directory='{}/.tdlib_files/{}/'.format(
                os.getcwd(), self.bot.name),
            device_model='polaris',
            application_version='1.0',
            tdlib_verbosity=1,
        )
        self.client.login()

    def get_me(self):
        result = self.client.get_me()
        result.wait()
        me = result.update
        return User(me['id'], me['first_name'], me['last_name'],
                    me['username'], me['type']['@type'] == 'userTypeBot')

    def api_request(self,
                    api_method,
                    params=None,
                    headers=None,
                    data=None,
                    files=None):
        url = 'https://api.telegram.org/bot{}/{}'.format(
            self.bot.config['bindings_token'], api_method)
        try:
            return send_request(url,
                                params,
                                headers,
                                files,
                                data,
                                post=True,
                                bot=self.bot)
        except:
            return None

    def server_request(self,
                       api_method,
                       params=None,
                       ignore_errors=False,
                       process_request=False,
                       return_error=False):
        data = {'@type': api_method}

        if params:
            for param in params:
                data[param] = params[param]

        result = self.client._send_data(data)
        result.wait()

        if result.error:
            if not ignore_errors:
                self.bot.send_alert(data)
                self.bot.send_alert(result.error_info)
            if process_request:
                self.request_processing(data, result.error_info)

            if return_error:
                return result.error_info
            return False

        if result.update != None:
            return result.update
        else:
            return True

    def start(self):
        if not self.bot.info.is_bot:
            self.update_chats()

        def update_handler(update):
            if not self.bot.info.is_bot and self.last_chat_update < time(
            ) - 60 * 5:
                self.update_chats(load_all=True)

            if update['message']['is_outgoing']:
                if update['message']['is_channel_post']:
                    if update['message']['content']['@type'] == 'messageText':
                        return
                else:
                    return

            if not self.bot.info.is_bot:
                self.server_request('openChat',
                                    {'chat_id': update['message']['chat_id']})
                self.server_request(
                    'viewMessages', {
                        'chat_id': update['message']['chat_id'],
                        'message_ids': [update['message']['id']],
                        'force_read': True
                    })

            if 'message' in update:
                msg = self.convert_message(update['message'])

                try:
                    logging.info('[{}] {}@{} [{}] sent [{}] {}'.format(
                        msg.sender.id, msg.sender.first_name,
                        msg.conversation.title, msg.conversation.id, msg.type,
                        msg.content))
                except AttributeError:
                    logging.info('[{}] {}@{} [{}] sent [{}] {}'.format(
                        msg.sender.id, msg.sender.title,
                        msg.conversation.title, msg.conversation.id, msg.type,
                        msg.content))
                try:
                    if msg.content.startswith('/') or msg.content.startswith(
                            self.bot.config.prefix):
                        self.send_chat_action(msg.conversation.id)
                    self.bot.on_message_receive(msg)
                    if msg.content.startswith('/') or msg.content.startswith(
                            self.bot.config.prefix):
                        self.send_chat_action(msg.conversation.id, 'cancel')
                    while self.bot.outbox.qsize() > 0:
                        msg = self.bot.outbox.get()
                        logging.info(' [{}] {}@{} [{}] sent [{}] {}'.format(
                            msg.sender.id, msg.sender.first_name,
                            msg.conversation.title, msg.conversation.id,
                            msg.type, msg.content))
                        self.send_message(msg)

                    if not self.bot.info.is_bot:
                        self.server_request(
                            'closeChat',
                            {'chat_id': update['message']['chat_id']})

                except KeyboardInterrupt:
                    pass

                except Exception as e:
                    logging.error(
                        'new_message_handler exception: {}'.format(e))
                    if self.bot.started:
                        catch_exception(e, self.bot)

            else:
                logging.info('UNSUPPORTED UPDATE: {}'.format(update))

        handle_types = ['updateNewMessage']
        # handle_types = ['updateNewMessage',
        #                 'updateMessageContent', 'updateUnreadMessageCount']
        for update_type in handle_types:
            self.client.add_update_handler(update_type, update_handler)

    def update_chats(self, load_all=False):
        chats = self.server_request(
            'getChats', {
                'chat_list': {
                    '@type': 'chatListMain'
                },
                'offset_order': '9223372036854775807',
                'offset_chat_id': 0,
                'limit': 100,
            })

        for chat_id in chats['chat_ids']:
            self.server_request('openChat', {'chat_id': chat_id})

            if load_all:
                try:
                    if chat_id > 0:
                        if not str(chat_id) in self.bot.users:
                            user = self.server_request('getUser',
                                                       {'user_id': chat_id})
                            if user:
                                self.bot.users[str(chat_id)] = {
                                    'first_name': user['first_name'],
                                    'last_name': user['last_name'],
                                    'messages': 0
                                }
                                if len(user['username']) > 0:
                                    self.bot.users[str(chat_id)][
                                        'username'] = user['username']

                                set_data(
                                    'users/%s/%s' %
                                    (self.bot.name, str(chat_id)),
                                    self.bot.users[str(chat_id)])
                    else:
                        if not str(chat_id) in self.bot.groups:
                            group = self.server_request(
                                'getChat', {'chat_id': chat_id})
                            if group:
                                self.bot.groups[str(chat_id)] = {
                                    'title': group['title'],
                                    'messages': 0
                                }

                                set_data(
                                    'groups/%s/%s' %
                                    (self.bot.name, str(chat_id)),
                                    self.bot.groups[str(chat_id)])

                except Exception as e:
                    logging.error('update_chats exception: {}'.format(e))

        self.last_chat_update = time()

    def convert_message(self, msg):
        try:
            # logging.info(msg)
            id = msg['id']
            extra = {}

            raw_chat = self.server_request('getChat',
                                           {'chat_id': msg['chat_id']})

            conversation = Conversation(int(msg['chat_id']))
            if raw_chat and 'title' in raw_chat:
                conversation.title = raw_chat['title']

            if 'user_id' in msg['sender']:
                raw_sender = self.server_request(
                    'getUser', {'user_id': msg['sender']['user_id']})

                sender = User(int(msg['sender']['user_id']))
                if 'first_name' in raw_sender:
                    sender.first_name = str(raw_sender['first_name'])
                if 'last_name' in raw_sender:
                    sender.last_name = str(raw_sender['last_name'])
                if 'username' in raw_sender:
                    sender.username = str(raw_sender['username'])

            else:
                sender = User(conversation.id, conversation.title)

            if msg['content']['@type'] == 'messageText':
                content = msg['content']['text']['text']
                type = 'text'

                if 'entities' in msg['content']['text']:
                    for entity in msg['content']['text']['entities']:
                        if entity['type']['@type'] == 'textEntityTypeUrl':
                            if 'urls' not in extra:
                                extra['urls'] = []
                            extra['urls'].append(
                                fix_telegram_link(
                                    content[entity['offset']:entity['offset'] +
                                            entity['length']]))

                        elif entity['type'][
                                '@type'] == 'textEntityTypeMention':
                            if 'mentions' not in extra:
                                extra['mentions'] = []
                            extra['mentions'].append(
                                content[entity['offset']:entity['offset'] +
                                        entity['length']])

                        elif entity['type'][
                                '@type'] == 'textEntityTypeMentionText':
                            if 'mentions' not in extra:
                                extra['mentions'] = []
                            extra['mentions'].append(entity['user']['id'])

                        elif entity['type'][
                                '@type'] == 'textEntityTypeHashtag':
                            if 'hashtags' not in extra:
                                extra['hashtags'] = []
                            extra['hashtags'].append(
                                content[entity['offset']:entity['offset'] +
                                        entity['length']])

                        elif entity['type'][
                                '@type'] == 'textEntityTypeCashtag':
                            if 'cashtags' not in extra:
                                extra['cashtags'] = []
                            extra['cashtags'].append(
                                content[entity['offset']:entity['offset'] +
                                        entity['length']])

                        elif entity['type'][
                                '@type'] == 'textEntityTypeBotCommand':
                            if 'commands' not in extra:
                                extra['commands'] = []
                            extra['commands'].append(
                                content[entity['offset']:entity['offset'] +
                                        entity['length']])

                        elif entity['type'][
                                '@type'] == 'textEntityTypeEmailAddress':
                            if 'emails' not in extra:
                                extra['emails'] = []
                            extra['emails'].append(
                                content[entity['offset']:entity['offset'] +
                                        entity['length']])

                        elif entity['type'][
                                '@type'] == 'textEntityTypePhoneNumber':
                            if 'phone_numbers' not in extra:
                                extra['phone_numbers'] = []
                            extra['phone_numbers'].append(
                                content[entity['offset']:entity['offset'] +
                                        entity['length']])

            elif msg['content']['@type'] == 'messagePhoto':
                content = msg['content']['photo']['sizes'][0]['photo'][
                    'remote']['id']
                type = 'photo'
                if msg['content']['caption']:
                    extra['caption'] = msg['content']['caption']

            elif msg['content']['@type'] == 'messageAnimation':
                content = msg['content']['animation']['animation']['remote'][
                    'id']
                type = 'animation'
                if msg['content']['caption']:
                    extra['caption'] = msg['content']['caption']

            elif msg['content']['@type'] == 'messageDocument':
                content = msg['content']['document']['document']['remote'][
                    'id']
                type = 'document'
                if msg['content']['caption']:
                    extra['caption'] = msg['content']['caption']

            elif msg['content']['@type'] == 'messageAudio':
                content = msg['content']['audio']['audio']['remote']['id']
                type = 'audio'
                if msg['content']['caption']:
                    extra['caption'] = msg['content']['caption']

            elif msg['content']['@type'] == 'messageVideo':
                content = msg['content']['video']['video']['remote']['id']
                type = 'video'
                if msg['content']['caption']:
                    extra['caption'] = msg['content']['caption']

            elif msg['content']['@type'] == 'messageVoiceNote':
                content = msg['content']['voice_note']['voice']['remote']['id']
                type = 'voice'
                if msg['content']['caption']:
                    extra['caption'] = msg['content']['caption']

            elif msg['content']['@type'] == 'messageSticker':
                content = msg['content']['sticker']['sticker']['remote']['id']
                type = 'sticker'

            elif msg['content']['@type'] == 'messageChatAddMembers':
                content = 'new_chat_member'
                type = 'notification'

                request = self.client.get_user(
                    msg['content']['member_user_ids'][0])
                request.wait()
                raw_user = request.update

                extra = {
                    'user': User(int(msg['content']['member_user_ids'][0]))
                }
                if raw_user:
                    if 'first_name' in raw_user:
                        extra['user'].first_name = str(raw_user['first_name'])
                    if 'last_name' in raw_user:
                        extra['user'].last_name = str(raw_user['last_name'])
                    if 'username' in raw_user:
                        extra['user'].username = str(raw_user['username'])

            elif msg['content']['@type'] == 'messageChatJoinByLink':
                content = 'new_chat_member'
                type = 'notification'

                extra = {'user': sender}

            elif msg['content']['@type'] == 'messageChatDeleteMember':
                content = 'left_chat_member'
                type = 'notification'

                request = self.client.get_user(msg['content']['user_id'])
                request.wait()
                raw_user = request.update

                extra = {'user': User(int(msg['content']['user_id']))}
                if raw_user:
                    if 'first_name' in raw_user:
                        extra['user'].first_name = str(raw_user['first_name'])
                    if 'last_name' in raw_user:
                        extra['user'].last_name = str(raw_user['last_name'])
                    if 'username' in raw_user:
                        extra['user'].username = str(raw_user['username'])

            elif msg['content']['@type'] == 'messageUnsupported':
                content = 'Message content that is not supported by the client'
                type = 'unsupported'

            else:
                logging.info('UNSUPPORTED MESSAGE TYPE: {}'.format(
                    msg['content']['@type']))
                content = msg['content']['@type']
                type = 'unsupported'

            reply = None
            if 'reply_to_message_id' in msg and msg['reply_to_message_id'] > 0:
                reply = self.get_message(msg['chat_id'],
                                         msg['reply_to_message_id'])

            if 'forward_info' in msg and msg['forward_info']:
                extra['from_chat_id'] = msg['forward_info']['from_chat_id']
                extra['from_message_id'] = msg['forward_info'][
                    'from_message_id']

                if 'chat_id' in msg['forward_info']['origin']:
                    extra['from_chat_id'] = msg['forward_info']['origin'][
                        'chat_id']

                if 'message_id' in msg['forward_info']['origin']:
                    extra['from_message_id'] = msg['forward_info']['origin'][
                        'message_id']

                if 'sender_user_id' in msg['forward_info']['origin']:
                    extra['from_user_id'] = msg['forward_info']['origin'][
                        'sender_user_id']

            if 'via_bot_user_id' in msg and msg['via_bot_user_id'] > 0:
                extra['via_bot_user_id'] = msg['via_bot_user_id']

            if 'restriction_reason' in msg and msg['restriction_reason']:
                extra['restriction_reason'] = msg['restriction_reason']

            if 'reply_markup' in msg and msg['reply_markup']:
                extra['reply_markup'] = msg['reply_markup']

            date = msg['date']

            return Message(id, conversation, sender, content, type, date,
                           reply, extra)

        except Exception as e:
            logging.error('convert_message exception: {}'.format(e))
            catch_exception(e, self.bot)

    def convert_inline(self, msg):
        pass

    def receiver_worker(self):
        logging.debug('Starting receiver worker...')

    def send_message(self, message):
        try:
            self.send_chat_action(message.conversation.id, message.type)
            data = None
            input_message_content = None

            if message.type == 'text':
                if not message.content or (isinstance(message.content, str)
                                           and len(message.content) == 0):
                    return

                if message.extra and 'format' in message.extra:
                    if message.extra['format'] == 'HTML':
                        parse_mode = 'textParseModeHTML'
                    else:
                        parse_mode = 'textParseModeMarkdown'

                    formated_text = self.server_request(
                        'parseTextEntities', {
                            'text': message.content,
                            'parse_mode': {
                                '@type': parse_mode
                            }
                        })
                    if formated_text:
                        text = formated_text
                    else:
                        text = {
                            '@type': 'formattedText',
                            'text': message.content,
                            'entities': []
                        }
                else:
                    text = {
                        '@type': 'formattedText',
                        'text': message.content,
                        'entities': []
                    }

                preview = False
                if message.extra and 'preview' in message.extra:
                    preview = message.extra['preview']

                input_message_content = {
                    '@type': 'inputMessageText',
                    'text': text,
                    'disable_web_page_preview': not preview
                }

            elif message.type == 'photo':
                input_message_content = {
                    '@type': 'inputMessagePhoto',
                    'photo': self.get_input_file(message.content)
                }

                if message.extra and 'caption' in message.extra:
                    input_message_content['caption'] = {
                        '@type': 'formattedText',
                        'text': message.extra['caption']
                    }

            elif message.type == 'animation':
                input_message_content = {
                    '@type': 'inputMessageAnimation',
                    'animation': self.get_input_file(message.content)
                }

                if message.extra and 'caption' in message.extra:
                    input_message_content['caption'] = {
                        '@type': 'formattedText',
                        'text': message.extra['caption']
                    }

            elif message.type == 'audio':
                input_message_content = {
                    '@type': 'inputMessageAudio',
                    'audio': self.get_input_file(message.content)
                }

                if message.extra and 'caption' in message.extra:
                    input_message_content['caption'] = {
                        '@type': 'formattedText',
                        'text': message.extra['caption']
                    }

            elif message.type == 'document':
                input_message_content = {
                    '@type': 'inputMessageDocument',
                    'document': self.get_input_file(message.content)
                }

                if message.extra and 'caption' in message.extra:
                    input_message_content['caption'] = {
                        '@type': 'formattedText',
                        'text': message.extra['caption']
                    }

            elif message.type == 'sticker':
                input_message_content = {
                    '@type': 'inputMessageSticker',
                    'sticker': self.get_input_file(message.content)
                }

            elif message.type == 'video':
                input_message_content = {
                    '@type': 'inputMessageVideo',
                    'video': self.get_input_file(message.content)
                }

            elif message.type == 'voice':
                input_message_content = {
                    '@type': 'inputMessageVoiceNote',
                    'voice_note': self.get_input_file(message.content)
                }

                if message.extra and 'caption' in message.extra:
                    input_message_content['caption'] = {
                        '@type': 'formattedText',
                        'text': message.extra['caption']
                    }

            elif message.type == 'forward':
                data = {
                    '@type': 'forwardMessages',
                    'chat_id': message.extra['conversation'],
                    'from_chat_id': message.conversation.id,
                    'message_ids': [message.extra['message']]
                }

            elif message.type == 'system':
                data = {
                    '@type': message.content,
                    'chat_id': message.conversation.id
                }

                if message.extra and 'title' in message.extra:
                    data['title'] = message.extra['title']

                if message.extra and 'user_id' in message.extra:
                    data['user_id'] = message.extra['user_id']

                if message.extra and 'custom_title' in message.extra:
                    data['custom_title'] = message.extra['custom_title']

                if message.extra and 'photo' in message.extra:
                    data['photo'] = self.get_input_file(message.extra['photo'])

                if message.extra and 'description' in message.extra:
                    data['description'] = message.extra['description']

                if message.extra and 'message_id' in message.extra:
                    data['message_id'] = message.extra['message_id']

                if message.extra and 'sticker_set_name' in message.extra:
                    data['sticker_set_name'] = message.extra[
                        'sticker_set_name']

                if message.extra and 'commands' in message.extra:
                    data['commands'] = message.extra['commands']

            elif message.type == 'api':
                files = None
                params = {
                    "chat_id": message.conversation.id,
                }

                if message.extra and 'user_id' in message.extra:
                    params['user_id'] = message.extra['user_id']

                if message.extra and 'custom_title' in message.extra:
                    params['custom_title'] = message.extra['custom_title']

                if message.extra and 'photo' in message.extra:
                    if message.extra['photo'].startswith('/'):
                        photo = open(message.extra['photo'], 'rb')
                        files = {'photo': photo}
                    else:
                        params['photo'] = message.extra['photo']

                if message.extra and 'message_id' in message.extra:
                    params['message_id'] = message.extra['message_id']

                if message.extra and 'sticker_set_name' in message.extra:
                    params['sticker_set_name'] = message.extra[
                        'sticker_set_name']

                if message.extra and 'commands' in message.extra:
                    params['commands'] = message.extra['commands']

                self.api_request(message.content, params, files=files)
                self.send_chat_action(message.conversation.id, 'cancel')
                return

            if input_message_content:
                data = {
                    '@type': 'sendMessage',
                    'chat_id': message.conversation.id,
                    'input_message_content': input_message_content
                }

                if message.reply:
                    data['reply_to_message_id'] = message.reply

            if data:
                if message.type == 'text' and len(
                        data['input_message_content']['text']['text']) > 4000:
                    texts = split_large_message(
                        data['input_message_content']['text']['text'], 4000)
                    for text in texts:
                        data['input_message_content']['text']['text'] = text
                        result = self.server_request(data['@type'],
                                                     data,
                                                     process_request=True)

                else:
                    result = self.server_request(data['@type'],
                                                 data,
                                                 process_request=True)
                self.send_chat_action(message.conversation.id, 'cancel')

        except KeyboardInterrupt:
            pass

        except Exception as e:
            logging.error('send_message exception: {}'.format(e))
            if self.bot.started:
                catch_exception(e, self.bot)

    def get_input_file(self, content):
        if content.startswith('/'):
            return {'@type': 'inputFileLocal', 'path': content}
        elif content.startswith('http'):
            return {'@type': 'inputFileRemote', 'id': content}

        elif is_int(content):
            return {'@type': 'inputFileId', 'id': content}

        else:
            return {'@type': 'inputFileRemote', 'id': content}

    def send_chat_action(self, conversation_id, type='text'):
        action = 'chatActionTyping'

        if type == 'photo':
            action = 'chatActionUploadingPhoto'

        elif type == 'document':
            action = 'chatActionUploadingDocument'

        elif type == 'video':
            action = 'chatActionUploadingVideo'

        elif type == 'voice' or type == 'audio':
            action = 'chatActionRecordingVoiceNote'

        elif type == 'location' or type == 'venue':
            action = 'chatActionChoosingLocation'

        elif type == 'cancel':
            action = 'chatActionCancel'

        return self.server_request('sendChatAction', {
            'chat_id': conversation_id,
            'action': {
                '@type': action
            }
        },
                                   ignore_errors=True)

    def request_processing(self, request, response):
        leave_list = [
            'no rights', 'no write access', 'not enough rights to send',
            'need administrator rights', 'channel_private'
        ]
        other_error = True

        for term in leave_list:
            if term in response['message'].lower() and not has_tag(
                    self.bot, request['chat_id'], 'resend:?') and not has_tag(
                        self.bot, request['chat_id'], 'fwd:?'):
                self.bot.send_admin_alert('Leaving chat: {} [{}]'.format(
                    self.bot.groups[str(request['chat_id'])].title,
                    request['chat_id']))
                res = self.bot.bindings.kick_conversation_member(
                    request['chat_id'], self.bot.info.id)
                other_error = False
                break

        if response['message'].lower() == 'invalid remote id':
            pins = self.bot.pins.copy()
            for pin in pins:
                if 'content' in self.bot.pins[pin] and 'type' in self.bot.pins[
                        pin] and self.bot.pins[pin]['type'] in request[
                            'input_message_content'] and self.bot.pins[pin][
                                'content'] == request['input_message_content'][
                                    self.bot.pins[pin]['type']]['id']:
                    if pin in self.bot.pins:
                        self.bot.send_admin_alert(
                            'Deleting invalid pin: {} [{}]'.format(
                                pin, self.bot.pins[pin]['content']))
                        delete_data('pins/%s/%s' % (self.bot.name, pin))
                        del self.bot.pins[pin]

            other_error = False

        elif response['message'].lower() == 'chat not found':
            logging.info('Chat not found: {}'.format(request['chat_id']))
            other_error = False

        if other_error:
            self.bot.send_alert(request)
            self.bot.send_alert(response)

    # THESE METHODS DO DIRECT ACTIONS #
    def get_message(self, chat_id, message_id):
        result = self.server_request('getMessage', {
            'chat_id': chat_id,
            'message_id': message_id
        },
                                     ignore_errors=True)
        if result:
            return self.convert_message(result)

        return None

    def delete_message(self, chat_id, message_id):
        return self.server_request('deleteMessages', {
            'chat_id': chat_id,
            'message_ids': [message_id],
            'revoke': True
        })

    def get_file(self, file_id, link=False):
        if self.bot.info.is_bot:
            params = {"file_id": file_id}
            result = self.api_request('getFile', params)
            if 'result' in result:
                if link:
                    return 'https://api.telegram.org/file/bot{}/{}'.format(
                        self.bot.config['bindings_token'],
                        result.result.file_path)
                else:
                    return download(
                        'https://api.telegram.org/file/bot{}/{}'.format(
                            self.bot.config['bindings_token'],
                            result.result.file_path))

        return None

    def check_invite_link(self, invite_link):
        if self.bot.info.is_bot:
            return None

        return self.server_request('checkChatInviteLink',
                                   {'invite_link': invite_link})

    def join_by_invite_link(self, invite_link):
        if self.bot.info.is_bot:
            return None

        return self.server_request('joinChatByInviteLink',
                                   {'invite_link': invite_link})

    def invite_conversation_member(self, conversation_id, user_id):
        if self.bot.info.is_bot:
            return False

        return self.server_request('addChatMember', {
            'chat_id': conversation_id,
            'user_id': user_id
        })

    def promote_conversation_member(self, conversation_id, user_id):
        return self.server_request(
            'setChatMemberStatus', {
                'chat_id': conversation_id,
                'user_id': user_id,
                'status': {
                    '@type': 'chatMemberStatusAdministrator'
                }
            })

    def kick_conversation_member(self, conversation_id, user_id):
        return self.server_request(
            'setChatMemberStatus', {
                'chat_id': conversation_id,
                'user_id': user_id,
                'status': {
                    '@type': 'chatMemberStatusLeft'
                }
            })

    def unban_conversation_member(self, conversation_id, user_id):
        return self.server_request(
            'setChatMemberStatus', {
                'chat_id': conversation_id,
                'user_id': user_id,
                'status': {
                    '@type': 'chatMemberStatusMember'
                }
            })

    def rename_conversation(self, conversation_id, title):
        return self.server_request('setChatTitle', {
            'chat_id': conversation_id,
            'title': title
        })

    def change_conversation_description(self, conversation_id, description):
        return self.server_request('setChatDescription', {
            'chat_id': conversation_id,
            'description': description
        })

    def change_conversation_photo(self, conversation_id, photo):
        return self.server_request('setChatPhoto', {
            'chat_id': conversation_id,
            'photo': photo
        })

    def conversation_info(self, conversation_id):
        return self.server_request('getChat', {'chat_id': conversation_id})

    def get_chat_administrators(self, conversation_id):
        result = self.server_request('getChatAdministrators',
                                     {'chat_id': conversation_id},
                                     ignore_errors=True)

        admins = []
        if result and 'administrators' in result:
            for member in result['administrators']:
                user = User(member['user_id'])

                request = self.client.get_user(user.id)
                request.wait()
                raw_user = request.update

                if raw_user:
                    user.is_bot = raw_user['type']['@type'] == 'userTypeBot'
                    if 'first_name' in raw_user:
                        user.first_name = str(raw_user['first_name'])
                    if 'last_name' in raw_user:
                        user.last_name = str(raw_user['last_name'])
                    if 'username' in raw_user:
                        user.username = str(raw_user['username'])

                admins.append(user)

        return admins