1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336
|
.. _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.
Configuration of your bot, such as its available commands and auto-completion,
is configured through `@BotFather <https://t.me/BotFather>`_.
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 `echobot.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 & ~Filters.command, 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 fewer 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):
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
.. _echobot.py: https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples/echobot.py
|