@Aleksander_Spb

Почему при создании кнопки InlineKeyboardButton с атрибутом url для ссылки вида mailto: добавляется префикс https://?

Пишу телеграм-бота с telebot. На последнем этапе нужно создать кнопку со ссылкой вида "mailto:" по нажатию на которую будет осуществляться переход в почтовый клиент пользователя и будет создаваться письмо определенного формата.
Проблема в том, что при создании кнопки InlineKeyboardButton с атрибутом url, для ссылки вида "mailto:" добавляется префикс "https://", который автоматом делает ссылку нерабочей (почтовый клиент открываться не будет).

По ряду причин по-другому работу с почтой реализовать не могу, поэтому нужно найти способ обойти добавления этого префикса к ссылке.

Сам код ниже:

spoiler
# Создаем функцию для формирования письма на почту магазина и открытия его в почтовом клиенте
def send_email(director_id):
  global director_data # используем глобальную переменную
  director = director_data[str(director_id)] # получаем данные директора по его id
  user_id = director['user_id'] # получаем id пользователя
  from_store = director['from_store'] # получаем название магазина из которого перемещаем
  to_store = director['to_store'] # получаем название магазина куда перемещаем
  items = director['items'] # получаем список позиций и их количество
  director_email = director['director_email'] # получаем адрес e-mail магазина
  
  # создаем пустую строку
  body_text = ''
  # добавляем приветствие и информацию о перемещении
  body_text += f'Здравствуйте! Пользователь с номером {user_id} хочет сделать перемещение из магазина {from_store} в магазин {to_store}. Вот список позиций и их количество:\n'
  # добавляем каждую позицию и ее количество
  for item in items: # для каждой позиции
    body_text += f'{item[0]} - {item[1]}\n' # добавляем название и количество в тело письма
  # добавляем информацию о согласовании
  body_text += 'Этот запрос был согласован директором дивизиона.'

  # Формируем URL-адрес для создания письма в почтовом клиенте с кодировкой русских букв
  subject = f'Перемещение из бутика {from_store} в бутик {to_store} от {datetime.date.today().strftime("%d %B %Y")}'
  subject = urllib.parse.quote(subject)
  body_text = urllib.parse.quote(body_text)
  
  url = f'mailto:{director_email}?subject={subject}&body={body_text}'

  # Создаем разметку с кнопкой
  markup = telebot.types.InlineKeyboardMarkup()
  button = telebot.types.InlineKeyboardButton(text="Создать письмо", url=url) # Используем параметр url 
  markup.add(button)

  # Отправляем сообщение с разметкой
  bot.send_message(director_id, text="Нажмите на кнопку ниже, чтобы создать письмо в вашем почтовом клиенте.", reply_markup=markup)
  • Вопрос задан
  • 78 просмотров
Решения вопроса 1
@Aleksander_Spb Автор вопроса
По итогу решения, кроме как использовать сокращатель ссылок, я не нашел.
С сокращателями тоже оказалось не все так просто, потому как половина сервисов не понимает ссылки "mailto". (Например, Яндекс Кликер).

Поэтому воспользовался отличным сервисом от портала involta.ru. Спасибо авторам за отличный инструмент!
Пришлось также повозиться с кириллицей и амперсандом перед body - при передачи запроса из кода, сервис не понимал, что это часть ссылки, а не разделитель параметров самого сервиса.
Экранирование с помощью модуля urllib вызывало ошибку 500 на сервере, поэтому пришлось экранировать ссылку с помощью модуля re.

Итоговое решение выглядит следующим образом:

spoiler
def send_email(director_id):
  global director_data # используем глобальную переменную
  director = director_data[str(director_id)] # получаем данные директора по его id
  user_id = director['user_id'] # получаем id пользователя
  from_store = director['from_store'] # получаем название магазина из которого перемещаем
  to_store = director['to_store'] # получаем название магазина куда перемещаем
  items = director['items'] # получаем список позиций и их количество
  director_email = director['director_email'] # получаем адрес e-mail магазина
  
  # создаем пустую строку
  body_text = ''
  # добавляем приветствие и информацию о перемещении
  body_text += f'Коллеги, добрый день!\n\n Мной было согласовано перемещение из бутика {from_store} в бутик {to_store} следующих позиций:\n\n'
  # добавляем каждую позицию и ее количество
  for item in items: # для каждой позиции
    body_text += f'{item[0]} - {item[1]} шт.\n' # добавляем название и количество в тело письма
  # добавляем информацию о согласовании
  body_text += f'\n\nЗапрос на согласование отправлял пользователь с id:{user_id}\n\nБлагодарю и отличных продаж!\n\n'
  
  # Формируем URL-адрес для создания письма в почтовом клиенте с кодировкой русских букв
  subject = f'Перемещение из бутика {from_store} в бутик {to_store} от {datetime.date.today().strftime("%d %B %Y")}'
  subject = urllib.parse.quote(subject)
  body_text = urllib.parse.quote(body_text)
  
  url = f'mailto:{director_email}?subject={subject}&body={body_text}'
  print(url)
  escaped_link = re.sub(r'([^\w.-])', lambda m: '%{:02X}'.format(ord(m.group(1))), url)

  # Сокращаем URL-адрес с помощью сервиса https://involta.ru/
  response = requests.get("https://involta.ru/tools/short-links/api/?api=ВАШ_ТОКЕН&url="+ escaped_link)
  print(response)
  print(response.text)
  data = response.json() # преобразуем ответ в JSON-формат
  short_url = data['data']['shortUrl'][0]['link'] # берем первую ссылку из списка

  # создаем клавиатуру
  keyboard = telebot.types.InlineKeyboardMarkup()
  # создаем кнопку с текстом " НАЖМИ МЕНЯ! " и ссылкой на short_url
  button = telebot.types.InlineKeyboardButton(text=" НАЖМИ МЕНЯ! ", url=short_url)
  # добавляем кнопку на клавиатуру
  keyboard.add(button)
  # отправляем сообщение директору с текстом "Нажмите на кнопку ниже, чтобы создать письмо в вашем почтовом клиенте." и клавиатурой
  bot.send_message(director_id, text="Нажмите на кнопку ниже, чтобы создать письмо в вашем почтовом клиенте.", reply_markup=keyboard)
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
RimMirK
@RimMirK
Вроде человек. Вроде учусь. Вроде пайтону
если говорить просто, то потому-что телеграм открывает сслылку, а не команду.
Надо искать другое решение. Например, создать простой сайт который будет перекидывать на почту.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы