Skip to main content

Simple, easily extendable Telegram bot framework

Project description

A very minimal framework that implements a Telegram bot trigger-response loop plus some endpoint utilities. Can (should) be extended depending on needs.

Why yet another Python Telegram bot framework?

This framework was born from my need to have a simple, easily-maintainable, async-first, server-independent solution to develop Telegram bots. It doesn’t attempt to implement the full API, but it offers a handy way to perform requests while leaving the developer free to do what he wants with the response thus not incurring in extra parsing overhead.
The development is driven by my needs or (eventually) feature requests, a list of what is missing can be found at the bottom of this readme.
What set this bot apart from the “competition” is:
  • method chaining to generate requests, easier on IDEs code completion and more readable than long 10-params functions
  • fully async request handling for high responsiveness
  • doesn’t depend on any other framework to handle the networking side
  • simple to understand, easy to maintain
  • caches media files ids with barely any effort (and if you backup the cache in a db you can make it persistent)

Quickstart

pip install ubot uvicorn

import asyncio
import json

import uvicorn

from ubot import Bot, Trigger
from ubot.endpoints import SendMessage

loop = asyncio.get_event_loop()
bot = Bot('token', loop=loop)

# add a simple trigger
@bot.trigger
class CustomTrigger(Trigger):
    async def match(self, update, bot):
        return True

    async def trigger(self, update, bot):
        req = SendMessage(YOUR_USER_ID, 'test').serialize()
        await bot.api_request(req)

# prepare the ASGI class to push updates into the bot
class App:
    def __init__(self, scope):
        assert scope['type'] == 'http'
        self.scope = scope

    async def __call__(self, receive, send):
        if self.scope['path'] == WEBHOOK_PATH and self.scope['method'] == 'POST':

            body = []
            more_body = True

            while more_body:
                message = await receive()
                body.append(message.get('body', b'').decode('utf-8'))
                more_body = message.get('more_body', False)

            body = ''.join(body)
            body = json.loads(body)
            bot.push_update(body)

        await send({
            'type': 'http.response.start',
            'status': 204,  # noqa: S001
            'headers': [
                [b'content-type', b'text/plain'],
            ]
        })
        await send({
            'type': 'http.response.body'
        })

# remoe the loop and http parameters if you're not using PyPy
server = uvicorn.Server(uvicorn.Config(
    app=App, host='0.0.0.0', port=8080, loop='asyncio', http='h11'))

# start the server and the bot
loop.run_until_complete(asyncio.gather(
     bot.start(),
     server.serve(),
     loop=loop
 ))

Reading file metadata

Ubot supports reading metadata through a wrapper to libmediainfo called libmediainfo_cffi. If you need this functionality you must install this library with pip install ubot[mediainfo].

Resources

TODO: documentation, unit tests, support sticker, passport, payments, games

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Files for ubot, version 7.0.0
Filename, size File type Python version Upload date Hashes
Filename, size ubot-7.0.0-py3-none-any.whl (25.4 kB) File type Wheel Python version py3 Upload date Hashes View
Filename, size ubot-7.0.0.tar.gz (17.3 kB) File type Source Python version None Upload date Hashes View

Supported by

Pingdom Pingdom Monitoring Google Google Object Storage and Download Analytics Sentry Sentry Error logging AWS AWS Cloud computing DataDog DataDog Monitoring Fastly Fastly CDN DigiCert DigiCert EV certificate StatusPage StatusPage Status page