21

当我向我的 Telegram Bot 发送消息时,它会毫无问题地响应。

我想限制访问权限,以便我并且只有我可以向它发送消息。

我怎样才能做到这一点?

4

5 回答 5

26

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.

于 2018-03-22T14:06:33.803 回答
11

按字段过滤消息update.message.from.id

于 2016-02-13T01:54:19.987 回答
8

根据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

哪里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))

更新 | 对于函数和方法(DRYpython-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

正如预期的那样,这适用于函数和方法。它并不完全干燥(参见评论),但至少是独立的。

于 2019-02-24T17:40:40.703 回答
4

与您的机器人开始对话,并向其发送消息。这将为包含您对话的消息和聊天 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!"}}]}

确定聊天 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)
于 2016-12-16T13:20:47.250 回答
0

过滤update.message.chat_id对我有用。为了找到您的聊天 ID,请向您的机器人发送消息并浏览至

https://api.telegram.org/bot$TOKEN/getUpdates

BotFather 提供的机器人令牌在哪里$TOKEN,如 fdicarlo 的回答中所述,您可以在其中找到 json 结构中的聊天 ID。

于 2019-01-08T09:11:50.897 回答