Пора делать нормальных телеграм-ботов #3
Очень неочевидные вещи, о которых никогда не приходится задумываться, пока не сталкиваешься с реальными проблемами использования ботов (иногда очень злонамеренного и неправильного).
Предыдущие части:
1. Язык вашего бота — его враг (и ваш)
Не в прямом смысле, конечно, но то, что отправляет бот, является сообщением, какой-то информацией, которая может вредить, быть запрещённой в некоторых странах и т. п. Будьте аккуратны при отправке, например, сгенерированных текстов ChatGPT или подобных решений, поскольку любой получатель сообщения может отправить жалобу на сообщение, и никакие дисклеймеры о том, что сообщение не отражает официальную позицию или мнение разработчика и блаблабла, не помогут. Особенно будьте аккуратны при рассылке рекламы. Если достаточно пользователей пожалуются на спам, ваш бот будет удалён.
Что происходит при удалении бота из-за жалоб? Он просто перестаёт существовать. Ни в @BotFather, ни в списке контактов вы его не увидите.
Что делать? Попробуйте написать в @BotSupport, вдруг ответят.
2. Нежданные сообщения — зло
Да, вопрос «а как же тогда зарабатывать на боте?» очевиден. Зарабатывайте, но не докучайте неактивным пользователям. Например, лично меня не устраивает, что бот будет находиться в блок-листе. Я этот раздел использую для сохранения ботов, которые могут впоследствии понадобиться (да, немножко странно, но телеграм вообще очень плохой мессенджер, с какой стороны ни посмотри, тоже об этом как-нибудь напишу), несмотря на то, что блокировка бота — единственный официальный способ не получать от него сообщения.
Как не докучать неактивным пользователям? Отправляйте сообщения только тем, кто пользовался ботом последние N часов/дней (в зависимости от масштабов бота), при этом нельзя считать активностью сообщение о том, что пользователь заблокировал или разблокировал бота.
Но лучше всегда спрашивать, готов ли пользователь на рассылку новостей, рекламы и прочего. Дайте ему возможность исчезнуть из вашей базы. Пока это никак, к сожалению, не регулируется, и вы можете хранить всё, что пожелаете, пока об этом не узнают. А об этом не узнают.
3. Данные в нажимаемой кнопке могут занимать только 64 байта
Я написал байта, а не символа, потому что телеграм использует кодировку UTF-8, символ в которой, в общем-то, может весить от 1 до 4 байт. Пока в параметры с текстовым наполнением (типа callback_data
в кнопке или text
в сообщении) вы вписываете латинские буквы, цифры и знаки препинания (всё, что есть печатаемого в таблице ASCII), каждый символ будет занимать 1 байт. Как только вы переходите на кириллицу — каждый её символ будет занимать 2 байта. Эмодзи занимают уже от 2 до 4 байт. В итоге из 64 символов у вас остаётся вдвое –, а то и вчетверо — меньше. Но я бы не написал это просто так, чтобы напомнить. В телеграме (насколько мне известно) все шрифты одинаково отображают латиницу и кириллицу, а значит разницы между латинской «a» и русской «а» пользователь не заметит. Поэтому для экономии места все совпадающие с латинскими по начертанию кириллические символы можно заменять.
4. Данные в нажимаемой кнопке — это то, что можно подсмотреть и подделать
В прошлый раз я написал, что для защиты от нажатия на «опасные» кнопки дважды можно в каждую добавлять генерируемый при отправке этих кнопок секрет, а потом его проверять. Также можно этот секрет обновлять с каждым сообщением. Этой защиты достаточно, но есть два нюанса. Если ваш бот имеет ценность, достаточно большую ценность — ваши кнопки начнут разбирать, используя самодельные телеграм-клиенты, где вся информация о содержимом кнопки просматривается, поскольку это необходимо для того, чтобы поместить эту информацию в нарисованную кнопку или показать пользователю. А значит кнопка может нажаться совсем не та, которую вы ожидаете. Поэтому всегда проверяйте, может ли конкретный пользователь на данный момент нажать на эту кнопку, использовать заложенную в неё функцию. Второй нюанс заключается в содержимом параметра callback_data
. В моих ботах, к примеру, я использую кнопки в качестве замены команд, но обрабатываются они как команды, то есть параметры содержат что-то вроде:
/edit 1 3 some text
Этот текст можно напрямую отправить как сообщение, и бот точно так же его обработает.
Поэтому убедитесь в том, что вы не помещаете в кнопку достаточно чувствительные к раскрытию данные: пароли, хэши, секреты и прочее. Ну и не забываем про всякие инъекции, которые тоже могут отправиться через кнопку, и никакой secret_token
не спасёт положение.
5. Какой ещё secret_token?
При установке вебхука одним из параметров можно указать secret_token
с секретным значением, которое будет присылать вам в заголовке каждый раз сам телеграм, чтобы вы могли идентифицировать его запросы. Так вы убедитесь в том, что запросы действительно от него. Проблема может быть в том, что этот токен могут узнать, если на вашем компьютере установлен кейлоггер или что-то подобное, дабы отлавливать именно такие вещи, или конфиденциальность вашей работы на компьютере ещё каким-либо образом скомпрометирована. В общем, это вероятно точно так же, как и просмотр и подделка ваших кнопок на кастомном телеграм клиенте, и эта вероятность прямо пропорциональна ценности компрометации вашей разработки. Если вы какой-нибудь Сбер — задумайтесь над этим. Если вы Вася — забейте, ваш бот никому не нужен. А впрочем, это уже совсем другая история…
P.S. Как мне указали в комментарии к прошлой статье, у телеграма есть определённый пул адресов, запросы с которых отправляются на ваш сервер — так можно определить, что запрос пришёл от телеграма. Плюс можно менять secret_token
через определённые промежутки времени. Настолько глубоко я не погружался в безопасность разработки, так как совсем не моя область, но не упомянуть об этом я не мог.