E.B*_*E.B 7 python-telegram-bot telegram-bot
当我向Telegram Bot发送消息时,它没有任何问题.
我想限制访问,以便我和只有我可以向它发送消息.
我怎样才能做到这一点?
小智 9
由于此问题与python-telegram-bot有关,因此以下信息与此有关:
在将处理程序添加到bot的调度程序中时,可以指定各种预构建的过滤器(在docs,github上了解更多信息),也可以创建自定义过滤器以过滤传入的更新。
为了限制对特定用户的访问,您需要Filters.user(username="@telegramusername")在初始化处理程序时添加,例如:
dispatcher.add_handler(CommandHandler("start", text_callback, Filters.user(username="@username")))
该处理程序将/start仅接受来自用户名username的命令@username。
您也可以指定用户ID而不是用户名,我强烈建议您使用它,因为后者不是恒定的,可以随时间更改。
根据python-telegram-bot代码片段,可以围绕处理程序构建一个简单的包装器:
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
Run Code Online (Sandbox Code Playgroud)
哪里conf['restricted_ids']可能是一个 id 列表,例如[11111111, 22222222].
所以用法看起来像这样:
@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))
Run Code Online (Sandbox Code Playgroud)
更新 | 对于函数和方法(DRY,python-telegram-bot 版本 12 及更高版本)
上面的解决方案不能用于类内部的方法(位置参数改变)。有一段时间,我刚刚为方法创建了一个额外的装饰器。然而,人们总是需要记住何时使用哪个装饰器。
在此解决方案之上,可以构建以下装饰器类:
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
Run Code Online (Sandbox Code Playgroud)
正如预期的那样,这适用于函数和方法。它并不完全干燥(参见评论),但至少是自包含的。
小智 5
与您的机器人开始对话,并向其发送消息。这将为包含对话消息和聊天 ID 的机器人更新进行排队。
要查看最近的更新,您可以调用 getUpdates 方法。这是通过向 URL https://api.telegram.org/bot $TOKEN/getUpdates 发出 HTTP GET 请求来完成的,其中 $TOKEN 是 BotFather 提供的令牌。就像是:
"chat":{
"id":12345,
"first_name":"Bob",
"last_name":"Jones",
"username":"bjones",
"type":"private"},
"date":1452933785,
"text":"Hi there, bot!"}}]}
Run Code Online (Sandbox Code Playgroud)
一旦你确定了你的聊天 ID,你就可以在你的机器人中编写一段代码,如下所示:
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)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7979 次 |
| 最近记录: |