【问题标题】:How can I send message to user, knowing his username?如何在知道用户名的情况下向用户发送消息?
【发布时间】:2019-10-11 09:07:27
【问题描述】:

我使用python-telegram-bot 向用户发送消息(在私人消息中)。在documentation 中写道,该机器人可以向用户发送消息,知道他的channel_idusername

但是,通过 chat_id 消息正在发送,但通过用户名我收到错误 telegram.error.Bad Request: Chat not found `

bot.send_message(chat_id='@username', text)

【问题讨论】:

  • 没有测试,但正如我从文档中看到的那样:“chat_id (int | str) – 目标聊天的唯一标识符或目标频道的用户名(格式为 @channelusername)。” - 您可以按名称向频道发送消息,而不是向用户发送消息
  • 但是为什么我可以通过chat_id与用户一起向用户发送private message,而不是他的username

标签: python telegram telegram-bot python-telegram-bot


【解决方案1】:

这是我的方法

def save_user_id(bot, update):
    username = get_username(update)
    tg_user, created = YourModel.objects.get_or_create(username=username,
                                                       first_name=update.message.from_user.first_name,
                                                       telegram_user_id=update.message.from_user.id)

所以稍后您可以使用用户名发送消息:

user = YourModel.objects.get(username='@username')
bot.send_message(chat_id=user.telegram_user_id, text='your text')

忘记添加get_username func。很简单:

def get_username(update):
    username = update.message.from_user.username

但我建议根据您的需要扩展它,因为有些用户还没有设置他们的用户名

【讨论】:

  • 抱歉,刚刚添加
  • 这是否需要用户先写入机器人?
  • 是的。用户需要启动机器人。否则你不会得到用户的chat_id。这是电报限制
  • 谢谢。我就知道。但我想,也许这可以以某种方式被规避(
【解决方案2】:

这里引用了

chat_id (:obj:int | :obj:str):目标的唯一标识符 聊天或目标频道的用户名(格式为 @频道用户名)。

    @log
    def send_message(self,
                     chat_id,
                     text,
                     parse_mode=None,
                     disable_web_page_preview=None,
                     disable_notification=False,
                     reply_to_message_id=None,
                     reply_markup=None,
                     timeout=None,
                     **kwargs):
        """Use this method to send text messages.
        Args:
            chat_id (:obj:`int` | :obj:`str`): Unique identifier for the target chat or username
                of the target channel (in the format @channelusername).
            text (:obj:`str`): Text of the message to be sent. Max 4096 characters. Also found as
                :attr:`telegram.constants.MAX_MESSAGE_LENGTH`.
            parse_mode (:obj:`str`): Send Markdown or HTML, if you want Telegram apps to show bold,
                italic, fixed-width text or inline URLs in your bot's message. See the constants in
                :class:`telegram.ParseMode` for the available modes.
            disable_web_page_preview (:obj:`bool`, optional): Disables link previews for links in
                this message.
            disable_notification (:obj:`bool`, optional): Sends the message silently. Users will
                receive a notification with no sound.
            reply_to_message_id (:obj:`int`, optional): If the message is a reply, ID of the
                original message.
            reply_markup (:class:`telegram.ReplyMarkup`, optional): Additional interface options.
                A JSON-serialized object for an inline keyboard, custom reply keyboard,
                instructions to remove reply keyboard or to force a reply from the user.
            timeout (:obj:`int` | :obj:`float`, optional): If this value is specified, use it as
                the read timeout from the server (instead of the one specified during creation of
                the connection pool).
            **kwargs (:obj:`dict`): Arbitrary keyword arguments.
        Returns:
            :class:`telegram.Message`: On success, the sent message is returned.
        Raises:
            :class:`telegram.TelegramError`
        """
        url = '{0}/sendMessage'.format(self.base_url)

        data = {'chat_id': chat_id, 'text': text}

        if parse_mode:
            data['parse_mode'] = parse_mode
        if disable_web_page_preview:
            data['disable_web_page_preview'] = disable_web_page_preview

        return self._message(url, data, disable_notification=disable_notification,
                             reply_to_message_id=reply_to_message_id, reply_markup=reply_markup,
                             timeout=timeout, **kwargs)

您应该在这里发送频道名称而不是用户的用户名。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-07
    • 2017-05-10
    • 2021-07-01
    • 2018-07-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多