mirror of
				https://github.com/LonamiWebs/Telethon.git
				synced 2025-10-31 07:57:38 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			334 lines
		
	
	
		
			9.9 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
			
		
		
	
	
			334 lines
		
	
	
		
			9.9 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
| .. _botapi:
 | |
| 
 | |
| =======================
 | |
| HTTP Bot API vs MTProto
 | |
| =======================
 | |
| 
 | |
| 
 | |
| Telethon is more than just another viable alternative when developing bots
 | |
| for Telegram. If you haven't decided which wrapper library for bots to use
 | |
| yet, using Telethon from the beginning may save you some headaches later.
 | |
| 
 | |
| .. contents::
 | |
| 
 | |
| 
 | |
| What is Bot API?
 | |
| ================
 | |
| 
 | |
| The `Telegram Bot API`_, also known as HTTP Bot API and from now on referred
 | |
| to as simply "Bot API" is Telegram's official way for developers to control
 | |
| their own Telegram bots. Quoting their main page:
 | |
| 
 | |
|     The Bot API is an HTTP-based interface created for developers keen on
 | |
|     building bots for Telegram.
 | |
| 
 | |
|     To learn how to create and set up a bot, please consult our
 | |
|     `Introduction to Bots`_ and `Bot FAQ`_.
 | |
| 
 | |
| Bot API is simply an HTTP endpoint which translates your requests to it into
 | |
| MTProto calls through tdlib_, their bot backend.
 | |
| 
 | |
| 
 | |
| What is MTProto?
 | |
| ================
 | |
| 
 | |
| MTProto_ is Telegram's own protocol to communicate with their API when you
 | |
| connect to their servers.
 | |
| 
 | |
| Telethon is an alternative MTProto-based backend written entirely in Python
 | |
| and much easier to setup and use.
 | |
| 
 | |
| Both official applications and third-party clients (like your own
 | |
| applications) logged in as either user or bots **can use MTProto** to
 | |
| communicate directly with Telegram's API (which is not the HTTP bot API).
 | |
| 
 | |
| When we talk about MTProto, we often mean "MTProto-based clients".
 | |
| 
 | |
| 
 | |
| Advantages of MTProto over Bot API
 | |
| ==================================
 | |
| 
 | |
| MTProto clients (like Telethon) connect directly to Telegram's servers,
 | |
| which means there is no HTTP connection, no "polling" or "web hooks". This
 | |
| means **less overhead**, since the protocol used between you and the server
 | |
| is much more compact than HTTP requests with responses in wasteful JSON.
 | |
| 
 | |
| Since there is a direct connection to Telegram's servers, even if their
 | |
| Bot API endpoint is down, you can still have connection to Telegram directly.
 | |
| 
 | |
| Using a MTProto client, you are also not limited to the public API that
 | |
| they expose, and instead, **you have full control** of what your bot can do.
 | |
| Telethon offers you all the power with often **much easier usage** than any
 | |
| of the available Python Bot API wrappers.
 | |
| 
 | |
| If your application ever needs user features because bots cannot do certain
 | |
| things, you will be able to easily login as a user and even keep your bot
 | |
| without having to learn a new library.
 | |
| 
 | |
| If less overhead and full control didn't convince you to use Telethon yet,
 | |
| check out the wiki page `MTProto vs HTTP Bot API`_ with a more exhaustive
 | |
| and up-to-date list of differences.
 | |
| 
 | |
| 
 | |
| Migrating from Bot API to Telethon
 | |
| ==================================
 | |
| 
 | |
| It doesn't matter if you wrote your bot with requests_ and you were
 | |
| making API requests manually, or if you used a wrapper library like
 | |
| python-telegram-bot_ or pyTelegramBotAPI_. It's never too late to
 | |
| migrate to Telethon!
 | |
| 
 | |
| If you were using an asynchronous library like aiohttp_ or a wrapper like
 | |
| aiogram_ or dumbot_, it will be even easier, because Telethon is also an
 | |
| asynchronous library.
 | |
| 
 | |
| Next, we will see some examples from the most popular libraries.
 | |
| 
 | |
| 
 | |
| Migrating from python-telegram-bot
 | |
| ----------------------------------
 | |
| 
 | |
| Let's take their `echobot2.py`_ example and shorten it a bit:
 | |
| 
 | |
| .. code-block:: python
 | |
| 
 | |
|     from telegram.ext import Updater, CommandHandler, MessageHandler, Filters
 | |
| 
 | |
|     def start(update, context):
 | |
|         """Send a message when the command /start is issued."""
 | |
|         update.message.reply_text('Hi!')
 | |
| 
 | |
|     def echo(update, context):
 | |
|         """Echo the user message."""
 | |
|         update.message.reply_text(update.message.text)
 | |
| 
 | |
|     def main():
 | |
|         """Start the bot."""
 | |
|         updater = Updater("TOKEN")
 | |
|         dp = updater.dispatcher
 | |
|         dp.add_handler(CommandHandler("start", start))
 | |
|         dp.add_handler(MessageHandler(Filters.text, echo))
 | |
| 
 | |
|         updater.start_polling()
 | |
| 
 | |
|         updater.idle()
 | |
| 
 | |
|     if __name__ == '__main__':
 | |
|         main()
 | |
| 
 | |
| 
 | |
| After using Telethon:
 | |
| 
 | |
| .. code-block:: python
 | |
| 
 | |
|     from telethon import TelegramClient, events
 | |
| 
 | |
|     bot = TelegramClient('bot', 11111, 'a1b2c3d4').start(bot_token='TOKEN')
 | |
| 
 | |
|     @bot.on(events.NewMessage(pattern='/start'))
 | |
|     async def start(event):
 | |
|         """Send a message when the command /start is issued."""
 | |
|         await event.respond('Hi!')
 | |
|         raise events.StopPropagation
 | |
| 
 | |
|     @bot.on(events.NewMessage)
 | |
|     async def echo(event):
 | |
|         """Echo the user message."""
 | |
|         await event.respond(event.text)
 | |
| 
 | |
|     def main():
 | |
|         """Start the bot."""
 | |
|         bot.run_until_disconnected()
 | |
| 
 | |
|     if __name__ == '__main__':
 | |
|         main()
 | |
| 
 | |
| Key differences:
 | |
| 
 | |
| * The recommended way to do it imports less things.
 | |
| * All handlers trigger by default, so we need ``events.StopPropagation``.
 | |
| * Adding handlers, responding and running is a lot less verbose.
 | |
| * Telethon needs ``async def`` and ``await``.
 | |
| * The ``bot`` isn't hidden away by ``Updater`` or ``Dispatcher``.
 | |
| 
 | |
| 
 | |
| Migrating from pyTelegramBotAPI
 | |
| -------------------------------
 | |
| 
 | |
| Let's show another echobot from their README:
 | |
| 
 | |
| .. code-block:: python
 | |
| 
 | |
|     import telebot
 | |
| 
 | |
|     bot = telebot.TeleBot("TOKEN")
 | |
| 
 | |
|     @bot.message_handler(commands=['start'])
 | |
|     def send_welcome(message):
 | |
|         bot.reply_to(message, "Howdy, how are you doing?")
 | |
| 
 | |
|     @bot.message_handler(func=lambda m: True)
 | |
|     def echo_all(message):
 | |
|         bot.reply_to(message, message.text)
 | |
| 
 | |
|     bot.polling()
 | |
| 
 | |
| Now we rewrite it to use Telethon:
 | |
| 
 | |
| .. code-block:: python
 | |
| 
 | |
|     from telethon import TelegramClient, events
 | |
| 
 | |
|     bot = TelegramClient('bot', 11111, 'a1b2c3d4').start(bot_token='TOKEN')
 | |
| 
 | |
|     @bot.on(events.NewMessage(pattern='/start'))
 | |
|     async def send_welcome(event):
 | |
|         await event.reply('Howdy, how are you doing?')
 | |
| 
 | |
|     @bot.on(events.NewMessage)
 | |
|     async def echo_all(event):
 | |
|         await event.reply(event.text)
 | |
| 
 | |
|     bot.run_until_disconnected()
 | |
| 
 | |
| Key differences:
 | |
| 
 | |
| * Instead of doing ``bot.reply_to(message)``, we can do ``event.reply``.
 | |
|   Note that the ``event`` behaves just like their ``message``.
 | |
| * Telethon also supports ``func=lambda m: True``, but it's not necessary.
 | |
| 
 | |
| 
 | |
| Migrating from aiogram
 | |
| ----------------------
 | |
| 
 | |
| From their GitHub:
 | |
| 
 | |
| .. code-block:: python
 | |
| 
 | |
|     from aiogram import Bot, Dispatcher, executor, types
 | |
| 
 | |
|     API_TOKEN = 'BOT TOKEN HERE'
 | |
| 
 | |
|     # Initialize bot and dispatcher
 | |
|     bot = Bot(token=API_TOKEN)
 | |
|     dp = Dispatcher(bot)
 | |
| 
 | |
|     @dp.message_handler(commands=['start'])
 | |
|     async def send_welcome(message: types.Message):
 | |
|         """
 | |
|         This handler will be called when client send `/start` command.
 | |
|         """
 | |
|         await message.reply("Hi!\nI'm EchoBot!\nPowered by aiogram.")
 | |
| 
 | |
|     @dp.message_handler(regexp='(^cat[s]?$|puss)')
 | |
|     async def cats(message: types.Message):
 | |
|         with open('data/cats.jpg', 'rb') as photo:
 | |
|             await bot.send_photo(message.chat.id, photo, caption='Cats is here 😺',
 | |
|                                  reply_to_message_id=message.message_id)
 | |
| 
 | |
|     @dp.message_handler()
 | |
|     async def echo(message: types.Message):
 | |
|         await bot.send_message(message.chat.id, message.text)
 | |
| 
 | |
|     if __name__ == '__main__':
 | |
|         executor.start_polling(dp, skip_updates=True)
 | |
| 
 | |
| 
 | |
| After rewrite:
 | |
| 
 | |
| .. code-block:: python
 | |
| 
 | |
|     from telethon import TelegramClient, events
 | |
| 
 | |
|     # Initialize bot and... just the bot!
 | |
|     bot = TelegramClient('bot', 11111, 'a1b2c3d4').start(bot_token='TOKEN')
 | |
| 
 | |
|     @bot.on(events.NewMessage(pattern='/start'))
 | |
|     async def send_welcome(event):
 | |
|         await event.reply('Howdy, how are you doing?')
 | |
| 
 | |
|     @bot.on(events.NewMessage(pattern='(^cat[s]?$|puss)'))
 | |
|     async def cats(event):
 | |
|         await event.reply('Cats is here 😺', file='data/cats.jpg')
 | |
| 
 | |
|     @bot.on(events.NewMessage)
 | |
|     async def echo_all(event):
 | |
|         await event.reply(event.text)
 | |
| 
 | |
|     if __name__ == '__main__':
 | |
|         bot.run_until_disconnected()
 | |
| 
 | |
| 
 | |
| Key differences:
 | |
| 
 | |
| * Telethon offers convenience methods to avoid retyping
 | |
|   ``bot.send_photo(message.chat.id, ...)`` all the time,
 | |
|   and instead let you type ``event.reply``.
 | |
| * Sending files is **a lot** easier. The methods for sending
 | |
|   photos, documents, audios, etc. are all the same!
 | |
| 
 | |
| Migrating from dumbot
 | |
| ---------------------
 | |
| 
 | |
| Showcasing their subclassing example:
 | |
| 
 | |
| .. code-block:: python
 | |
| 
 | |
|     from dumbot import Bot
 | |
| 
 | |
|     class Subbot(Bot):
 | |
|         async def init(self):
 | |
|             self.me = await self.getMe()
 | |
| 
 | |
|         async def on_update(self, update):
 | |
|             await self.sendMessage(
 | |
|                 chat_id=update.message.chat.id,
 | |
|                 text='i am {}'.format(self.me.username)
 | |
|             )
 | |
| 
 | |
|     Subbot(token).run()
 | |
| 
 | |
| After rewriting:
 | |
| 
 | |
| .. code-block:: python
 | |
| 
 | |
|     from telethon import TelegramClient, events
 | |
| 
 | |
|     class Subbot(TelegramClient):
 | |
|         def __init__(self, *a, **kw):
 | |
|             await super().__init__(*a, **kw)
 | |
|             self.add_event_handler(self.on_update, events.NewMessage)
 | |
| 
 | |
|         async def connect():
 | |
|             await super().connect()
 | |
|             self.me = await self.get_me()
 | |
| 
 | |
|         async def on_update(event):
 | |
|             await event.reply('i am {}'.format(self.me.username))
 | |
| 
 | |
|     bot = Subbot('bot', 11111, 'a1b2c3d4').start(bot_token='TOKEN')
 | |
|     bot.run_until_disconnected()
 | |
| 
 | |
| 
 | |
| Key differences:
 | |
| 
 | |
| * Telethon method names are ``snake_case``.
 | |
| * dumbot does not offer friendly methods like ``update.reply``.
 | |
| * Telethon does not have an implicit ``on_update`` handler, so
 | |
|   we need to manually register one.
 | |
| 
 | |
| 
 | |
| .. _Telegram Bot API: https://core.telegram.org/bots/api
 | |
| .. _Introduction to Bots: https://core.telegram.org/bots
 | |
| .. _Bot FAQ: https://core.telegram.org/bots/faq
 | |
| .. _tdlib: https://core.telegram.org/tdlib
 | |
| .. _MTProto: https://core.telegram.org/mtproto
 | |
| .. _MTProto vs HTTP Bot API: https://github.com/LonamiWebs/Telethon/wiki/MTProto-vs-HTTP-Bot-API
 | |
| .. _requests: https://pypi.org/project/requests/
 | |
| .. _python-telegram-bot: https://python-telegram-bot.readthedocs.io
 | |
| .. _pyTelegramBotAPI: https://github.com/eternnoir/pyTelegramBotAPI
 | |
| .. _aiohttp: https://docs.aiohttp.org/en/stable
 | |
| .. _aiogram: https://aiogram.readthedocs.io
 | |
| .. _dumbot: https://github.com/Lonami/dumbot
 | |
| .. _echobot2.py: https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/echobot2.py
 |