When I send a message to my Telegram Bot, it responses with no problems.
I wanna limit the access such that me and only me can send message to it.
How can I do that?
When I send a message to my Telegram Bot, it responses with no problems.
I wanna limit the access such that me and only me can send message to it.
How can I do that?
As this question is related to python-telegram-bot, information below is related to it:
When you add handlers to your bot's dispatcher, you can specify various pre-built filters (read more at docs, github) or you can create custom ones in order to filter incoming updates.
To limit access to a specific user, you need to add Filters.user(username="@telegramusername")
when initializing handler, e.g.:
dispatcher.add_handler(CommandHandler("start", text_callback, Filters.user(username="@username")))
This handler will accept /start
command only from user with username @username
.
You can also specify user-id instead of username, which I would highly recommend, as latter is non-constant and can be changed over time.
Based on the python-telegram-bot
code snippets, one can build a simple wrapper around the handler:
def restricted(func):
"""Restrict usage of func to allowed users only and replies if necessary"""
@wraps(func)
def wrapped(bot, update, *args, **kwargs):
user_id = update.effective_user.id
if user_id not in conf['restricted_ids']:
print("WARNING: Unauthorized access denied for {}.".format(user_id))
update.message.reply_text('User disallowed.')
return # quit function
return func(bot, update, *args, **kwargs)
return wrapped
where conf['restricted_ids']
might be an id list, e.g. [11111111, 22222222]
.
So the usage would look like this:
@restricted
def bot_start(bot, update):
"""Send a message when the command /start is issued"""
update.message.reply_text('Hi! This is {} speaking.'.format(bot.username))
Update | for functions and methods (DRY, python-telegram-bot version 12 and above)
The solution above cannot be used on methods inside classes (positional arguments change). For a while, I had just created an additional decorator for methods. However one would always need to keep in mind which decorator to use when.
Building on top of this solution, the following decorator class can be built:
class restricted(object):
"""
Decorator class used to restrict usage of commands.
Sends a "disallowed" reply if necessary. Works on functions and methods.
"""
def __init__(self, func):
self._func = func
self._obj = None
self._wrapped = None
def __call__(self, *args, **kwargs):
if not self._wrapped:
if self._obj:
self._wrapped = self._wrap_method(self._func)
self._wrapped = partial(self._wrapped, self._obj)
else:
self._wrapped = self._wrap_function(self._func)
return self._wrapped(*args, **kwargs)
def __get__(self, obj, type_=None):
self._obj = obj
return self
def _wrap_method(self, method): # Wrapper called in case of a method
@wraps(method)
def inner(self, *args, **kwargs): # `self` is the *inner* class' `self` here
user_id = args[0].effective_user.id # args[0]: update
if user_id not in cfg.RESTRICTED_IDS:
print(f'Unauthorized access denied on {method.__name__} ' \
f'for {user_id} : {args[0].message.chat.username}.')
args[0].message.reply_text('User disallowed.')
return None # quit handling command
return method(self, *args, **kwargs)
return inner
def _wrap_function(self, function): # Wrapper called in case of a function
@wraps(function)
def inner(*args, **kwargs): # `self` would be the *restricted* class' `self` here
user_id = args[0].effective_user.id # args[0]: update
if user_id not in cfg.RESTRICTED_IDS:
print(f'Unauthorized access denied on {function.__name__} ' \
f'for {user_id} : {args[0].message.chat.username}.')
args[0].message.reply_text('User disallowed.')
return None # quit handling command
return function(*args, **kwargs)
return inner
This works then, as expected, on functions and methods. It's not entirely DRY (cf. comments), but at least self-contained.
Start a conversation with your bot, and send it a message. This will queue up an updates for the bot containing the message and the chat ID for your conversation.
To view recent updates, you call the getUpdates method. This is done by making a HTTP GET request to the URL https://api.telegram.org/bot$TOKEN/getUpdates Where $TOKEN is the token provided by the BotFather. Something like:
"chat":{
"id":12345,
"first_name":"Bob",
"last_name":"Jones",
"username":"bjones",
"type":"private"},
"date":1452933785,
"text":"Hi there, bot!"}}]}
Once you determined your chat id you can write a piece of code in your bot like:
id_a = [111111,2222222,3333333,4444444,5555555]
def handle(msg):
chat_id = msg['chat']['id']
command = msg['text']
sender = msg['from']['id']
if sender in id_a:
[...]
else:
bot.sendMessage(chat_id, 'Forbidden access!')
bot.sendMessage(chat_id, sender)
I ran into this question myself so I thought I might say how I did it with Python's python-telegram-bot. So, with the new release (Version 20) [some classes/functions have changed] you could do something such as:
async def restrict(update: Update, context: ContextTypes.DEFAULT_TYPE):
await context.bot.send_message(
chat_id=update.effective_chat.id,
text="There is no bot in Ba Sing Se."
)
# Creating the Application
application = ApplicationBuilder().token(TOKEN).build()
# Restrict bot to the specified user_id
restrict_handler = MessageHandler(~ filters.User(USER_ID), restrict)
application.add_handler(restrict_handler)
See the github tutorial for the rest of the scaffolding, but this puts the restricted handlder first using a filter to effectively cut off access to any user who doesn't match the USER_ID you feed to it, and because it's first, all other handlers don't hit.
The other answers work well if you want to specifically restrict certain actions, but this is good for a blanket restriction. You could also just use a filter inside each action you want restricted.
in my case this idea helped, actually logic is pretty easy,maybe you will find it useful. I used a telebot module:
# list with an id's, type int
prmssn=[
12345678,87654321
]
@bot.message_handler(content_types=['text'])
def handle_text(message):
# get the user's id of a last message
u_id=message.chat.id
# you can use print to find out an id's of those who're trying to write to your bot
print(u_id)
# we use a permission list to compare id, if id is in the perm. list bot is going to answer, otherwise it keeps silence
if u_id in prmssn:
# get user's message
u_query=message.text.strip()
# echo it back
bot.send_message(message.chat.id, u_query)
Filtering by update.message.chat_id
works for me.
In order to find your chat id, send a message to your bot and browse to
https://api.telegram.org/bot$TOKEN/getUpdates
where $TOKEN
is the bot token as provided by BotFather, as mentioned in the answer by fdicarlo, where you can find the chat id in the json structure.
© 2022 - 2025 — McMap. All rights reserved.
from functools import partial, wraps
– Dockery