Before handlers¶
A before handler runs on every update, before routing. Return True to stop: no route is looked up and no handler runs.
from dj_telegram_bot.core.handlers import before_handler
@before_handler
def ignore_banned(ctx):
return ctx.user_id in BANNED_IDS
OR
from dj_telegram_bot.core.handlers import UpdateHandler, before_handler
class Guards(UpdateHandler):
@before_handler
def check(self):
return self.is_user_block()
- They run in registration order and stop at the first one that returns
True. - They run for every update type, even when no route would match.
ctxis anUpdateHandler, so every member is available whatever the update type. See Handler object.- The database user is loaded before they run, so
ctx.user_objcosts nothing extra. - Returning
FalseorNonelets the update continue. - Registering the same function twice is ignored.
Errors stop the whole update
If a before handler raises, the update is dropped and the error is only logged. Keep them small.
user_obj can raise or be None
ctx.user_obj raises ImproperlyConfigured if your user model has no user_id and step fields, and is None for someone who never started the bot. In a check that must work everywhere, use ctx.user_id. See User model.
Built-in checks are not automatic
The library gives you two checks, is_update_mode() and is_user_block(), but does not run them for you. Register the ones you need, as shown below.
Maintenance mode¶
ctx.is_update_mode() returns True while the bot is paused and sends the configured message.
@before_handler
def maintenance(ctx):
return ctx.is_update_mode()
Rules:
- It only applies in private chats. Updates from groups, channels and inline mode pass through, so the bot does not spam the message there.
- Superusers are never blocked, so you can test in production.
Turn it on from the admin (Bot update status: is_update and update_msg) or from code:
from dj_telegram_bot.contrib.services import BotStatusService
BotStatusService.set_updating(True)
Note
The status is cached for 60 seconds. set_updating() clears the cache immediately, but a change made in the admin can take up to a minute to apply.
Blocked users¶
Set is_active = False on a user to block them, then register:
@before_handler
def blocked(ctx):
return ctx.is_user_block(notify_user=True)
is_user_block() returns True for a blocked user in every chat type, so the bot stays silent in groups and inline mode too. It only replies when you pass notify_user=True and the update comes from a private chat. The default is notify_user=False: the user is ignored without a reply.
The reply is the message with step block from the admin (Messages & keyboards), or the built-in text Access denied. Your account is currently blocked.
This check reads is_active on your user model. See User model.
Use both checks
@before_handler
def access(ctx):
return ctx.is_update_mode() or ctx.is_user_block(notify_user=True)
Channel membership for every update¶
@sponsor_required guards one handler. To require channel membership for every update, use the guard in a before handler.
from dj_telegram_bot.core.guards import SponsorGuard
@before_handler
def sponsor(ctx):
return not SponsorGuard(ctx).ensure_joined()
Note the not
ensure_joined() returns True when the user may continue, while a before handler returns True to stop.
The same rules apply: groups and channel posts are skipped. You do not also need @sponsor_required on the handlers.
Order matters¶
Tip
Put cheap checks first and register the ones with side effects (like sending a message) after the checks that should win. Registration order follows module import order.