Русский
Русский
English
Статистика
Реклама

Telegram

Опубликованы исходники швейцарского криптомессенджера Threema

18.03.2021 22:21:23 | Автор: admin

Архитектура веб-клиента Threema, источник

Защищённый мессенджер Threema открыл исходный код и инструкции по воспроизводимой сборке приложений. Опубликованы 12 репозиториев для клиентов Android, iOS, веб-версии, рилеев нотификаций и других компонентов. Это важнейшее событие в истории компании Threema GmbH, которая с публикацией исходников выходит на новый уровень разработки.

На фоне массового исхода пользователей WhatsApp платный мессенджер Threema стал одним из самых скачиваемых приложений в мире, вместе с Telegram, Signal и Element (децентрализованная сеть Matrix), см. также статью Какое шифрование лучше: Signal или Telegram?.

Threema наименее известна в этой плеяде. Зато у неё есть одно преимущество перед конкурентами швейцарская юрисдикция.

Threema сервис для обмена сообщениями, который реализует сквозное шифрование коммуникаций (E2EE). Поддерживаются аудио- и видеозвонки, обмен файлами и другие возможности современных мессенджеров.

Есть версии для Android, iOS и веба. Отдельного десктопного приложения, в том числе под Linux, пока не разработано.

Интересно, что исходники на Github обновляются только с обновлением клиентов, то есть один коммит = один релиз. Пул-реквесты и баги в репозиториях Github не принимаются, только по почте.

Юрисдикция это важно


Threema развивается швейцарской компанией Threema GmbH. Серверы проекта тоже в Швейцарии. Именно швейцарская юрисдикция главное преимущество Threema перед Signal (США) и Telegram (США, Великобритания, разработка переезжает по офисам в разных странах, сейчас находится в ОАЭ, основатели и программисты преимущественно из России, инвесторы из России и других стран, кроме США).

Юрисдикция управляющей компании вовсе не второстепенный вопрос, когда у властей возникают претензии к отдельным пользователям, клиентам сервиса. Например, в США действуют законы, по которым компания обязана секретно внедрить бэкдоры в свои продукты и сервисы и реализовать слежку за пользователями, если секретный суд примет такое решение.

Это касается и любых криптографических сервисов, даже опенсорсных и самых защищённых на архитектурном уровне. Очень важно, что компания не имеет права предупреждать пользователей о таких действиях. Фактически, в этой ситуации у неё единственный вариант защиты пользователей: закрыться и прекратить оказание услуг.

Многие помнят историю почтового сервиса Tutanota, которого немецкий суд заставил установить бэкдор для расшифровки почты определённого пользователя. Владельцы ганноверской компании тогда жалели, что не выбрали иную юрисдикцию. В одном из интервью они сказали, что рассматривают переезд в Швейцарию, хотя правовая ситуация в Германии не такая плачевная: Правовая ситуация и конституция Германии в основном очень хорошие и защищают конфиденциальность людей. Общественная активность также помогает нам предотвратить или ослабить проблемные законы (слежку).

В США правовая ситуация гораздо хуже, особенно после 9/11. В августе 2013 года был вынужден закрыться почтовый сервис Lavabit. Основатель и владелец сервиса Ладар Левисон (Ladar Levison) сказал, что принял это решение после долгих раздумий:

Я бы хотел иметь легальную возможность рассказать вам о всех событиях, которые привели к такому моему решению, но я не могу. Я чувствую, что вы заслуживаете знать, что происходит. Первая поправка должна гарантировать мне свободу слова в ситуациях вроде этой. К сожалению, Конгресс принял законы, которые говорят обратное. На данном этапе я не могу поделиться событиями последних шести недель, хотя я дважды отправлял соответствующие запросы [чтобы мне разрешили это сделать], написал основатель Lavabit Ладар Левисон. Он не вдаётся в подробности своего дела, но обращается ко всем пользователям: Минувшие события преподали мне один очень важный урок: до решения Конгресса или чёткого судебного прецедента я _очень_ не рекомендую кому-либо доверять персональные данные компании, которая физически привязана к США.

О правовой ситуации в странах с менее развитой судебной системой нечего и говорить. В государствах вроде РФ правовые гарантии конфиденциальности как таковые практически отсутствуют. То есть доверять приватные данные российской компании самый огромнейший риск среди всех, которые можно представить.

В такой ситуации вопрос юрисдикции конкретного веб-сервиса становится ключевым. В мире осталось не так много мест, где права человека ценятся выше, чем права государства.

Threema GmbH швейцарский стартап, который получил финансирование от немецко-швейцарской инвестиционной компании Afinum Management AG. Основатели компании три программиста Мануэль Каспер (Manuel Kasper), Сильван Энгелер (Silvan Engeler) и Мартин Блаттер (Martin Blatter).

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

Разработчики обещают выпустить полноценный десктопный клиент, в том числе под Linux, которым можно будет пользоваться без смартфона: Безопасность и защита приватности глубоко укоренились в ДНК Threema, поэтому наш код регулярно проходил внешний аудит (см. результаты аудита за ноябрь 2020 года). Благодаря открытым исходникам любой желающий может самостоятельно проверить безопасность Threema и убедиться, что опубликованный исходный код соответствует загруженному приложению. В будущем благодаря инновационному решению с несколькими устройствами можно будет использовать несколько устройств параллельно. В отличие от других подходов, на сервере не останется никаких следов персональных данных. Благодаря этой технологии Threema можно использовать на ПК без смартфона. В итоге, Threema станет ещё более надёжным и ещё более удобным приложением.

В отличие от Telegram, серверы Threema не хранят сообщения и файлы пользователей, поэтому здесь расходы на инфраструктуру минимальны.

Дополнительно:





Подробнее..

Свой криптографический протокол опасная идея

01.06.2021 12:20:22 | Автор: admin

Разработка своей криптографии в чём-то сравнима с созданием собственного авиадвигателя, говорит эксперт по безопасности Руна Сандвик. Фото: Виталий Кузьмин

Предположим, заказчик требует разработать собственный сетевой протокол. Например, для передачи данных между сервером и мобильным приложением, для связи между микросервисами, модулями программной системы, поверх UDP или поверх TCP. С шифрованием.

Казалось бы, почему не использовать открытые стандарты типа WebSocket и JSON, зачем собственный закрытый протокол? На это обычно приводят ряд причин. Во-первых, для безопасности, чтобы его было сложнее отреверсить и никто не понял, какие данные вы передаёте. Во-вторых, для эффективности. У нас ведь уникальный случай использования, поэтому стандартные решения не самые оптимальные. Наш собственный протокол будет работать с меньшими задержками, потреблять меньше трафика и меньше расходовать батарею (на мобильных устройствах). И третья причина функции. В своём протоколе специально для нашего приложения мы реализуем уникальные возможности, каких нет ни в открытом стандарте, ни у конкурентов.

Это распространённые причины, из-за которых разрабатывают проприетарные протоколы.

Безопасность


Поговорим о безопасности.

Любой безопасник скажет, что протокол должен быть закрытым. Это важно для защиты от конкурентов. И от клиентов тоже. Чем меньше клиент знает о протоколе тем меньше он контролирует систему, приложение. Вся власть остаётся в руках разработчика. Система полностью под контролем производителя, то есть вас. Соответственно, клиент навечно привязан к вам по обслуживанию, он не сможет ничего поломать в аппаратуре или софте. Он вообще побоится туда сунуться, потому что там ничего не понятно. Всё обфусцировано, зашифровано и написано на непонятном языке. Классика.

На Хабре частенько упоминают реверс-инжиниринг протоколов в различных устройствах: автомобили, тракторы, даже машины для производства мороженого. Производители этой техники стараются скрыть технические данные ради безопасности. Чтобы глупые пользователи не совали шаловливые ручки внутрь.

Например, важной частью бизнеса многих компаний является сервис и техническое обслуживание. Поэтому некая компания, скажем, системный интегратор предпочтёт вместо стандартных Open Source решений внедрить клиенту проприетарный софт с собственным закрытым протоколом. И всё. После этого она будет доить клиента десятилетиями.

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

В общем, проприетарный протокол кажется очень выгодным для фирмы.

Но жизнь иногда показывает обратное. А именно:

  1. Принцип безопасность через неясность не работает. Любой протокол можно отреверсить.
  2. Проприетарная реализация шифрования это очень рискованно.
  3. Никто не поможет закрыть критические дыры в закрытом софте.

Принцип безопасность через неясность не работает в криптографии


Принцип безопасность через неясность (security through obscurity) заключается в том, чтобы скрыть внутреннее устройство системы или реализацию для обеспечения безопасности.

Но в любой системе есть недостатки. В данном случае разработчик системы хочет спрятать эти недостатки, чтобы злоумышленник ими не воспользовался.

Сравните с опенсорсными системами, где разработчик специально открывает код, чтобы независимые сторонние эксперты помогли выявить и исправить эти недостатки.

В итоге получается, что собственный проприетарный протокол, максимально закрытый от посторонних глаз и обфусцированный, вовсе не увеличивает безопасность системы, а уменьшает её!


В криптографии одно из базовых правил использовать только открытые, публичные алгоритмы и протоколы. В такой системе есть лишь один секрет приватный ключ. Больше ничего. Это принцип Керкгоффса, который широко применяется в криптографии и считается практически неоспоримым.

Голландский криптограф Огюст Керкгоффс изложил правила проектирования военных шифров в книге Военная криптография (1883). Основная идея была в том, что попадание системы в руки врага не должно причинять неудобств. Поэтому ничего, кроме ключа, не должно быть секретным.

Собственная криптография


Вопрос Почему не разработать собственную криптографию? чем-то похож на вопрос Почему не спроектировать авиадвигатель?, говорит Руна Сандвик, исследователь по безопасности. Конечно, теоретически мы можем это сделать. Но это чрезвычайно сложно. Гораздо более простой и надёжный вариант выбрать готовое решение, проверенные и надёжные протоколы и алгоритмы.

Поэтому в сообществе информационной безопасности вызывает большое подозрение, если какая-то компания реализует собственный проприетарный протокол. Например, проприетарный протокол MTProto в Telegram поначалу вызвал массу критических отзывов. Взлом MTProto1.0 стал одной из самых популярных статей на Хабре в 2013 году: Безопасен ли Telegram? Или как я искал закладку в MTProto (спойлер: глупые ошибки в проприетарной криптографии).

Хотя баг быстро исправили, это наглядный пример, почему не нужно разрабатывать собственные авиадвигатели криптографические алгоритмы. Вы можете допустить ошибку а риски огромные. Люди полагаются на безопасное шифрование, от этого зависит их свобода, а иногда жизнь.

К тому же, в мессенджере запрещена анонимная регистрация без номера телефона вероятно, так удобнее коммерческой компании, чтобы блокировать спам и продвигать приложение по адресным книгам. Кто будет думать об анонимности, когда на кону миллиарды долларов прибыли? При этом Telegram изначально позиционировали именно как безопасный мессенджер (многие пользователи купились на такую рекламу).

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

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

Конечно, в опенсорсе есть свои специфические риски. Например, проблемы с сотнями зависимостей, которые вы не контролируете. Например, 20% багов в проектах на GitHub явно внесены в проекты специально, со злым умыслом. То есть вредоносными контрибуторами, которые действовали умышленно. Ещё не забыта история c мейнтейнером ESLint, который 12 июля 2018 года опубликовал вредоносные версии пакетов eslint-scope и eslint-config-eslint в репозитории npm.

Такое может случиться с каждым опенсорсным проектом, потому что мейнтейнеры работают бесплатно, на износ:


Поэтому иногда соглашаются продать свой проект (такая же история с расширениями для браузеров). А этот проект уже внедрён в качестве зависимости в тысячи других.

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

Кстати, в 2013 году проприетарный софт впервые обогнал опенсорсные проекты по среднему количеству багов на 1000 строк кода.


Источник: Coverity Scan Open Source Report

В прошлом веке считалось, что проприетарный софт пишут профессионалы, а Open Source любители. Сегодня же профессиональный уровень опенсорсных программ вовсе не уступает проприетарным. Может, даже превосходит их.

Возвращаясь к примеру Telegram. 5 декабря 2020 года двое итальянских математиков Марино Микулан и Никола Витоколонна опубликовали на сайте препринтов arXiv.org исследование Автоматическая символическая проверка протокола MTProto 2.0 в Telegram (вторая версия опубликована 30 апреля 2021 года, arXiv:2012.03141v1). Оно подтверждает безопасность обновлённой версии фирменного протокола MTProto 2.0.


Набор протоколов MTProto 2.0 (в голубой рамке) и область покрытия данной научной работы (светло-зелёным цветом). Схема из научной статьи Марино Микулана и Никола Витоколонны, arXiv:2012.03141v1

Статья содержит полностью автоматизированное доказательство надёжности аутентификации MTProto 2.0, обычного чата, зашифрованного end-to-end чата и механизмов повторного ввода ключей в отношении нескольких свойств безопасности, включая аутентификацию, целостность, конфиденциальность и совершенную прямую секретность, а также доказывает формальную корректность MTProto 2.0.


Протокол аутентификации MTProto 2.0. Здесь $\{m\}_{pk}$ означает асимметричное шифрование $m$ открытым ключом $pk$. В свою очередь, $\{m\}_{(k,iv)}$ означает симметричное шифрование общим ключом $k$ с вектором инициализации $iv$. Схема из научной статьи


Слегка упрощённая версия протокола MTProto 2.0 для секретных чатов. Все сообщения перенаправляются через сервер $S$: каждое сообщение между $X \in \{A, B \}$ и $S$ шифруется с использованием ключа авторизации $X$ (здесь не показан). Обратите внимание, что $g_{ab}$, $k$ и $iv$ не известны серверу $S$. Схема из научной статьи



Эта математическая работа чуть ослабила озабоченность экспертов по поводу проприетарного протокола MTProto2.0. Редкий случай, когда собственная нестандартная криптографическая система (пока) работает надёжно. В ней ещё не нашли таких фатальных уязвимостей, как в MTProto 1.0.

Неужели разработчики Telegram всё-таки научились и смогли сделать уникальный авиадвигатель без ошибок? Можно только порадоваться за них, ведь все пользователи Telegram участвовали в этом обучении как бета-тестеры. В каком-то смысле это наш общий успех.



На правах рекламы


Наша компания предлагает серверы с Linux или Windows. Не экономим на железе только современное оборудование и одни из лучших дата-центров в России и ЕС. Поспешите проверить!

Присоединяйтесь к нашему чату в Telegram.

Подробнее..

Как замедлили Twitter? Что такое DPI? Разбор

13.04.2021 20:10:28 | Автор: admin
Наверное, вы слышали, что на этой неделе стартовало так называемое замедление Twitter.

С 10 марта 100% мобильного и 50% стационарного трафика Twitter в России официально замедлены. Все это стало возможным благодаря технологии DPI. Мы решили разобраться, как это работает и как устроен механизм замедления.

Почему это важно? Можно предположить, что Twitter это репетиция перед замедлением/блокировкой Facebook, а потом YouTube.

Поэтому сегодня разберемся, что такое DPI, как работает и какие у него возможности.

Будет ли у нас как в Китае? И как от этого защититься?



Начнем издалека, в ноябре 2019 года вступил в силу закон, по которому операторы связи должны были начать установку специальных технических средств противодействия угрозам (ТСПУ).

Позднее выяснилось, что за аббревиатурой ТСПУ скрывалась известная любому сисадмину технология DPI Deep Packet Inspection или Глубокий анализ пакетов. Не путать с плотностью пикселей на дюйм это тоже DPI, но Dots Per Inch.



И вот она дошла до тестирования в масштабах страны. На примере твиттера.

Я сразу скажу, что осуждаю подобное давление на соцсети, потому что это угроза свободе слова, которая у нас только в интернете и сохраняется.Но перейдем к технологиям.

Как работает DPI?


Сисадмины знают, что передача данных в сети разделена на уровни: от физического, где передаются биты, до уровня приложений, где упаковывается сообщение в мессенджере. На каждом уровне пакет данных пополняется своими метаданными, относящимися к нему. Получается своеобразная матрешка. Например, какое приложение отправляет информацию, на какой IP-адрес и так далее.

Так вот DPI умеет просматривать данные разного уровня и сами пакеты. И оно может понять не только откуда и куда идет трафик, но и что это за трафик конкретно: текстовое сообщение, картинки или видео, голосовой трафик Skype или может даже торрент.А дальше сделать с ним, то что хочется:
  • Приоритизировать
  • Ограничить по скорости
  • Перенаправить
  • Заблокировать
  • Ну или, конечно, передать получателю.

Кстати насколько именно замедляется Twitter сейчас непонятно. Лично я проблем пока не наблюдаю. Но почему так мы еще поговорим.



Это сильно упрощает задачи по блокировке сайтов и сервисов. Почему?

Раньше блокировки делались по IP-адресам. А это означало, что сервис ограничивался полностью. А кроме этого страдали сайты, которые записаны на тот же IP-адрес.

Теперь можно внимательно рассматривать пакеты и заблокировать, к примеру только загрузку картинок.

Но как вся эта вундер-технология работает?


Есть две вещи, которые анализирует DPI: сами пакеты информации, причем как метаданные и заголовки, так и внутреннее содержимое. И второе это так сказать поведение пакетов данных.



Давайте посмотрим на пример. Вот так выглядит заголовок пакета при получении данных браузером и с ним все ясно. Сверху написан протокол HTTP, то есть скорее всего веб-страничка. Мы видим адрес запроса. И даже, какие именно данные отправляются.



В данном случае, это небольшая картинка. И ее размер в байтах тоже написан. Даже не нужно залезать внутрь самих данных, чтобы понять, что перед нами.





С зашифрованным трафиком сложнее.Тут инфы намного меньше. Система увидит, какой порт используется (это дает намек на тип приложения), IP-адреса, тип шифрования. А все остальное зашифровано, даже URL-адрес.

Есть и вторая часть алгоритмов DPI. DPI применяет так называемый эвристический анализ: из пакета извлекаются небольшие кусочки данных, так сказать образцы. А дальше система смотрит на что эти данные похожи. Сравнивая их с огромной базой известных образцов. Такие образцы данных называются сигнатурами трафика.



Это очень похоже на то как работает Shazam, который сравнивает небольшой кусочек песни, записанный вами на диктофон, с огромной базой сигнатур песен которые хранятся на сервере. То есть по большому счету DPI это Shazam для трафика.



Кстати, точно по такому же принципу работают антивирусы, они сравнивают сигнатуры новых вирусов с огромной базой известных вирусов.

Кроме этого DPI смотрит на частоту и размер пакетов, потому что разные приложения тоже имеют свои особенности. Например, торренты очень своеобразно отправляют пакеты.

И главное, что поскольку все происходит в реальном времени, такой подход позволяет не сильно замедлять интернет.

Как можно использовать DPI?


Классифицировав пакет, технология DPI позволяет много чего с ним сделать и в целом технология может быть полезна. С помощью DPI можно повышать качество и скорость соединения, приоритизируя один тип трафика над другим.Например, если в вашей локалке все качают торренты, то люди не смогут нормально созвониться по ZOOM по работе. Тогда DPI позволит трафику ZOOM поставить приоритет повыше.

Но если вы Роскомнадзор, у вас вероятно другие приоритеты.

Но вопрос в том, кто будет определять, какой трафик приоритетный а какой нет, остается открытым. Например, при помощи DPI вполне можно продвигать одни сервисы и замедлять другие: отдавая приоритеты отечественным аналогам. К примеру, можно замедлить YouTube и при этом ускорить Rutube.В общем, вариантов для фантазии масса.

Архитектура или почему все снова пошло не по плану?


Но если существует такой мощный инструмент, почему же с Twitter по-прежнему все весьма неплохо?

Важным является вопрос архитектуры и внедрения: то есть, где именно устанавливать DPI-оборудование. Чтобы весь трафик страны проходил проверку, необходимо, чтобы операторы ставили DPI на всех своих пограничных шлюзах. Логично.

Вы обратили внимание, что анонсировано: Замедление для 100% мобильного трафика, а для стационарного только 50%? Распространять опасный по мнению РКН контент через компы не так опасно, что ли? Нет.

Просто внедрили технологию далеко не все. С тусовкой мобильных операторов удалось договориться. А маленьких местных провайдеров интернета огромное количество. Но это полбеды.

Во-вторых, как и в случае с Telegram, заблокировать Twitter не так уж и просто. Дело в том, что Twitter для обеспечения высокой скорости работы сервиса по всему миру пользуется услугами CDN-провайдера. Он называется Akamai.

CDN Content Delivery Network сеть доставки контента.




CDN-провайдер предоставляет Твиттеру распределенную по всему миру инфраструктуру. Как правило, это необходимо, чтобы пользователь при обращении к какому-либо сайту получал информацию не с его основного сервера, который может находиться на другом конце света, а с ближайшего к нему узла.

Такая распределенная система доставки контента заметно усложняет возможность блокировки или ограничения доступа к ресурсу. Потому что если приложение не получит данные по одному адресу, оно пойдет в другой. А там у оператора может быть не включен DPI.



Чтобы наверняка ограничить доступ к интернет-сервису, использующему CDN, требуется ограничить доступ практически ко всей сети CDN-провайдера, у которого могут быть десятки тысяч серверов по всему миру. Иными словами, чтобы заблокировать Twitter, надо заблокировать CDN-провайдера, а от этого снова ляжет половина интернета.

И я даже не буду останавливаться на курьезной ситуации, когда ограничивают полосу пропускания не только для домена twitter.com, но и для всех доменов, в названии которых есть сочетание t.co это короткий домен, принадлежащий твиттеру. Таким образом, ограничениям подвергались и другие сайты, к примеру: reddit.com, microsoft.com и даже сайт Russia Today rt.com. Предположительно по этой же причине прилегли сервера ростелекома.

Впрочем, со временем это вроде починили. Интересно другое.

Ограничения DPI. Что делать?




Но самое любопытное: поскольку это своего рода гадание, нет единого стандарта DPI. У каждого поставщика оборудования свои алгоритмы и технологии.

Качество и эффективность работы DPI очень сильно зависит, от качества базы сигнатур, которую должен на постоянной основе обновлять поставщик. Иными словами, если Twitter что-то поменяет в составе пакетов трафика, то не факт, что старые DPI смогут классифицировать трафик по старым сигнатурам.



Ну и наконец, DPI достаточно легко обойти при помощи VPN, так как VPN шифрует весь трафик и подменяет ваш IP-адрес, то и DPI для него не страшен.



Но ожидается и более простое решение. Протоколы шифрования тоже не стоят на месте. И с приходом TLS 1.3 и DNSSEC еще больше данных приложения и пользователя будут скрыты от DPI. И понять, что в системе за пакет будет еще сложнее. Такие дела.
Подробнее..

Прекратите повторять за мной как хайп вокруг Clubhouse повлиял на планы других соцсетей

02.05.2021 22:08:33 | Автор: admin

Анализируем релизы Reddit, Discord и Telegram их команды буквально на днях предложили свой взгляд на интерфейсы для голосового общения. Главный фактор, подстегнувший соцсети к вводу такого функционала, это фантастическая концентрация внимания аудитории и инвесторов на проекте Clubhouse. Как вы уже знаете, он выстрелил в прошлом году, а в апреле 2021-го его капитализацию оценили в четыре миллиарда долларов. Разбираемся, за тем ли зайцем погнались крупнейшие социальные платформы, и как идет этот процесс.

Фотография: Kristina Litvjak. Источник: Unsplash.comФотография: Kristina Litvjak. Источник: Unsplash.com

Дом для Reddit

В России интерес к Clubhouse, кажется, падает. Однако в мире о проекте продолжают говорить. Массовый хайп вокруг него мотивирует руководство крупнейших соцсетей к экстренному запуску похожего функционала. Так, команда Reddit пару недель назад анонсировала сервис для общения в прямом эфире Talk. Он предназначен для тематических сообществ, чьи участники с помощью Reddit Talk смогут проводить сессии вопросов и ответов, организовывать лекции и в любое удобное время общаться в голосовых чатах. Пока их не открыли для всех пользователей платформы и ожидают тех, кто будет готов попробовать сервис в деле в числе первых.

Как пишут в релизе, права на запуск аудиокомнат будут исключительно у модераторов сообществ. Еще они получат возможность приглашать спикеров и управлять их микрофонами во время беседы, плюс удалять пользователей из аудиочата и ограничивать для них вход. Последние смогут подключаться к прослушиванию и сигнализировать о готовности высказаться по тому или иному вопросу с помощью поднятых рук. Словом, все как в Clubhouse.

Новость о готовящемся запуске сообщество площадки встретило без энтузиазма. Первым под огонь критики попал интерфейс многим он показался перегруженным аватарами спикеров и слушателей. Еще больший гнев вызвала необходимость модерации происходящего в голосовых чатах менеджеры сообществ пожаловались, что им не хватает времени на анализ контента в текстовом виде, а тут появляется новый инструмент, требующий дополнительных трудозатрат. Третий момент, на который обратили внимание резиденты площадки, это вопросы относительно того, как Reddit собирается хранить и обрабатывать аудиоконтент: будут ли записи оставаться в облаке, планируется ли возможность бэкапа бесед по запросу организаторов и с разрешения участников. Все это еще предстоит выяснить.

Фотография: Steven Weeks. Источник: Unsplash.comФотография: Steven Weeks. Источник: Unsplash.com

Обработка аудиозаписей пользователей соцсетей значимая тема, и обсуждать ее начали задолго до появления клубного дома. Однако пристальное внимание к этому проекту и скандалы, связанные с утечками данных из Clubhouse, вместе с общими сложностями с модерацией потокового аудио подогрели обстановку вокруг платформ, разрабатывающих подобный функционал. Reddit не исключение, и у его аудитории возникло множество сомнений на этот счет, учитывая тот факт, что пресс-релиз вышел без каких-либо пояснений.

Перестройка в Discord и Telegram

Даже сервисы, казалось бы, не требовавшие доработки, решили подвергнуть локальному переформатированию в свете хайпа вокруг Clubhouse. Чуть более месяца назад Discord представили так называемые Stage Channels каналы, доступные для тематических серверов [отличаются от обычных Discord-комнат по типу и задуманы для сообществ]. Они очень похожи на аудиочаты в Reddit и комнаты в Clubhouse: здесь у модераторов есть возможность назначить спикеров, управлять их микрофонами, а у аудитории присоединяться к прослушиванию бесед и поднимать руку в надежде, что вопрос или реплику дадут произнести в эфире.

В Telegram голосовые чаты появились раньше, в конце прошлого года. В середине марта их обновили. Реализованы здесь аудиокомнаты на свой лад с учетом зарекомендовавшего себя функционала мессенджера. Хотя и все основные Clubhouse-возможности тут тоже есть. Как и одно заметное отличие простой и понятный подход к записи бесед в аудиочатах.

Фотография: Dan-Cristian Pdure. Источник: Unsplash.comФотография: Dan-Cristian Pdure. Источник: Unsplash.com

Что интересно, ни одна из компаний не стала раскрывать пользователям свои планы относительно длительности хранения записей и перспектив их использования. Например, для обучения нейросетей или формирования сводов метаданных для профилирования пользователей, разработки алгоритмов модерации аудиоконтента и рекламных движков.

Глухая стена

Очевиден кризис отрасли. Его явный признак массовое копирование фичей выстрелившего проекта с непонятными перспективами. Такими темпами крупнейшие медиаплатформы рискуют перегрузить свои интерфейсы избыточным функционалом, который не ожидала увидеть и не просила разрабатывать их аудитория. Однако этот подход может оказаться губительным лишь для монополистов рынка, чье место в скором времени способны занять новые соцсети.

О том, как будут развиваться события, и о других проектах, внедряющих похожие возможности в свои продукты, мы поговорим в нашем следующем материале.


Что еще у нас есть в нашем Мире Hi-Fi:


У нас на Хабре: парочка доступных бандлов с устройствами для аудиозаписи.


Подробнее..

Демократия в Telegram-группах

07.05.2021 14:19:42 | Автор: admin

Многие из нас проводят время в профильных телеграм-группах. Власть над общением здесь принадлежит случайным людям со своими недостатками. Нередко встречаются конфликты и злоупотребления. Это побуждает задуматься, а можно ли поддерживать порядок иначе, так, чтобы не расцветал мошеннический спам и одновременно ни у кого не было абсолютной власти над адекватным собеседником?
И в моем случае эти размышления вылились в разработанную и протестированную систему которую уже сегодня можно подключить в ваш Telegram.

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

  • У каждого пользователя копится время с момента написания первого сообщения.
    Это аналог безусловного базового дохода. Минута за минутой, час за часом. Он необходим чтобы эмиссия системной валюты происходила без злоупотреблений, независимо от каких-либо центров управления.

  • Абсолютно каждый может использовать часть накопленного времени, чтобы забанить другого пользователя в чате на это время.
    Это электронный аналог второй поправки, необходимый для того чтобы власть не сосредоточилась в группе в одних руках.

  • Каждый также может использовать накопленное время чтобы разбанить другого пользователя.
    Обратимость бана защищает от злоупотреблений свободного оборота банхаммеров. Одновременно эта функция является обратным к эмисии процессом. Время потраченное на выкуп из бана сгорает безвозвратно.

  • Накопленное время можно передать другим людям, полностью или по частям.
    Эта функция в перспективе обеспечивает подключенным группам свободный рынок обмена чем угодно.

Итак, как это работает в теории разобрались, а что необходимо для практического функционирования такой системы?

  • Простой способ подключения чата к системе.
    - Реализована в виде бота

  • Максимально удобный для Telegram команд UX
    - Есть распознавание речи основанное на нормализованных семантических представлениях

Где примеры использования?

Бот понимает в запросах и русский и английский язык в свободной форме. Используются сокращения: d - дни, h - часы, m - минуты, s - секунды. Все уведомления публичны, но исчезают через 15 секунд, чтобы не засорять общий чат.

Вот как можно посмотреть сколько времени накопилось. Вот как можно посмотреть сколько времени накопилось. Забанить токсичного человека, спамера или мошенника можно указав в ответе в ему, в свободной форме, на сколько времени он получает бан (и за что по желанию). Забанить токсичного человека, спамера или мошенника можно указав в ответе в ему, в свободной форме, на сколько времени он получает бан (и за что по желанию). Если это было недопонимание и человек все же хороший, можно таким же образом, просто написать в ответе что его нужно разблокироватьЕсли это было недопонимание и человек все же хороший, можно таким же образом, просто написать в ответе что его нужно разблокироватьЧтобы перевести время другому пользователю указажите в ответе сколько времени нужно передать.Чтобы перевести время другому пользователю указажите в ответе сколько времени нужно передать.

Довольно слов, покажите мне код!

Для бекенда использовался язык Kotlin + JVM, в качестве базы данных используется Redis-кластер. Весь код продокументирован и доступен на GitHub: demidko/timecobot
Чтобы начать использовать бота в вашей телеграм-группе просто добавьте его с правами администратора: @timecbobot

Напишите пожалуйста свое мнение в комментариях, нужное ли это для сообщества дело и стоит ли развивать систему дальше? Что можно улучшить или поменять? Интересна ли подробная статья с кодом на тему как это реализовано внутри?

Всем удачного дня!

Подробнее..

Telegram для бабушки испанец создал механическую DIY-машину для чтения и печати сообщений

27.04.2021 14:21:47 | Автор: admin

Общение в мессенджерах давно стало нормой для большинства жителей планеты. Но далеко не все пожилые люди овладели современными технологиями. Чтобы облегчить коммуникацию со своей 96-летний бабушкой, испанец Мануэль Лусио Далло создал механическую машину. Ее общение с внуками было сильно ограничено во время пандемии, что и вдохновило испанца на разработку устройства. Аппарат умеет принимать текстовые и отправлять голосовые сообщения. Технологическая схема процесса напоминает использование старого телефонного коммутатора.

Yayagram для бабушки


Источник
Испанец назвал устройство Yayagram. На кастильском диалекте yaya это вариант теплого обращения к бабушке.


Две основные функции Yayagram:

  1. Отправка голосовых сообщений.
  2. Прием сообщений с печатью на термобумаге.


Как же оно работает? Чтобы отправить сообщение, нужно подключить физический кабель рядом с именем получателя. Во время проговаривания сообщения следует нажать и удерживать кнопку встроенный микрофон запишет звук. На телефон адресату придет стандартная голосовая заметка. Когда же на устройство приходит текстовое сообщение, оно печатается с помощью встроенного термопринтера.

Создание DIY-устройства


Источник
Далло работает в компании, разрабатывающей ПО Plastic SCM. Для создания аппарата для бабушки он использовал Raspberry Pi 4 и несколько сторонних программных библиотек. Код написал на Python. Микрофон самый обычный. Встроенный принтер похож на те, что используют в кассовых аппаратах. Помимо этого, в устройстве задействованы несколько светодиодов, разъемов, кабели и кнопки. По словам Далло, синхронизировать аппарат с Telegram он решил из-за большей открытости сервиса по сравнению с другими мессенджерами. А еще он не любит Facebook.

Источник
Бабушка Далло живет в испанском городе Бургос (Burgos), вдалеке от большинства своих внуков. Во время пандемии они не могли ее навещать. Еще его бабушка плохо слышит, поэтому разговаривать с ней по телефону или с помощью видеозвонков порой проблематично. Теперь же с помощью Yayagram она может самостоятельно отправлять и получать сообщения.

Аппарат обошелся Далло в 76 евро. Патентовать устройство он не собирается. В планах у разработчика опубликовать исходный код и детали проекта, чтобы сделать его доступным для всех желающих и помочь наладить общение между поколениями.

Подробнее..

Твиттер Илона Маска в телеграме и с переводом на русский

16.06.2021 16:13:28 | Автор: admin

Хочу поделиться одной моей поделкой, возможно, кому-то она тоже будет полезна. В этой статье я поделюсь тем, что я сделал, чтобы читать Twitter-аккаунт Маска в удобном мне месте и имея под рукой перевод англоязычных твитов на русский.

Проблема

Последние несколько лет замечаю за собой, что хочу начать регулярно почитывать тот или иной блог, но если он не находится в зоне удобного или привычного доступа (к сожалению весь твиттер для меня таков, ничего не могу с собой поделать, не читатель я твиттера), то я довольно быстро забиваю на это. Еще хуже, если блог на другом языке, тут появляется дополнительная проблема, когда из-за технических терминов или разговорного жаргона сложно понять смысл. Собственно такие "преграды" обычно и приводят к тому, что вроде бы и хочется, но как-то не делается.

Идея

Сейчас я делаю на заказ программных роботов, которые в онлайне обрабатывают новостные потоки в соцсетях, фильтруют, выбирают наиболее интересные и цитируемые, и передают заказчику. Я подумал, почему бы мне не использовать свои навыки и не облегчить себе жизнь в описанной выше проблеме. Для этого нужно только каждые сколько-то минут заходить в твиттер, забирать новые сообщения, прогонять их через переводчик и отправлять в канал в телеграме. Кажется, ничего сложного.

Подводные камни

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

Вторая проблема, отказ твиттера в выдаче доступа к API в описанных мной кейсах. То есть остается единственный вариант заниматься веб-скраппингом. Ну что ж.

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

Технологии

Я решил попробовать самостоятельно и начал гуглить что-то вроде "parsing twitter without API". Нашлось достаточно много решений, сразу скажу, что решениеtwint библиотека с открытым исходным кодом, которая вполне работоспособна и подошла под мою задачу.

Для того, чтобы перевести текст с английского на русский, я сначала было собирался использовать google translate, но понимал, что в нем ограниченное количество бесплатных переводов, решил что попробую использовать единственную известную мне нейросеть для перевода с английского на русскийfairseqот Facebook AI Research. Качество перевода показалось мне вполне приемлемым с точки зрения того, чтобы понять в чем суть твита, хотя оно и не было идеальным.

Все это я обернул в скрипт на языке программирования python и запустил на постоянную работу на своем сервере.

Примеры кода

Чтобы собрать данные из твиттера без использования выделенных девелоперских доступов, логинов, паролей и API, нужно сделать следующее:

Установить библиотеку twint

pip3 install twint

Запустить код формата

twint -u <name_of_twitter_user> -o output.csv --csv --since 2020-01-01 --retweets

Здесь есть важный момент, что запускается это все из-под bash, при том что у библиотеки есть python API (да и написана она на питоне), но при этом я потратил довольно много времени и оно ни в какую не заводилось. При этом если запускать из командной строки - все кроме автоматического перевода постов у меня работало.

Из функционала, который есть у библиотеки еще отмечу:

  • Возможность искать твиты пользователя по ключевому слову

twint -u username -s pineapple
  • Возможность находить твиты пользователя с указанием номеров телефонов и почт

twint -u username --email --phone
  • Поиск твитов вокруг определенной локации

twint -g="48.880048,2.385939,1km" -o file.csv --csv
  • Сохранение в Elasticsearch или SQLite

twint -u username -es localhost:9200twint -u username --database tweets.db
  • Сохранение фоловеров, подписок и избранных для пользователя

twint -u username --followerstwint -u username --followingtwint -u username --favorites

Данные сохраняются в csv файл, в котором присутствуют такие поля как (перечислю те, которые использовал сам, так как их много и большинство несут мало информации):

id - идентификатор сообщения

conversation_id - идентификатор беседы

created_at - дата создания сообщения

tweet - текст сообщения

mentions - упоминания пользователей твиттера ( список словарей)

urls - вставленные по правилам твиттера ссылки (например на youtube)

photos - ссылки на картинки

link - ссылка на твит

reply_to - список словарей с пользователямя, ответом на твиты которых является твит

У библиотеки есть также возможность перевода на другой язык, но она у меня совсем не заработала. Собственно по этой причине я искал другую возможность. Нашел я, как упоминал выше, открытую разработку Facebook AI Research - библиотеку fairseq, в которой можно скачать веса нейронки для перевода в частности из английского в русский и наоборот.

pip install hydra-core

Итого необходимо было установить:

pip install torch pip install hydra-core==1.0.0 omegaconf==2.0.1pip install fastBPE regex requests sacremoses subword_nmt 

Вообще мануал по установке и пример использование есть на сайте pytorch, но как видите у меня он немного отличается. Для того, чтобы сделать перевод можно пользоваться следующим куском из примера - он вполне рабочий:

import torch# Compare the results with English-Russian round-trip translation:en2ru = torch.hub.load('pytorch/fairseq', 'transformer.wmt19.en-ru.single_model',                        tokenizer='moses', bpe='fastbpe')ru2en = torch.hub.load('pytorch/fairseq', 'transformer.wmt19.ru-en.single_model',                        tokenizer='moses', bpe='fastbpe')paraphrase = ru2en.translate(  en2ru.translate('PyTorch Hub is an awesome interface!'))assert paraphrase == 'PyTorch is a great interface!'

В нем два раза производится перевод и проверяется соотвествие результата исходному варианту. При первом запуске с серверов torch хаба выкачивается большая нейронка, которая довольно шустро работает и на процессоре.

В целом, если не считать способов использования библиотек, у меня набралось еще довольно много кода, чтобы делать полученные сообщения достаточно читабельными, но это уже детали моего применения.

Как пользоваться

Выглядит сейчас это следующим образом. Каждый твит и ретвит на главной странице твиттера Илона Маска пропускается через переводчик, подбираются ссылки и картинки из поста, дальше все это сохраняется в пост в телеграм-канале. Выглядит это так

Итого у меня получилсятелеграм-каналпод названием "Твиттер Илона Маска" (подписывайтесь, мне будет приятно, что это нужно кому-то еще , будет дополнительный стимул поддерживать в будущем), в котором можно

1) читать новые и старые посты Илона Маска

2) видеть перевод текста на русский язык

3) перейти по ссылке на исходный пост в твиттере

И все это без регистрации и смс:)

Если эта статья показалась вам интересной, поставьте, пожалуйста апвоут (так ее увидит больше людей) и подписывайтесь на мой блог втелеграме, там я ежедневно рассказываю о всех своих экспериментах. Если хотите решить похожую проблему для своего бизнеса пишите вличку.

Подробнее..

Recovery mode Социальный эксперимент порядок из хаоса

14.05.2021 08:04:13 | Автор: admin

Бывало ли такое, что вы вас ограничивали за ваши мысли, так, что вы больше не могли высказаться в ответ? Весьма досадное чувство, не так ли? Как выстрел завершает жизнь человека, так и набор минусов способен лишить вас права существования на площадке.
Что будет если попытаться устроить общение по новым принципам, без администраторов, модераторов, без системы кармы, и даже без владельцев хоста? Сохранить свободу высказываний и при этом оградиться от хаоса? Я убежден что благодаря техническому прогрессу это стало возможно уже сегодня, и предлагаю на деле убедиться в этом, поучаствовав в эксперименте!

В чем суть?

Высшее дао рождает тьму вещей, но ею не владеет; творит многообразные изменения, но над ними не господствует. Те, что бегают и дышат, летают и пресмыкаются, наступает время и рождаются, но не из-за его благоволения; наступает время и умирают, но не из-за его вражды. Приобретая с пользой, оно не может быть восхваляемо; тратя и терпя убыток, оно не может быть порицаемо. Делает раздачи и одаряет, а не скудеет

(Лао-цзы)

Представьте себе затерянный телеграм чат, где нет владельца, и никто не был назначен модератором. У всех участников чата в фоновом режиме майнится некая валюта, просто по факту присутствия в чате, без регистрации. Благодаря встроеному в чат UX, валютой можно обмениваться и передавать друг другу, быстрее чем перевод в банке.
Ее также можно потратить чтобы закрепить свое сообщение на определенное время... или чтобы заблокировать спамера. Блокировка не удаляет человека, а лишь убирает ему поле ввода на время, в зависимости от затраченной на блокировку валюты. Система была бы несовершена без возможности отменить блокировку пользователю, точно также потратив на это часть своей накопленной валюты.

Звучит интересно, в чем отличие от кармы?

  1. Каждый может делать это! Нет инвайтов и все только в ваших и ваших друзей руках, нет централизованной точки отката, нет модератора который может затереть ваш пост или ограничить. Когда нет владельца, то нет и возможности для злоупотреблений "по праву владельца".

  2. Валюта майнится в фоновом режиме безусловно от мнения о вас других пользователей. Это можно сравнить с безусловным базовым доходом. Сверх этого, ее можно увеличивать добровольными переводами, никак привязанными к содержанию и рейтингу ваших высказываний.

  3. Каждый "из коробки" обладает банхаммером, но его мощность ограничивается накопленной (и полученной от других пользователей) валютой. Поэтому систему не получится использовать для злоумышленного канселинга.

  4. Каждый может разбанить любого другого если у него достаточно валюты. Нет тотальной отмены с глубоким минусом, нет минуса которого нельзя отменить (как -100 на Хабре), нет лимитов прощения, было бы только желание подождать немного или попросить любого пользователя помочь вернуться сразу!

В чем цели эксперимента?

Проверить возможны ли новые, горизонтальные подходы во взаимодействии пользователей? Возможен ли отказ от иерархии? Можно ли общаться в интернете без концепции владения хостом? Можно ли автоматизировать модерацию? Успех эксперимента может стать толчком к расцвету таких систем. Эксперимент абсолютно некоммерческий, нет никакой рекламы, нет механизма извлечения выгоды. Я делаю это ради интереса посмотреть что получиться (и удовольствия пронаблюдать вышеописанную механику в действии).

Как поучаствовать?

Зайти в чат где все это реализовано: t.me/habr_experimental
В чате нет владельцев и админов, а вместо них подлючена и ждет наплыва пользователей вышеописанная система. Полагаю что тематика обсуждений может быть любая, на интересные целевой аудитории Хабра темы, и помните что никто ни в чем не может ограничить вас, кроме вас самих и таких же как вы людей.

Исходный код чата

Эта статья о социальном эксперименте, однако она была бы не для Хабра без технических деталей. Поэтому для тех кому это интересно, подробные принципы работы валюты и UX описаны в этой статье: habr.com/ru/post/556292/
Исходный код системы доступен на GitHub: github.com/demidko/timecobot
Для бекенда использован один из лучших виданных мною языков - Kotlin, за что хочу сказать здесь спасибо его разработчикам.

Возможно эта статья обрушит мою карму здесь, а возможно мы увидим как появится новый мир свободных интернет-систем. Напоследок хочу пожелать всем читавшим, эксперементируйте чаще и делайте это ради интереса!

Подробнее..

Распознавание команд

03.06.2021 20:19:56 | Автор: admin

При разработке ботов для Telegram и других месенджеров, периодически возникает задача распознавания и выполнения запросов, высказанных человеческим языком. Именно эта "фишка", по некоторому мнению, и является главным отличием ботов от приложений командной строки. Под катом описан собственный фреймворк для исполнения произвольных речевых команд. Описания ключевых концепций сопровождены примерами на языке Kotlin.

За основу для распознания речи возьмем нормализованные семантические представления. Их выбор обусловлен прежде всего простотой и легкостью реализации. Начнем с базиса, пример из исходников фреймворка:

/** Правило проверяет лексему на соответствие */typealias Rule = (String) -> Boolean/** Нормализованное семантическое представление */open class Semnorm(vararg val rules: Rule)/** Правило задает стемы для семантических представлений */fun stem(vararg stems: String): Rule = { stems.any(it::startsWith) }/** Правило задает точные соответствия для семантических представлений */fun word(vararg words: String): Rule = { words.any(it::equals) }/** Проверяем слово на соответствие семантике */fun String.matches(norm: Semnorm) = norm.rules.any { it(this) }

Теперь у нас появилась возможность задавать предопределенные нормализованные семантические представления в виде объектов:

object Day : Semnorm(stem("day", "суток", "сутк", "дня", "ден", "дне"))

Фреймворк ставит их в соответствие лексемам входящих фраз, и предложение начинает выглядеть, например так:

assertThat(  "забань васю на 5 минут".tokenize(),   equalTo(   listOf(     Token("забань", Ban),      Token("васю", null),     Token("на", null),      Token("5", Number),     Token("минут", Minute)   )  ))

С распознаванием речи мы разобрались. Код токенизатора приложен в репозитории, доступном в конце статьи. Перейдем к исполнению команд из речи. А вот здесь и начинается самое интересное: фреймворк позволяет для каждого семантического представления навесить заданное поведение. Снова простейший пример, как распознать запрос справки на двух языках:

object Help : ExecutableSemnorm(stem(  "помощ", "справк", "правил", "help",   "rule", "faq", "start", "старт",)) {  override fun execute(bot: Botm: Message) {    val faq = message.from.relatedFaq()    bot.sendMessage(m.chat.id, faq)  }}

Что насчет более сложного поведения, зависящего от различных слов в предложении? Оно тоже поддерживается, вот как, например, исполняется, уже известное из тестов предложение забанить Васю:

object Ban : DurableSemonrm(stem(  "ban", "block", "mute", "бан", "блок",  "забан", "завали", "замьют",)) {  override fun execute(    bot: Bot, attackerMessage: Message, duration: Duration) {    val victimMessage = attackerMessage.replyToMessage    val victimId = victimMessage.from.id    val untilSecond = now().epochSecond + duration.inWholeSeconds    bot.restrictChatMember(      attackerMessage.chat.id, victimId, untilSecond)  }}

Откуда это семантическое представление знает о своей продолжительности? Дело в том, что ему вовсе не обязательно парсить всю цепочку токенов целиком. Достаточно задать только минимально необходимое поведение для каждого представления, например для времени:

object Week : Semnorm(stem("week", "недел")) {  override fun toDuration(number: Long) =     days(number) * 7}

Или для любых команд, зависящих от времени:

class DurableSemnorm(vararg rules: Rule) : ExecutableSemnorm(*rules) {  final override fun execute(    token: Iterator<Token>, bot: Bot, m: Message) =       execute(bot, message, token.parseDuration())  abstract fun execute(bot: Bot, m: Message, duration: Duration)}

Благодаря такой архитектуре, нам больше не приходится думать о запутанной логике работы интерпретатора. Достаточно просто определить желаемые атрибуты для семантических представлений и наслаждаться результатом. Пример бота, использующего эту концепцию, можно посмотреть на Github: https://github.com/demidko/timecobot

Подробнее..

Telegram bot ML универсальный алгоритм совмещения

31.03.2021 00:12:34 | Автор: admin

Пишу модели для кейсов на Kaggle, изучаю чужие и вдохновляюсь. Все статьи с описанием того, как внедрить их в веб-проект, для меня, школьника Junior Frontend'а, дают overhead сложной инфы, я же хочу просто "позаимствовать" любую крутую модель и быстро внедрить в свой сервис. Руки зачесались придумать универсальный алгоритм, так что решение было найдено быстро.

Приступаем. 1 шаг

Я хочу взять формат большинства моделей с Kaggle, чтобы в дальнейшем было легко заимствовать чужой код любой сложности не разбираясь в нем. Бот для телеги пишем на Python 3.9, с помощью либы pyTelegramBotAPI, для решения проблемы совместимости расширений .py и .ipynb юзаем ipynb.

И так, устанавливаем зависимости:

pip install pyTelegramBotAPIpip install ipynb

Заходим на Kaggle и выбираем понравившуюся модель. Я начну с классического кейса Titanic - Machine Learning from Disaster, заимствую это решение (Titanic Random Forest: 82.78%), перетаскиваю в проект с ботом.

Устанавливаем появившиеся зависимости:

pip install <имя>

Пилим бота. 2 шаг

Создаем новый файл и импортируем в него наши либы:

import telebotfrom ipynb.fs.defs.ml import is_user_alive

В ipynb.fs.defs.ml вместо ml впишите имя модуля, в котором находится модель, а вместо is_user_alive имя будущей функции, которую будет эта модель реализовывать. В нашем случае она предсказывает, выживет ли пассажир.

Инициализируем бота, вставляем токен (получите его через @BotFather):

bot = telebot.TeleBot('token')

Пишем хэндлер на команду /start, описываем в нем как юзать бота и формат ввода дынных. Чтобы его определить, изучите тестовый датасет и поэксперементируйте с вводом своих строк.

@bot.messagehandler(commands=['start'])def welcome(message):      bot.sendmessage(message.chat.id, 'Привет! Назови Класс билета, Имя (одним словом), '                  'Пол (male/female), Возраст, Прибыл ли он с супругом (1-да, 0-нет), '                  'с Ребенком (1-да, 0-нет), Номер билета, его Стоимость и Порт '                  'пасадки, - а я предскажу, выжил ли этот пассажир на Титанике!')

Теперь какой бы текст юзер не ввел, мы воспринимаем его как данные пассажира. Превращаем их в лист и приводим к формату тестового датасета:

@bot.messagehandler(contenttypes=['text'])def answer(message):      bot.sendmessage(message.chat.id, 'Анализируем')      passengerdata = message.text.split()      passengerdata.insert(0, 0)      passengerdata.insert(9, ',')      passengerdata[2] = '"', passengerdata[2], '"'

Как видите, в нашем случае в начало было необходимо добавить бесполезный айдишник, на 9е место незначащую запятую, а имя пассажира заключить в кавычки.

Модифицируем модель. 3 шаг

В файле модели поиском cntrl+f выделяем и удаляем все разделители на ячейки #%% кроме первого. Переносим все импорты в начало и табаем массив кода после них. Теперь оборачиваем его в нашу функцию с аргументом в виде пользовательских данных:

<импорты>def is_user_alive(user_data):  <весь остальной код>

Куда-нибудь в самое начало добавляем код, вписывающий в тестовый датасет наши данные:

with open(os.path.join('input', 'test.csv'), "a") as fp:      wr = csv.writer(fp, dialect='excel')      wr.writerow(user_data)

Predictions чаще всего содержит результат работы модели (проверьте ваш случай). Так как данные пользователя содержались в конце тестового датасета, возвращаем последнюю его строку (return пишем в конце файла):

return predictions[len(predictions)-1:]['Survived']

Допиливаем бота. 4 шаг

В функции answer создаем переменную с результатом анализа, она будет содержать 0 или 1 в странном формате. Короче, в нашем случае необходимо ответ дополнительно перевести в числовой тип:

answer = is_user_alive(passenger_data)if int(answer) == 1:      bot.sendmessage(message.chat.id, 'Везунчик! Видимо, этот пассажир успел на спасательную шлюпку.') elif int(answer) == 0:      bot.send_message(message.chat.id, 'Увы, но Титаник ваш пассажир не пережил бы.')

Создаем функцию с предложением чекнуть кого-нибудь еще, вызываем ее из answer с message аргументом:

def doagain(message):      bot.sendmessage(message.chat.id, 'Проверить живучесть кого-нибудь еще?')

Запускаем полинг:

while True:      try:            bot.polling(none_stop=True)      except ():            time.sleep(5)
Результат

Все! Довольно просто, правда?

Если не очень, можешь глянуть видео версию:

Код: https://github.com/freakssha/ml-bot-titanic

Это спидран от чешущихся рук, он не оптимизированный и его можно много где улучшить, но я пока не знаю как. Если вы понимаете, как это сделать, не теряя простоты и универсальности - напишите, прошу!

GitHub, Inst, VK

Подробнее..

Telegram бот на Firebase

26.04.2021 14:21:23 | Автор: admin

В основном, про Firebase рассказывают в контексте создания приложений под IOS или Android. Однако, данный инструмент можно использовать и в других областях разработки, например при создании Telegram ботов. В этой статье хочу рассказать и показать насколько Firebase простой и удобный инструмент (а ещё и бесплатный, при разумных размерах проекта).


Motivation

Ровно посередине апреля я очнулся от работы и вдруг вспомнил, что у меня ещё не написан диплом, а сдавать его через месяц - полтора. У меня была заброшенная научная статья на достаточно скучную тему, делать на её базе диплом мне уж совсем не хотелось. Нужен был глоток свежего воздуха - какой-нибудь новый проект.

В середине февраля я с ребятами из веб студии обсуждал идею создания приложения по подбору квартир с рекомендательной системой, которая анализировала бы изображения интерьеров и подстраивалась под предпочтения пользователя. Так как мой диплом должен быть на тему Computer Vision, то я решил развить эту тему. Да, и было придумало прикольное название - Flinder (Flats Tinder).

Если погружаться в детали, то для создания рекомендательной системы, работающей с изображениями, необходимо построить пайплайн конструирования эмбедингов на базе изображений. Эмбединг - это вектор, содержащий в себе информацию о изображении и являющийся результатом работы нейронной сети.

В частности, меня вдохновила одна научная статья про DeViSE: A Deep Visual-Semantic Embedding Model. Мне было интересно попробовать такие эмбединги.

В чём суть?

Если кратко, то авторы статьи обучили нейронную сеть предсказывать не конкретные классы изображений, по типу "кошка", "собака", а векторные представления названий классов. Это те самые векторные представления, для которых "King - Man + Woman = Queen".

Такой подход, объединяет визуальное представление нейросети об изображении со структурой языка. Это приводит, например, к тому что модель может предсказать класс, которого не было в датасете, но который семантически близок к классу из датасета.

Какого бота я делал?

Для рекомендательной системы важно настроить алгоритм сбора данных о взаимодействии пользователей с контентом. В такой ситуации сложно придумать что-то более быстрое в разработке, чем телеграм бот.

Итак, телеграм бот:

  • Присылает пользователю изображение и просит его оценить

  • Получает оценку от пользователя

  • Сохраняет оценку пользователя в базу данных

  • *киллер фича* - удаляет изображение из диалога, если оно не понравилось пользователю

На первом этапе работы бот присылает пользователю случайные изображения. Но при последующем развитии проекта и интеграции рекомендательной системы бот будет присылает всё более и более релевантные фотографии.

Да, также важно раздобыть контент, который пользователи будут оценивать. Немного заморочившись я скачал сразу 20.000 изображений с интерьерами с Pinterest. Это были и запросы как скандинавский интерьер квартиры так и готический интерьер дома. Старался собрать как можно более разнообразный (репрезентативный) набор изображений.

Изображения добывал с помощью библиотечки pinterest-image-scraper (Там есть баги и она не супер удобная, но мне её хватило).

Firebase

Меня немного смущал момент отправки изображений телеграм ботом. Получившаяся база изображений в 20.000 штук весила примерно 1.5 гигабайта и мучаться с переносом её на сервер мне уж совсем не хотелось.

Тут я подумал о том, что было бы классно выложить все фотографии на какой-нибудь облачный сервис, и дальше в телеграмм боте использовать только ссылки на изображения, а не сами изображения. А ссылки на изображения (или идентификаторы изображений) и оценки пользователей можно хранить в Firebase Realtime Database.

Перед этим я быстро проверил, поддерживает ли библиотека pyTelegramBotAPI отправку изображений ссылками. Метод send_photo спокойно работал с ссылками на изображения, так что я решил дальше использовать этот подход.

Прежде я работал только с Firebase Realtime Database, но про удобство Firebase Storage был наслышан.

Инициализация проекта в Firebase

Итак, чтобы начать работать с Firebase вам необходимо зарегистрироваться на этом сервисе и создать там проект. После чего у вас откроется вкладка Project Overview.

Project OverviewProject Overview

Для того чтобы получить доступ к функциям Firebase из кода необходимо скачать ключи доступа к проекту. Сделать это можно нажав на значок шестерёнки в верхнем левом углу, справа от надписи Project Overview, и выбрать пункт Project Settings. Затем, на открывшемся экране нужно выбрать Service Accounts и нажать Generate new private key.

После чего, выбрав в левой вкладке меню Realtime Database и Storage можно создать соотвествующие базы данных. В проект на питоне подключить эти базы данных можно следующим способом.

import firebase_adminfrom firebase_admin import credentialsfrom firebase_admin import dbfrom firebase_admin import storagecred = credentials.Certificate("/path/to/secret/key.json")default_app = firebase_admin.initialize_app(cred, {  'databaseURL': 'https://realtime-db-name',    'storageBucket' : 'storage-bucket-local-name'})bucket = storage.bucket()

Где правые части внутри выражения initialize_app есть условные ссылки на названия ваших баз данных внутри проекта в Firebase. После инициализации у вас будут доступны две базы данных

  • db - объект Realtime Database. Данные хранятся в виде одного JSON дерева. В случае работы с питоном - это по сути объект dict.

  • bucket - объект Storage, по сути, обёртка над Google Storage, позволяющая по API загружать и скачивать объекты.

Далее покажу несколько примеров использования этих двух баз данных.

Firebase Realtime Database

Обожаю эту базу данных и готов петь ей дифирамбы. Она очень удобная, быстрая, надёжная, а главное - никакого SQL! Это JSON based Database. Но хватит похвалы, давайте посмотрим, как с ней работать.

Например, у нас есть несколько пользователей, которые хранятся в users_database.

users_databse = {"1274981264" : {"username" : "user_1","last_activity" : 1619212557},"4254785764" : {"username" : "user_2","last_activity" : 1603212638}}

Добавить их в в Realtime Database мы можем так:

db.reference("/users_databse/").set(users_databse)

Также мы можем добавить и следующего пользователя таким вот образом:

user_3_id = "2148172489"user_3 = {"username" : "user_3","last_activity" : 1603212638}db.reference("/users_database/" + user_3_id).set(user_3)

Этот код добавит user_3 в users_database

Получить данные можно так.

user_3 = db.reference("/users_database/" + user_3_id).get()users_databse = db.reference("/users_databse/").get()

Это вернет объекты формата Python dict

Стоит отметить, что массивы в Realtime database хранятся в следующем виде.

a = ["one", "two", "three"]firebase_a = {"0" : "one","1" : "two","2" : "three"}

То есть также в формате json

И ещё один нюанс, Realtime Database не хранит объекты None и [] То есть код

db.reference("/users_database/" + user_3_id).set(None)

Приведёт к ошибке

А код

db.reference("/users_database/" + user_3_id).set([])

Удалит данные user_3

Также стоит добавить, что если внутри вашего объекта в питоне есть какое-либо поле, значение которого есть None или [], то в объекте, загруженном в Realtime Database этих полей не будет. То есть:

user_4 = {"username" : "user_4","last_activity" : 4570211234,  "interactions" : []}# Но user_4_in_fb = {"username" : "user_4","last_activity" : 4570211234}

На самом деле, методами get() и set() всё не ограничивается. По ссылке вы можете посмотреть документацию по firebase_admin.db

Firebase Storage

Вернёмся к Firebase Storage. Допустим, у нас на локальном диске хранится изображение по пути image_path Следующий код добавит это изображение в Storage.

def add_image_to_storage(image_path):    with open(image_path, "rb") as f:        image_data = f.read()    image_id = str(uuid.uuid4())        blob = bucket.blob(image_id + ".jpg")        blob.upload_from_string(        image_data,        content_type='image/jpg'    )

Где image_id - уникальный идентификатор изображения.

С получением доступа к изображению всё чуточку сложнее. blob имеет формат

blob.__dict__
blob.__dict__ = {'name': 'one.jpg', '_properties': {'kind': 'storage#object',  'id': 'flinder-interiors/one.jpg/1619134548019743',  'selfLink': 'https://www.googleapis.com/storage/v1/b/flinder-interiors/o/one.jpg',  'mediaLink': 'https://storage.googleapis.com/download/storage/v1/b/flinder-interiors/o/one.jpg?generation=1619134548019743&alt=media',  'name': 'one.jpg',  'bucket': 'flinder-interiors',  'generation': '1619134548019743',  'metageneration': '1',  'contentType': 'image/jpg',  'storageClass': 'REGIONAL',  'size': '78626',  'md5Hash': 'OyY/IkYwU3R1PlYxeay5Jg==',  'crc32c': 'VfM6iA==',  'etag': 'CJ+U0JyCk/ACEAE=',  'timeCreated': '2021-04-22T23:35:48.020Z',  'updated': '2021-04-22T23:35:48.020Z',  'timeStorageClassUpdated': '2021-04-22T23:35:48.020Z'}, '_changes': set(), '_chunk_size': None, '_bucket': <Bucket: flinder-interiors>, '_acl': <google.cloud.storage.acl.ObjectACL at 0x7feb294ff410>, '_encryption_key': None}

Где есть selfLink и mediaLink, однако доступ к изображению по этим ссылкам - ограничен и доступен только при наличии определенных прав доступа, которые настраиваются в консоли Firebase.

В своём проекте я постарался сделать всё максимально просто и поэтому воспользовался методом blob.generate_signed_url(...). Этот метод генерирует ссылку, которая имеет определённое время жизни. Время жизни ссылки является параметром метода.

Следующий метод генерирует ссылку, живущую 10 минут.

def get_image_link_from_id(image_id):    blob = bucket.blob(image_id + ".jpg")    time_now = int(time.time() // 1)    ttl = 600    return blob.generate_signed_url(time_now + ttl)

Telegram Bot

Не буду вдаваться в подробности написания телеграм ботов, так как на эту тему статей много (простой туториал, супер подробная статья). Пройдусь только по основным моментам.

Как выглядит бот?

В своём проекте на pyTelegramBotAPI я использовал InlineKeyboardButton, состоящую из эмоджи и callback_query_handler, обрабатывающий нажатия на кнопки.

keyboard = types.InlineKeyboardMarkup(row_width = 3)nott = types.InlineKeyboardButton(text="no_emoji", callback_data='no')bad = types.InlineKeyboardButton(text="bad_emoji", callback_data='bad')yes = types.InlineKeyboardButton(text="yes_emoji", callback_data='yes')keyboard.add(nott, bad, yes)
Небольшой баг хабра

Пока писал статью столкнулся с тем, что редактор статей Хабр в браузере Safari не переваривает эмоджи внутри вставок с кодом. Если что, в моём боте кнопки имеют такой вот вид, ниже скрин кода.

Реакции пользователей я храню в Realtime Database. Добавляю их туда следующим образом.

def push_user_reaction(chat_id, image_id, reaction):  db_path = "/users/" + str(chat_id)+ "/interactions/"+ str(image_id)db.reference(db_path).set(reaction)

База данных Firebase Realtime Database имеет следующий вид

users - база данных пользователей.

Для каждого пользователя в разделе interactions мы храним взаимодействия пользователя с изображениями. last_image_id и last_message_id - элементы логики работы телеграмм бота. Что-то типо конечного автомата.

Да, и идентификаторы пользователей в базе данных - это telegram id пользователей (chat_id для библиотеки telebot).

usersusersinteractionsinteractions

interiors_images - база идентификаторов изображений. В ней хранятся метаданные изображений, а также дублируются реакции пользователей.

interiors_imagesinteriors_images

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

Костыль

Собственно говоря сам костыль.

IMAGES_UUIDS = Nonedef obtain_images_uuids():    global IMAGES_UUIDS    IMAGES_UUIDS = db.reference("/images_uuids/data").get()obtain_images_uuids()def get_random_image_id():    image_id = np.random.choice(IMAGES_UUIDS)    return image_id

Да, на первом этапе, изображения, отправляемые пользователю, выбираются случайным образом.

Firebase Storage выглядит таким вот образом. Можно заметить, что названия изображений в Storage есть просто идентификаторы изображений + их расширение.

Также, огромным плюсом облачных баз данных является то, что можно хранить состояния взаимодействия пользователя с ботом. И если вдруг сервер решит перезапустить код бота, то это состояние сохранится. (Хотя если пользоваться обычной базой данных состояние тоже сохранится, так что это такой, притянутый за уши плюс)

Вообще, из недостатков библиотеки pyTelegramBotAPI - это то, что она медленная. И под напором сообщений от большого количества пользователей что-то вполне может пойти не так. Так что в будущем я планирую использовать другую, более мощную библиотеку. Проект в нынешнем виде - это буквально один вечер работы и поэтому я использовал знакомые мне инструменты, с которыми я уже работал.

Деплой на сервер

Последнее время я стал адептом докера, поэтому и этот свой проект я размещал на сервер с помощью докера. Пройдусь по основным моментам, которые я использовал в проекте.

Dockerfile

FROM python:busterCOPY requirements.txt /tmp/RUN pip install -r /tmp/requirements.txtRUN mkdir /srcWORKDIR /srcCOPY ./src .CMD python3 /src/code/bot.py
requirements.txt
pyTelegramBotAPIfirebase-admingoogle-cloud-storagenumpy

Где src - это место монтирования docker volume, который я создал до этого командой

docker volume create \            --opt type=none \            --opt o=bind \            --opt device=/home/ubuntu/Flinder/src \            --name flinder_volume

После чего собрал образ и запустил контейнер следующим образом, где флаг-v монтирует созданные ранее flinder_volume в директорию src внутри докер контейнера.

docker run -d \--network=host \--name flinder_bot \--restart always \-v "flinder_volume:/src" devoak/flinder:1.0

Ну и полезное замечание, что у команды docker run можно указать прекрасный параметр --restart always, который обеспечит постоянную работу бота на сервере.

До этого я делал через systemctl, что было сложнее и менее удобно.

Заключение и капелька пиара

Flinder - именно так называется мой проект (Flats Tinder)Flinder - именно так называется мой проект (Flats Tinder)

Надеюсь, моя статья была полезна. Хочу привнести в сообщество программистов такую идею, что работать с Firebase - это очень просто, приятно и удобно, а главное - бесплатно, при разумных размерах проекта.

Более того, использование Firebase не ограничивается Телеграм ботами, недавно я сделал целый промышленный парсер инстаграмма на основе Firebase Realtime Database, о чём я тоже планирую написать статью.

Касательно моего проекта, буду благодарен, если вы повзаимодейтсвуете с моим ботом, там собраны классные фотографии интерьеров. Несколько часов сидел на Пинтересте и выбирал наиболее эстетичные категории. Добавил даже интерьеры квартир с двойным светом и интерьеры домов в стиле шале. С помощью бота планирую собрать данные для того чтобы проверить гипотезу о том, что эмбединги DeViSE работают эффективнее обычных эмбедингов изображений в контексте рекомендательных систем.

По поводу других проектов, оставлю свой телеграм канал. Периодически пишу туда про проекты, которыми занимаюсь (а их много, есть даже нейросети для театра). Более того, если вам вдруг нужен сайт или приложение с продвинутым бэкендом, то милости прошу, моя веб студия. Занимаемся проектами любой сложности.

Подробнее..

Telegram-бот на Python для создания задач в MS Outlook и заметок в Evernote

29.03.2021 10:21:19 | Автор: admin

В MS Outlook есть прекрасный раздел задач. Это удобно и быстро. Можно с утра (или с вечера) накидать себе задачек на день и постепенно расщёлкивать их. Вторым уровнем группируем задачи по матрице Эйзенхауера или используем любой другой удобный вам инструмент тайм-менеджмента. Одна проблема с этими задачами: для их создания надо заходить в Outlook, щёлкать, писать, нажимать Enter, двигать в нужную группу. Это всё долго и не всегда удобно. Но есть в Outlook также правила, позволяющие письма содержащие определённые слова в теме автоматически делать задачами. Ещё быстрее и проще получится, если такие письма отправляются прямо из Telegram. О простейших ботах помогающих создавать задачи в MS Outlook и заметки в Evernote без необходимости сложных интеграций.

Бот: Telegram + Python + Docker

Строго говоря ботов два. Пока не получилось совместить весь функционал в одном боте так, чтобы это было удобно как переслать/накидать сообщение и нажать на кнопку "Send". Немного о стеке. Python был выбран за простоту кода и доступность для менеджеров проектов без глубоких познаний в программировании. Docker удобно упаковать бота в контейнер и запускать в нём, без необходимости думать о версиях Linux на хостинге, настройках сервисов и так далее. В качестве хостера использовался DigitalOcean, в котором Docker-контейнеры разворачиваются легко и просто.

Конечно же использовался не чистый Telegram API, а удобный telebot. Для отправки писем вполне подошла стандартная библиотека smtplib. Для сокращения текста используется textwrap. А формированием сущности сообщения занимается тоже стандартная email.mime:

import osimport telebotimport smtplibimport textwrapfrom email.mime.text import MIMEText

Пароли в контейнер кладём аккуратно. Чтобы не хранить их открытым текстом в исходнике, используем переменные окружения:

#ConfigurationCFG_TOKEN = os.environ.get('CFG_TOKEN') #TELEGRAM_BOT_TOKENCFG_SMTP_LOGIN = os.environ.get('CFG_SMTP_LOGIN') #'%YOUR_SMTP_LOGIN_ON_YANDEX%'CFG_SMTP_PASS = os.environ.get('CFG_SMTP_PASS') #'%YOUR_SMTP_PASS_ON_YANDEX%'CFG_SMTP_FROM = os.environ.get('CFG_SMTP_FROM') #'%FROM_EMAIL_ADDRESS%'CFG_SMTP_TO = os.environ.get('CFG_SMTP_TO') #'%TO_EMAIL_ADDRESS%'

При запуске Docker-контейнера берём переменные откуда нам удобно, например из файла .env или переменной окружения на хостовой машине.

Бот частный. Он не предназначен для раздачи доступов всем подряд. Поэтому в самом начале проводим проверку отправителя. Мне было лень писать обработчик значений с разными типами, поэтому я написал обработчик исключения:

try:    CFG_OWNER_ID = int(os.environ.get('CFG_OWNER_ID')) #YOUR_USER_ID_IN_TELEGRAMexcept:    CFG_OWNER_ID = os.environ.get('CFG_OWNER_ID')

Собственно письмо формируем по следующему алгоритму. Если текста сообщения менее или равна 40 символам, то помещаем его целиком в тему письма, а в теле пишем стандартный текст. Если более - помещаем первые 40 символов, а остаток кладём в тело письма. Это точно позволяет обойти какие-то правила антиспам-фильтра Яндекса, который использовался для рассылки сообщений.

msg = MIMEText('')if len(txt) > 40:txt = textwrap.shorten(txt, width=40, placeholder="...") #Лишнее обрезаем тремя точками  msg = MIMEText(message.text)else:msg = MIMEText("Задача из Telegram")

Если пересылаем сообщение другого пользователя (например, начальника) и делаем его сообщение задачей, то подсвечиваем в теме письма имя нашего контакта:

if "forward_sender_name" in message.json:txt = f'[{message.json["forward_sender_name"]}] {txt}'elif "forward_from" in message.json:  txt = f'[{message.json["forward_from"]["first_name"]}] {txt}'

Метим наше сообщение в теме как "[TASK]", чтобы MS Outlook мог его отличить от обычных писем и обработать правилами:

msg['Subject'] = f'[TASK] {txt}'

Далее стандартно отправляем наше письмо, не забывая вернуть сообщение с успехом или ошибкой при отправке:

try:server = smtplib.SMTP_SSL('smtp.yandex.ru:465')  server.login(CFG_SMTP_LOGIN, CFG_SMTP_PASS)  server.sendmail(CFG_SMTP_FROM, CFG_SMTP_TO, msg.as_string())   bot.send_message(message.from_user.id, "Задача отправлена в Outlook")  server.quit()except Exception as err:  bot.send_message(message.from_user.id, f"При отправке сообщения произошла ошибка: {str(err)}")

Полный код бота доступен здесь: https://github.com/nsuvorov83/sendtask-bot

Настройка MS Outlook

Правила MS Outlook настраиваются просто:

А как отправлять заметки в Evernote?

Для того, чтобы была возможность отправить сообщение в бота, которое автоматом станет заметкой в Evernote нужно написать код чуть по сложнее. Принцип тот же: отправляем сообщение, которое потом превращается в e-mail отправляемый на специальный адрес. Все письма поступающие по этому адресу становятся заметками.

Ключевой момент здесь - обработка типов сообщений и вложений. Определяем функции-обработчики для различных типов сообщений Telegram:

def _is_photo(message):        return message.photodef _is_document(message):        return message.documentdef _is_text(message):    return message.textdef _is_caption(message):    return message.caption  #А вот как определяется сам тип сообщения. Если тип некорректный, то вернётся Falseif _is_photo(message):#Photo handler  cached_files = getPhotoCached(message)  #Insert into e-mail  for f in cached_files:  with open(f, 'rb') as file:    msg.attach(MIMEImage(file.read()))

Пересылаемые фотографии и документы обязательно надо закешировать прежде чем их можно будет вложить в E-mail. Суть функции одна, поэтому привожу её только для фото:

def cachFile(file_info):    dt = datetime.datetime.now()    timestamp = dt.timestamp()    downloaded_file = bot.download_file(file_info.file_path)    ext = os.path.split(file_info.file_path)[1].split('.')[1]    cached_file_name = str(timestamp) + '.' + ext    src = tempfile.gettempdir() + os.path.sep + cached_file_name    with open(src, 'wb') as new_file:        new_file.write(downloaded_file)    return src  def getPhotoCached(message):    cached_files = []    ff = message.photo[-1]    file_info = bot.get_file(ff.file_id)    asrc = cachFile(file_info)    cached_files.append(asrc)    return cached_files  if _is_photo(message):        #Photo handler        cached_files = getPhotoCached(message)        #Attach into e-mail        for f in cached_files:            with open(f, 'rb') as file:                msg.attach(MIMEImage(file.read()))

Тему сообщения формируем аналогично, как для отправки задач, но можем добавить к ней стандартные теги. Мне удобно метить все сообщения из Telegram а также добавлять тег текущего года. Можно также предусмотреть ситуацию, когда текста сообщения нет и сформировать стандартный заголовок для таких заметок:

if len(txt) > 30:txt_subject = textwrap.shorten(txt, width=30, placeholder="...")elif len(txt) == 0:  #Стандартный заголовой для заметок без текста включает "Из Telegram", текущую дату и время  now = datetime.datetime.now()txt_subject = 'Из Telegram ' + str(now)else:txt_subject = txtmsg['Subject'] = f'{txt_subject} #{d.year} #из_telegram'

Процесс отправки e-mail стандартный и описан выше.

Полный код бота найдёте здесь: https://github.com/nsuvorov83/sendevn-bot

Подробнее..

Подборка телеграм-каналов для DevOps инженеров

13.03.2021 14:14:35 | Автор: admin

Приветствую, братцы!

Задача получения актуальной информации и совета опытных коллег сегодня актуальна как никогда. С одной стороны, сложно превзойти крупнейшие ИТ-сообщества в Slack. С другой стороны, важно иметь контакт с коллегами в нашей стране, в своем городе. Телеграм за последние годы стал крупнейшей площадкой для русскоязычного ИТ-сообщества, присоединяйтесь, не отставайте :)

Подборка телеграм-каналов и чатов:

Вакансии

Devops Jobs - Вакансии и резюме

Jobs for Devs & Ops - Вакансии для инженеров и разработчиков

Новостные каналы

Mops DevOps - Kubernetes, DevOps, SRE и многое другое

DevOps Deflope News - Новостной канал

Записки админа - Linux и администрировании серверов

k8s (in)security - Канал о (не)безопасности Kubernetes

Мир IT c Антоном Павленко - IT новости, статьи и видео

Конференции

DevOpsConf Channel - Информационный канал профессиональной конференции по эксплуатации и devops DevOpsConf Russia

Meetup Moscow - анонсы конференций

Инструменты DevOps

terraform_ru - Русскоязычный чат Hashicorp Terraform

pro_ansible- Чат для взаимопомощи по Ansible

Docker_ru- Русскоговорящее сообщество по экосистеме Docker (чат)

RU.Docker - Официальное Русское Сообщество (чат)

ru_gitlab- Русскоговорящая группа по GitLab

ru_jenkins- Русскоговорящая группа по Jenkins

Инфраструктура

Kubernetes- Общаемся на темы, посвященные Kubernetes, конфигурации и возможностям

istio_ru - Чат про Mervice Mesh в целом и Istio в частности

Вокруг Kubernetes в Mail.ru Group митапы по Kubernetes, DevOps, открытым технологиям в Mail.ru Group и немного проKubernetes как сервис

Envoy Proxy- Делимся опытом, экспертизой, советами и фэйлами :)

nginx_ru - Сообщество пользователей nginx, новости, обсуждения конфигураций

SDS и Кластерные FS - Обсуждаем Software-defined storage, кластерные файловые системы, блочные хранилища, стратегии построения хранилища и все что с ними связанно (Linstor, DRBD, ZFS, LVM, Ceph, GlusterFS, Lustre, MooseFS, LizardFS, mdadm, S3, iSCSI, NFS, OrangeFS, OCFS, GFS2)

Грефневая Кафка (pro.kafka)- Здесь топят за Кафку (Apache Kafka )

pro.kafka- Чат для добросовестных господ и дам, посвящённый Apache Kafka

DBA- Общаемся и обсуждаем темы, посвященные DBA, PostgreSQL, Redis, MongoDB, MySQL...

Облачные провайдеры

AWS_ru- Чат про Amazon Web Services

AWS notes- Канал про Amazon Web Services

Yandex.Cloud - Новости от команды платформы Yandex.Cloud

IT-журнал Завтра облачно - Блог команды Mail.ru Cloud Solutions (MCS)

Мониторинг и сбор логов

VictoriaMetrics_ru - Чат для обсуждения VictoriaMetrics

Церковь метрик- Канал про Метрики. Метрики. Метрики.

ru_logs - ElasticSearch, Graylog, Mtail, rsyslog и все такое прочее

Мониторим ИТ- Канал о мониторинге ИТ-инфраструктуры и приложений

Друзья, очень вероятно, что я мог забыть про какой-нибудь хороший, полезный и всеми любимы телеграм-канал. Жду ваши идеи в комментариях.

Подробнее..
Категории: Kubernetes , Gitlab , Devops , Nginx , Docker , Monitoring , Istio , Telegram , Aws , Envoy

Логирование в телеграм, или история о том, как я сделал питон библиотеку

24.03.2021 16:21:32 | Автор: admin

Модуль logging в питоне - это мощный инструмент в разработки. Он помогает отследить ошибки, наблюдать за работой приложения и даже собирать статистику об использовании вашего сервиса. В этой статье я расскажу, как можно расширить возможности этого модуля и причем тут телеграмм.

Intro

Давным-давно, а точнее несколько месяцев назад, накануне Нового года, я сидел дома и решал задачу по машинному обучению. Связана она была с нейронными сетями и классификацией текстов, поэтому я естественно пользовался бесплатным GPU от гугла (colab). За окном шел снег, а модели обучались ну уж очень долго. Обучать модель оставалось всего несколько минут, как вдруг появляется уведомление, что подключение к runtime потеряно, а это значит, что обученную модель и сабмиты из этого runtime скачать я не смогу, и все придется начинать заново.

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

Копировал я этот код из ноутбука (jupyter notebook) в ноутбук, а потом осознал, что это можно встроить в модуль logging и завернуть в библиотеку, чтобы не таскать каждый раз большие куски кода, а использовать всего пару строк.

Logging.handlers

Понятно было, что за основу надо взять модуль для логирования, встроенный в питон. Очевидно, потому что изобретать свой велосипед мне не хотелось, а еще потому что, для использования в приложениях пришлось бы переписывать весь код логирования. Надо было найти способ перехватывать логи, и пересылать их в телеграмм. К счастью, в logging есть такой класс, как StreamHandler. Не буду вдаваться в подробности, но с помощью него можно сделать свою функцию, которая будет запускаться для каждой новой строки в логах и отправлять ее в телеграмм.

Tg-logger

И вот, держа в голове все вышеописанные идеи, я отправился писать свою библиотеку. Вот, что получилось.

Для тех, кому лень запускать код, но хочется понять, как это будет работать, я сделал бота @tg_logger_demo_bot.

Чтобы воспользоваться библиотекой нужно:

  • создать телеграмм бота (как это сделать описано здесь)

  • получить свой user_id (это можно сделать через @tg_logger_demo_bot с помощью команды /id)

Установим библиотеку через pip.

pip install tg-logger

Рассмотрим код примера

import loggingimport tg_logger# Telegram datatoken = "1234567890:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"users = [1111111111]# Base loggerlogger = logging.getLogger('foo')logger.setLevel(logging.INFO)# Logging bridge setuptg_logger.setup(logger, token=token, users=users)# Testlogger.info("Hello from tg_logger by otter18")

Особо интересна для нас строка, в которой подключается логирование в телеграмм.

# Logging bridge setuptg_logger.setup(logger, token=token, users=users)

В функцию setup() нужно просто передать тот logger, к которому вы хотите подключить мост. Если заглянуть в документацию, то можно посмотреть на другие параметры функции setup(). С помощью них можно, в частности, настроить формат, в котором логи будут отправлены.

Outro

Подробнее..
Категории: Python , Python3 , Logging , Telegram , Library , Logger , Handler

Делаем телеграм бота за 5 минут быстрый старт с продвинутым шаблоном

27.03.2021 00:13:02 | Автор: admin

В последнее время я сделал насколько много ботов для телеграмма, что крайне преисполнился в том, как их писать, как хостить, да и в принципе выработал красивый шаблон для быстрого их создания.

Сразу могу предложить посмотреть на то, что получиться в конце этого туториала. Для этого я запустил бота с идентичном шаблону кодом.

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

А еще сразу скажу, что далее будет все на питоне... Вот... Сказал. Не буду больше ходить вокруг да около, у нас всего 5 минут (помните, да?). Приступим!

Пошаговая инструкция

1) Создаем репозиторий на гитхабе из моего шаблона

2) Регистрируемся на Heroku

3) Создаем новое приложение

4) Привязываем наш репозиторий к проекту на Heroku

5) Настраиваем автоматический deployment

6) Смотрим на адрес, где будет висеть наш бот

7) Настраиваем переменные среды

KEY

VALUE

BOT_TOKEN

Токен для бота

WEBHOOK_TOKEN

Рандомная строка из букв для безопастности

ADMIN_PASSWORD

Еще одна рандомная строка из букв для безопастности

HOST

Адрес полученный в пункте 6 (например fancy-panda.herokuapp.com). Обратите внимание на формат!

IS_PRODUCTION

True

LOG_BOT_TOKEN

Токен для бота, куда будут отправляться логи

ADMIN_ID

user_id, куда будут отправляться логи (получить в боте @userinfobot)

8) Собираем наше приложение и ждем пока оно запустится

9) Заходим по адресу из пункта 6 и добавляем к ссылке пароль. Получиться что-то такое: fancy-panda.herokuapp.com/?password=<ADMIN_PASSWORD>

10) Устанавливаем webhook, переходя по ссылке на подобие fancy-panda.herokuapp.com/set_webhook?password=<ADMIN_PASSWORD>

Тестируем

Теперь, когда мы закончили все настраивать, пора посмотреть, что же мы "натворили".

Посмотреть в живую можно тут.

Пример работы из коробкиПример работы из коробкиПример работы логированияПример работы логирования

Добавляем функционал

Теперь, когда у вас есть рабочий бот, который сам разворачивается и запускается в облаке, пришло время добавить свои функции. Для примера такую:

@bot.message_handler(commands=["id"])def get_id(message):    logger.info(f'</code>@{message.from_user.username}<code> used /id')    bot.send_message(message.chat.id, f"user_id = {message.chat.id}")

Думаю, дальше ограничивает вас только воображение... (ну почти)

Применение в проектах

Все любят, когда есть примеры работы. На основе этого шаблона я сделал бота wifi_qr_bot, который генерирует QR-коды для подключения к WiFi. Это упрощает жизнь, ведь пароль у вас длинный (безопасность, все дела), а вводить его на каждом новом устройстве вам лень.

Выводы

Вот мы и сделали нашего бота, который хоститься в облаке. Он уже многое умеет в плане логирования. Для логирования я написал отдельную библиотеку, tg-logger. Если интересно, как она работает, то потыкайте в демо бота. Если все еще интересно, прочитайте мою статью. Такие пироги с котятками...

Ссылки

Подробнее..

Телеграмм-бот на Python

12.04.2021 20:16:10 | Автор: admin

Недавно я попал на стажировку в новую для себя IT-компанию и наш (моей команды) проект был - бот для телеграмма, который автоматизирует часть работы hr-менеджеров. Первую неделю нам дали на самостоятельное изучение всего, что мы посчитаем нужным (а я убежден, что лучший способ что-то изучить - это практика), так что я начал действовать. Язык программирования был выбран python (наверное понятно из обложки почему), так что в этой статьи я разберу пример именно с ним.

BotFather

Чтобы создать телеграмм-бота, достаточно написать пользователю @BotFather команду /newbot. Он запросит название и @username для будущего бота. Тут ничего сложного - он все подсказывает (главное, чтобы @username был не занят и заканчивался на "bot"). BotFather пришлет HTTP API токен, который мы и будем использовать для работы с ботом.

Создание ботаСоздание бота

Telebot и сила python

Мне всегда казалось, что создавать бота - это не так просто. Честно говоря, давно хотел попробовать, но то ли не хватало времени (думал, что это займет не один вечер), то ли не мог выбрать технологию (как-то смотрел туториал для c#), ну а скорее всего было просто лень. Но тут мне понадобилось это для работы, так что я больше не смел откладывать.

Сила python заключается в его популярности. А, как следствие, в появлении огромного количества сторонних библиотек практически под все нужды. Именно это сделало возможным написание примитивного бота (который просто отвечает однотипно на сообщения) в 6 (ШЕСТЬ!) строчек кода. А именно:

import telebotbot = telebot.TeleBot('1111105161:AAHIjyAKY4fj62whM5vEAfotuixC5syA-j8')@bot.message_handler(commands=['start'])def start_command(message):    bot.send_message(message.chat.id, "Hello!")bot.polling()
Первое сообщениеПервое сообщение

На самом деле бот будет отвечать только на команду /start, но для начала неплохо. Здесь все довольно просто: в первой строчке импортируется библиотека telebot (для ее работы необходимо установить пакет pyTelegramBotAPI командой pip install pyTelegramBotAPI (НЕ pip install telebot!), далее создаем объекта бот, используя токен, который нам прислал BotFather. Третья строчка проверяет, что присылают пользователи (в данном случае это только команда /start), и, если проверка пройдена, то бот отправляет ответ с текстом Hello!. Последняя строчка, наверное, самая сложная для понимания, и в следующих разделах я ее подробно разберу. Сейчас же я только скажу о ее предназначении - она заставляет бота работать, то есть "реагировать" на полученные сообщения.

Flask & Requests

Telebot, конечно, круто, но есть одно важное НО. По предположению нашего проекта, у hr-ов должен быть сервис (сайт), где они будут работать и через него отправлять/получать информацию пользователям/от них. Соответственно, нам нужно самим контролировать сервер и обрабатывать запросы. На мой взгляд самый простой способ создания сервера на python - фреймворк flask. Так выглядит простейший сервер, запускаемый локально на 5000-ом порту (http://localhost:5000/):

from flask import Flask app = Flask(__name__)@app.route("/", methods=["GET"])def index():    return "Hello, World!"  if __name__ == "__main__":    app.run()

Для работы бота нужно немного больше, а именно нужно добавить функцию отправки сообщений. Я не хочу полностью переписывать статью (habr), а воспользуюсь результатом и пойду с конца. Так выглядит программа, которая заставляет бота посылать Hello! на любое входящее сообщение:

from flask import Flask, requestimport requestsapp = Flask(__name__)def send_message(chat_id, text):    method = "sendMessage"    token = "1111105161:AAHIjyAKY4fj62whM5vEAfotuixC5syA-j8"    url = f"https://api.telegram.org/bot{token}/{method}"    data = {"chat_id": chat_id, "text": text}    requests.post(url, data=data)@app.route("/", methods=["POST"])def receive_update():    chat_id = request.json["message"]["chat"]["id"]    send_message(chat_id, "Hello!")    return "ok"if __name__ == "__main__":    app.run()

К сожалению, в таком варианте программа работать не будет. Точнее будет, но не сразу. Проблема заключается в том, что телеграмм пока что не знает, куда посылать информацию о полученных сообщениях. Для ее решения у telegram API есть метод setWebhook. Суть метода заключается в том, что мы просто отправляем телеграмму url, по которому мы хотим получать информацию о новых обращениях к боту (в нашем случае это http://localhost:5000/). Однако, мы не можем просто сказать телеграмму: "Посылай запросы на localhost", ведь для каждого сервера localhost будет разным. Еще одна проблема заключается в том, что метод setWebhook поддерживает только https url-ы. Для решения этих проблем можно воспользоваться программой ngrok, которая строит туннель до локального хоста. Скачать ее можно по ссылке ngrok, а для запуска туннеля достаточно ввести команду ngrok http 5000. Должно получиться так:

ngrokngrok

Теперь можно задействовать метод setWebhook, например, через postman. Нужно отправить post запрос на https://api.telegram.org/bot<ТОКЕН>/setWebhook с указанием в теле нужного url. Должно получиться аналогично:

setWebhooksetWebhook

Соединение

Чем больше я работал с библиотекой telebot, тем больше она мне нравилась. Хотелось бы, используя приложение на flaske, не терять эту возможность. Но как это сделать? Во-первых, мы можем вместо нашей функции send_message использовать готовую из библиотеки. Это будет выглядеть так:

from flask import Flask, requestimport telebotapp = Flask(__name__) bot = telebot.TeleBot('1111105161:AAHIjyAKY4fj62whM5vEAfotuixC5syA-j8')@app.route("/", methods=["POST"])def receive_update():    chat_id = request.json["message"]["chat"]["id"]    bot.send_message(chat_id, "Hello!")    return "ok"if __name__ == "__main__":    app.run()

Но, если присмотреться, можно заметить, что мы потеряли часть функционала, а именно @bot.message_handler - декораторы, которые отслеживают тип введенного боту сообщения (картинка, документ, текст, команда и т. д.). Получается, что если мы используем в качестве сервера наше flask приложение, то мы теряем некоторый функционал библиотеки telebot. Если же мы используем bot.polling(), то мы не можем обращаться к серверу со стороны. Конечно, хотелось бы как-то все соединить без потерь. Для этого я нашел немного костыльный способ, однако рабочий:

from flask import Flask, requestimport telebotbot = telebot.TeleBot('1111105161:AAHIjyAKY4fj62whM5vEAfotuixC5syA-j8')bot.set_webhook(url="http://personeltest.ru/aways/8c6f687b75c9.ngrok.io")app = Flask(__name__)@app.route('/', methods=["POST"])def webhook():    bot.process_new_updates(        [telebot.types.Update.de_json(request.stream.read().decode("utf-8"))]    )    return "ok"@bot.message_handler(commands=['start'])def start_command(message):    bot.send_message(message.chat.id, 'Hello!')if __name__ == "__main__":    app.run()

Здесь мы пользуемся методом set_webhook, аналогично тому, как мы делали это ранее через postman, а на пустом роуте прописываем "немного магии", чтобы успешно получать обновления бота. Конечно, это не очень хороший способ, и в дальнейшем лучше самостоятельно прописывать функционал для обработки входящих сообщений. Но для начала, я считаю, это лучшее решение.

Заключение

Написать телеграмм-бота на python и правда не так уж сложно, однако есть и подводные камни, о которых я постарался рассказать в данной статье. Конечно, это только начало, но последний фрагмент кода вполне можно использовать, как шаблон для серверной части, которая будет работать с телеграмм-ботом. Дальше остается только наращивать функционал по Вашему усмотрению.

Подробнее..
Категории: Python , Bot , Telegram , Flask

Подключаем Sqlite3 к Telegram боту

16.04.2021 16:20:16 | Автор: admin

Вступление

Для многих новичков в разработке на Python возникает проблема как подключить базу данных? Я сам столкнулся с такой проблемой в начале разработки. Тема оказалось довольно простой, но в интернете есть множество гайдов, которые могут запутать. В этом туториале я расскажу о том, как просто интегрировать базу данных Sqlite3 на примере Telegram бота.

Начало работы

Для работы нам понадобятся базовые знания в Python, достаточные для написания простого бота. Данный гайд можно использовать не только для интеграции с ботом, но и для других проектов. Если вы не используете PyCharm, и у вас нет средства для работы с БД, то необходимо установить утилиту SQLiteStudio с официального сайта.

Теперь давайте перейдем к написанию кода. В терминале необходимо установить pyTelegramBotAPI (если по какой-то причине у вас его нет).

pip install pyTelegramBotAPI

Далее создаем новый файл с расширением .py. В нем прописываем следующее:

import sqlite3import telebotbot = telebot.TeleBot("token")

Устанавливать sqlite3 не нужно это стандартная библиотека. Вместо "token" необходимо указать токен бота, который выдал вам BotFather. Теперь проверим, работает ли бот.

@bot.message_handler(commands=['start'])def start_message(message):bot.send_message(message.chat.id, 'Добро пожаловать')

Запустим код. Если при запуске бота он пишет нам "Добро пожаловать", то все работает отлично.

Как мы видим, все работает.

Настройка базы данных

Открываем SQLiteStudio. Во вкладке Database выбираем пункт Add a database. Для удобства можно использовать сочетание Ctrl+O.

Далее нажимаем на зеленую кнопку Создать новый фал базы данных. Выбираем директорию вашего проекта. В ней можете создать отдельную папку db, где будет хранится файл с базой. Вводим название, например database. Расширение будет присвоено автоматически. Нажимаем Сохранить. Теперь слева в списке у нас появился наш файл. Кликаем по нему ПКМ и выбираем пункт Connect to the database. Соединение с базой установлено. Появилось два подпункта: Таблицы и Представления. В этом уроке мы будем затрагивать только пункт Таблицы. Нажимаем по нему ПКМ и выбираем Add a table.

В поле для ввода указываем имя для таблицы. Я назову ее test. Чуть выше есть активная кнопка Добавить столбец (Ins). В появившемся окне указываем название столбца и тип данных. Для начала вам могут понадобится такие условия, как Первичный ключ, Не NULLи Уникальность. Первый столбец я назову id, выберу тип данных INTEGER и установлю все три условия. У Первичный ключ выберу настройку Автоинкремент. Этот столбец будет автоматически создавать ID записи в таблице. Работать с ним в коде мы не будем.

Второй столбец будет хранить user_id. Он будет иметь тип данных INT, уникален и не равен нулю. Третий столбец я назову user_name, присвою тип данных STRING и выберу пункт Не NULL. Еще 2 столбца будут называться user_surname и username. После того, как вы создали столбцы, нажимаем зеленую кнопку с галочкой.

В общем все будет выглядеть вот так.

Работа с базой данных в коде

Теперь давайте вновь перейдем к коду. Создадим 2 переменные.

conn = sqlite3.connect('db/database.db', check_same_thread=False)cursor = conn.cursor()

В первой мы подключаем нашу базу данных, а во второй создаем курсор для работы с таблицами. Обратите внимание на то, что у меня в директории проекта создана папка db, а уже в ней находится файл БД. Если у вас по другому, укажите расположение в первой переменной.

Теперь создадим функцию, которая будет нужна непосредственно для работы с таблицей.

def db_table_val(user_id: int, user_name: str, user_surname: str, username: str):cursor.execute('INSERT INTO test (user_id, user_name, user_surname, username) VALUES (?, ?, ?, ?)', (user_id, user_name, user_surname, username))conn.commit()

Итак, сейчас объясню, что тут происходит. В аргументах функции мы указываем переменную user_id с типом данных inst. Далее добавляем запись в таблицу test в столбец user_id. С остальными значениями точно так же. В конце мы просто применяем изменения. Эта функция не будет выполнятся, пока мы ее не вызовем. Давайте исправим это. Создадим обработчик сообщений от пользователя и будем вносить в базу его данные.

@bot.message_handler(content_types=['text'])def get_text_messages(message):if message.text.lower() == 'привет':bot.send_message(message.from_user.id, 'Привет! Ваше имя добавленно в базу данных!')        us_id = message.from_user.idus_name = message.from_user.first_nameus_sname = message.from_user.last_nameusername = message.from_user.usernamedb_table_val(user_id=us_id, user_name=us_name, user_surname=us_sname, username=username)

В переменные мы вносим имя пользователя, id, имя и фамилию в Telegram, а потом сохраняем в БД. В конце кода можем сделать так, чтобы бот работал постоянно.

bot.polling(none_stop=True)

Пришло время проверить, как работает код. Запускаем бота и пишем ему "Привет".

Теперь можем зайти в SQLiteStudio, и выбрав вкладку Данные посмотреть что получилось:

Как мы видим, данные уже в базе. Если их по какой-то причине нет, то обновите базу, нажав на синюю кнопку Обновить

Вот весь код:

import sqlite3import telebotbot = telebot.TeleBot("token")conn = sqlite3.connect('db/database.db', check_same_thread=False)cursor = conn.cursor()def db_table_val(user_id: int, user_name: str, user_surname: str, username: str):cursor.execute('INSERT INTO test (user_id, user_name, user_surname, username) VALUES (?, ?, ?, ?)', (user_id, user_name, user_surname, username))conn.commit()@bot.message_handler(commands=['start'])def start_message(message):bot.send_message(message.chat.id, 'Добро пожаловать')@bot.message_handler(content_types=['text'])def get_text_messages(message):if message.text.lower() == 'привет':bot.send_message(message.chat.id, 'Привет! Ваше имя добавлено в базу данных!')us_id = message.from_user.idus_name = message.from_user.first_nameus_sname = message.from_user.last_nameusername = message.from_user.usernamedb_table_val(user_id=us_id, user_name=us_name, user_surname=us_sname, username=username)bot.polling(none_stop=True)

Заключение

В этой статье мы немного познакомились с sqlite3 и сделали простой скрипт добавления сведений о пользователе. Этого, конечно, не достаточно. В скором времени выпущу продолжение, в котором затрону тему удаления пользователей и редактирования полей.

Огромное спасибо за то, что прочитали. Надеюсь, кому-то помог. Всем удачи и поменьше багов в коде!

Подробнее..
Категории: Python , Api , Sqlite , Telegram

Аналог фейсбучной ленты для Телеграма. Тупенький ИИ OLEG

09.05.2021 14:14:20 | Автор: admin

Этот пост о том, как я решил сделать систему коллаборативной фильтрации постов из пабликов Телеграма на основе машинного обучения.


И сделал: OLEG AI


Идея


В мире наступает революция ИИ, и в какой то момент мне стало казаться, что без меня она наступить не сможет. Поэтому я нашел курс по программированию нейросетей на Питоне Fast.AI, и решил придумать себе небольшой проект, чтобы поучиться на практике.


Я люблю Телеграм. И люблю иногда потупить в какую-нибудь ленту "информационного корма". В разное время я любил поразлагаться на Лепре, Дёти, Пикабу, но в итоге всеми этими источниками сладкого яда я остался недоволен.


И тогда я подумал: в Телеграме ведь куча источников, но Телеграм их не агрегирует по типу Фейсбука. Телеграм не собирает с нас лайки. Да, лайки это чистое зло и гореть им в аду, но иногда так хочется лайкнуть жопу фотомодели, нет?


А рекомендательные сервисы это одно из направлений ML. А Телеграм открытая система. Должно быть не сложно, подумал я. Оказалось чуть сложнее чем я думал, но получилось.


Стоит заметить, что я не профессиональный программист, и опыта в программировании у меня не было примерно с 2004 года. Так что, помимо собственно нейросетей, мне пришлось еще и быстренько расчухать основы Питона, вспомнить SQL, погрузиться в Докер и практику CI/CD. Это было потрясающе.


Процесс


Начал я с того, что убедился, что задуманное мной в принципе возможно.
Мне нужно было слушать некий набор каналов (пабликов) Телеграма, и передавать посты подписчикам бота. Поизучал доки Telegram Bot API, понял, что при помощи одного только Telegram Bot API сделать это не получится. Бот не может подписываться на каналы по своему выбору.


Придется писать своего клиента для Telegram. К счастью, с нуля писать не пришлось: есть неплохая основа в виде либы python-telegram. Апишка там не самая проработанная, но самое тяжелое она делает за нас: процесс логина, предоставляет классы для создания запросов и получения асинхронных ответов от TDLib. TDLib это сишная либа-Телеграм-клиент. Так что я вооружился доками от TDLib, и принялся ковырять ее. Заодно разобрался как работает Телеграм, прикольно.


Я завел доску miro.com, чтобы накидывать туда идеи, рисовать схемы. Например, схему БД я нарисовал там. Оказалось очень удобно для маленького проекта всё в одном месте и в то же время не мешает.


Как я представлял себе то, что хочу сделать:


Довольно быстро я накидал приложение, схема которого в итоге оказалась примерно такой:


Блоки объекты.
Тут не все объекты, конечно, а только основные.
Admin это обычный аккаунт Телеги, залогиненный через TDLib и подписанный на интересующие нас каналы. Слушает апдейты каналов и записывает. Причем он не пишет контент, а только метаданные сообщения: tg_channel_id и tg_msg_id. По этим двум полям можно найти любое сообщение в Телеге (если оно было показано аккаунту).
Bot аккаунт бота, общение с которым тоже происходит через TDLib (до этого я даже не знал, что так можно, думал, что только через Bot API можно работать с ботом).
К ним подключены TDLibUtils всякие методы для работы с TDLib низкого уровня. Типа, найти юзера, найти сообщение, вытащить имя канала из инфы о канале и тп.
OlegDBAdapter методы для работы с базой (get_users, get_posts etc)
OlegNN то, ради чего всё затевалось алгоритм коллаборативной фильтрации. Правда, по итогу никакой нейросети там внутри не осталось, но об этом позже.
Joiner логика подписки на каналы. Нельзя так просто взять список каналов и подписаться на него: быстро срабатывает рейт лимитинг. На вычисление безопасной логики подписки, логирование, организацию базы ушло около недели.
APScheduler сторонняя либа-планировщик тасков. Использую для периодической рассылки сообщений подписоте.


Контент


Схемы работы с контентом могло быть две:


  • забирать контент каждого сообщения, хранить его, и собирать из него сообщение для подписчика по запросу. Плохо, тк придется качать и хранить кучу контента. Ладно бы текст, но там еще и медиа
  • не хранить контент, а забирать его из Телеграма по необходимости
    • в идеале не выкачивать медиа, а придумать, как его передавать юзеру прямо внутри Телеграма. Этот вариант и реализовал, правда, пришлось помаяться.

Чтобы не выкачивать медиа, в Телеграме у каждого ассета есть свой уникальный айди. Когда собираешь сообщение, можно вместо файла указать этот айди. Я думал, что этого достаточно, но посты не отправлялись. Оказалось, дело в том, что аккаунт отправляющий медиа с помощью айдишника, должен сначала этот айдишник встретить в Телеграме. Например, получить сообщение с этой картинкой. Проблема в том, что у меня за получение сообщений отвечает аккаунт Admin, а за отсылку Bot. Я долго думал, и в итоге придумал: а что, если каждое полученное сообщение Админ будет форвардить Боту, таким образом Бот "увидит" всё медиа. Это сработало. Я боялся, что за такое количество форвардов поймаю рейтлимит и огребу гемморой, обходя это дело, но в итоге обошлось.


Каналы


Не мудрствуя лукаво, я купил список топовых каналов по количеству подписчиков у TGStat.ru. 45 категорий по 100 каналов, вышло 4500 каналов. Пока этого хватает, возможно допишу еще паука, который сам лезет в каналы упомянутые в постах, и подписывается на них. Я сразу сделал логику Joiner'а так, чтобы можно было легко докинуть ему в пул свежих каналов, а он с ними сам разберется.


С каналами уперся в неожиданный лимит: один аккаунт Телеграма может быть подписан только на 500 каналов. Придется теперь превращать Admin'а в хаб, управляющий несколькими аккаунтами, и добавлять аккаунты, следить какой аккаунт подписан на какой канал, и всё в таком духе. Пока отложил это, решил, что для старта 500 каналов хватит.


Нейросеть, которой нет


Затевал я всё это ради практики программирования нейросетей, как вы помните.


Когда внедряешь машинное обучение, сталкиваешься с тем, что это всё-таки черный ящик, у которого наружу торчат некие гиперпараметры, а на выходе получается какой-то результат, причем, если при разработке ты правильно учел всякие там размерности тензоров и не наделал глупых ошибок, оно будет работать. Как-то будет. Будет ли результат, выдаваемый ящиком, иметь какой-то смысл это вопрос. Чтобы ответить на этот вопрос, приходится сидеть, расковыривать ее так и эдак, смотреть на результаты разных этапов вычисления, читать тематические статьи, узнавать практику, прикидывать baseline результат и сравнивать с тем, что получилось у тебя. Короче, это весело. На первых этапах машинное обучение создает гораздо больше проблем, чем решает. И заставить его реально решать какие то проблемы, создавая прибавленную стоимость для вашего проекта большая работа, не очень похожая на обычное программирование и дебаг.


Так что трижды подумайте, прежде чем бросаться решать проблемы этим методом. ML требует жирных проблем, которые точно не решаются классическими методами и сулят повышенный профит. ML ради ML истощает бюджеты и роняет мораль!


Прежде чем прикрутить ML к Олежке, я долго крутил системы коллаборативной фильтрации на тренировочном датасете MovieLens (ой, только не надо).
Я делал решение как для задачи регрессии (в конце один нейрон который угадывает рейтинг фильма по шкале 1..5), так и для задачи классификации (в конце 5 нейронов, каждый отвечает за свой рейтинг 1..5, и какой нейрон сильнее активируется, тот рейтинг мы и считаем за предсказание).
Эти изыскания заняли прилично времени, кажется 2-3 недели. По ходу дела я даже с нуля написал классификатор MNIST, благодаря чему сильно продвинулся в понимании работы нейронок. Кто еще не делал этого: очень рекомендую. Времени занимает от силы 2 дня, а пользу приносит годами.


В итоге стало ясно, что если задачу рассматривать как регрессию (а не классификацию), предсказательная сила модели будет намного лучше, так я и сделал.


В основе механизма у меня эмбеддинги. Кто не в курсе читаем дальше, кто знает может промотать следующий раздел.


Embeddings


Идея простая, но гениальная: каждой сущности (юзеру, посту) противопоставляется вектор параметров. Например, K=10 параметров. Они еще называются латентные факторы (latent factors).
Получается, что если у нас N юзеров, то мы можем расположить все вектора друг под другом, и получить тензор формы (N,K). Матрицу из N рядов и K колонок, если по-колхозному.
Для постов получится такой же тензор, только другой.
Эти тензоры называются эмбеддингами.
Cистема спрашивает у алгоритма фильтрации: вот есть юзер U, пост P, предскажи мне рейтинг, который юзер поставит посту.
В самом простом варианте (без нейронки) мы ищем в тензоре юзеров нужный ряд соответствующий юзеру, в тензоре постов вектор поста, и перемножаем эти два вектора (как в школе). На выходе получается скаляр (число) это и есть предсказанный рейтинг.
В варианте посложнее, эти два вектора подаются на вход нейросети, и дальше сигнал продвигается уже механизмом нейросети. На выходе один нейрон, величина активации которого скаляр и есть предсказанный рейтинг.


Почему эти тензоры назвали отдельным словом "эмбеддинг", что в них особенного? Дело в том, что эмбеддинг это первый шаг вычисления результата работы нейронки.
Когда мы ищем нужный ряд для юзера или поста в тензоре, мы могли бы просто взять индекс нужного ряда, и вытащить вектор соответствующий этому индексу. Но операция "взять ряд по индексу" не является алгебраической, это программатик-операция работы с памятью. Это означает, что данная операция разрывает граф вычислений градиента нейросети. Градиент можно вычислить только для алгебраических операций. То есть, во время обучения механизм back propagation не сможет дойти до самого конца непосредственно до эмбеддинга. Как же быть?
Вместо того, чтобы брать ряд тензора по индексу, мы можем умножить этот тензор на one-hot-encoded vector. Например, нам нужен третий по счету ряд тензора. Умножаем тензор на вектор [0 0 1 0 ...] На выходе получаем нужный нам ряд тензора. Это алгебраическая операция (умножение тензора на тензор), она не ломает граф вычислений! Но это компутационно дорогая операция. Каждый раз так умножать GPU замучается. Поэтому в PyTorch и других пакетах нейровычислений есть специальный компутационный шорткат для эмбеддингов, который с одной стороны и граф вычислений не ломает, и компутационно дешев.


Где же взять эмбеддинги?
Допустим, у нас есть обучающий датасет: энное количество оценок, которые юзеры поставили постам.
Давайте проинициализируем эмбеддинги случайным образом, и для каждой оценки из датасета будем вычислять предсказание и сравнивать с оценкой. У нас получатся некие дельты, на этих дельтах мы и будем обучать нейросеть и эмбеддинги с помощью стохастического градиентного спуска (SGD).


В итоге через несколько эпох обучения (эпоха проход всего датасета) наши эмбеддинги из случайных превратятся в обученные, и будут иметь некий смысл.


Каждый из параметров эмбеддинга действительно приобретает некий смысл. Какой не совсем понятно, да и не нужно понимать. Будем считать, что этот смысл ведом только самой системе рекомендаций. Для нас главное, что в итоге система работает: рекомендует юзерам более релевантные посты. А какой "смысл" она видит в этих постах какая разница?


Длина вектора латентных параметров


Число параметров K какое оно должно быть? Лучший ответ, что мне удалось найти, был в этой статье: A social recommender system using item asymmetric correlation
Если коротко, единого ответа нет, всё зависит от глубины сложности ваших item'ов, постановки задачи, функции потерь, короче, от всего. Rule of thumb: 5 маловато, 50 многовато, где-то посередине в самый раз. Надо пробовать: смотреть, насколько гладко обучается модель, не провоцирует ли выбранное количество параметров переобучение, обучается ли модель вообще.


Я выбрал K=13


Где нейросеть?


Поиграв некоторое время с разными конфигурациями, я понял что для моей задачи регрессии оценки в диапазоне 0..1 лучше всего подходит конфигурация без нейросети. У меня просто перемножаются эмбеддинги. В таком варианте, без глубинного обучения, обучение происходит гораздо быстрее и плавнее. В данном случае проще оказалось лучше.


Обучение


Самый большой мой просчёт в архитектуре был связан с тем, что я думал, будто результаты обучения очень ценная инфа, и её надо хранить персистентно, на диске в виде бинарника или в базе. Я написал код, который сохраняет вектора для каждого поста и юзера в базу в виде BLOB'а. Написал, потестил время выполнения, оказалось, что процесс обучения занимает 1-2 секунды, а процесс записи результатов около минуты. Сама модель занимает в памяти 52 мегабайта для 1 млн постов. Так и зачем вообще сохранять ее в памяти? В любой момент можно обучить ее с нуля за пару секунд. Пришлось переписать.


Вот так выглядит процесс обучения. По вертикали ошибка, по горизонтали номер мини-батча:



Мини-батч это некоторое число оценок, которые одновременно подаются на вход модели для обучения. В моем случае batch_size = 512.
Каждый пик это старт обучения с нуля. Видно, как по мере обучения падает ошибка.


Вот так выглядит инференс (процесс предсказания) модели:



Каждая точка это пост из базы. По вертикали предсказанная оценка. Из 11 115 постов всего 338 имеют предсказанную оценку выше 1, из них в итоге модель и выберет тот пост, который попадет юзеру в ленту.


Обучение с нуля и инкрементное обучение


Когда переходишь от игрушечных моделей для учебы к реальной модели для проекта, возникают вопросы:


  • Как быть, если приходит новая оценка от юзера? Стартовать обучение сразу, или ждать N новых оценок?
  • При получении новой оценки, обучать модель "на старые дрожжи" (инкрементно), то есть взять те веса и эмбеддинги, которые есть, и на них натравить датасет из новых оценок? Или просто переобучить всё с нуля?

Когда передо мной встали эти вопросы, беглый поиск ответов мне ничего не принес, поэтому я вооружился здравым смыслом и практикой. Соображения у меня были такие:


  • Инкрементное обучение плохо тем, что если запускать только его, и никогда не обучать с нуля, параметры застревают в некой области значений. Кривая обучения становится очень резкой. На практике это означает, что при поступлении новых данных и запуске инкрементного обучения, несколько эпох ошибка почти не меняется, потом делает резкий скачок вниз или вверх, и потом опять стоит как вкопанная. Это очень нездровая ситуация, если вы столкнулись с таким, ищите как сделать обучение гладким, вплоть до переформулирования задачи как таковой.
  • Обучение "с нуля" почти ничего нам не стоит, поэтому не надо этого стесняться.
  • Глядя в будущее, можно предположить, что когда-нибудь у Олежки скопится датасет из 1 млн оценок, который будет занимать заметное время на обучение (десятки секунд). Юзеров будет достаточно много, и при получении каждой новой оценки запускать обучение с нуля мы не сможем.

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


Холодный старт и взросление сервиса


Если вам доводилось читать о рекомендательных системах, вам должно быть известно, что одной из самых больших проблем в них является "холодный старт" и бутсртап свежего юзера. Холодный старт это когда в системе в принципе мало оценок, а свежий юзер это юзер, о вкусах которого мы ничего пока не знаем.
Действительно, если в системе мало оценок (и много постов), как ее ни обучай, данных будет недостаточно, чтобы выученные эмбеддинги имели какой-то смысл. Рекомендации продуцируемые этой системой будут малорелевантными.
Со свежим юзером похожая проблема.
Как решить эти вопросы? Единого решения не существует. Все пользуются здравым смыслом и той информацией, которая доступна.
Например, для свежего юзера мы можем сделать некий опросник (так сделано в Netflix), который сможет быстро сообщить нам хоть что-то о юзере, чтобы сделать первый опыт пользования системой не ужасным.
Я решил, что опросник для Олежки будет слишком тяжеловесным решением, юзеры хотят просто тыкать лайки, а не отвечать на вопросы типа "ваш любимый цвет". Поэтому я решил так: первые 30 постов, которые Олежка присылает юзеру, я выбираю из числа тех, которые максимально нравятся всем. Говоря строго, они имеют максимальный bias.


Железо


Сейчас Олежка работает на самом дешевом инстансе Digital Ocean ($5/мес), без GPU. База расположена на этом же инстансе, в другом докер-контейнере. Думать о скейлинге пока рановато.


Итог


Олежка стабильно работает, перестал жрать память и чувствует себя хорошо.
Юзеров пока маловато, так что, пожалуйста, лайк-шер. Можно просто шерить посты из ленты друзьям в Телеграме.
Больше юзеров релевантнее рекомендации!

Подробнее..

Как мы запустили документооборот в Telegram и что из этого вышло? Да, это не сон

24.05.2021 12:21:25 | Автор: admin

Разбираем аргументы за и против. В конце также можно ознакомиться с моим мнением на этот счет.

С чего все начиналось?

Решение сложной задачи часто оказывается простым и гениальным. Так и вышло, когда ко мне обратилась крупная компания с проблемой потери прибыли. И дело было не в утечке или неграмотном ведении бизнес-процессов, а элементарно в долгих паузах в документообороте.

Немного обо мне: я Python разработчик, архитектор, тимлид. В программировании с 2009 года. Ранее опубликовал эту статью на vc.ru.

В реализации проекта мне помогал аналитик от заказчика, и в общем-то всё.

Итак, к кейсу

В коллектив организации входит большое количество выездных сотрудников. Часто возникают ситуации, когда у работника нет возможности CRM-системой на компьютере (в нашем случае ноутбуке) для выполнения рабочих задач.

Если коротко описать задачу: человек в полевых условиях должен иметь возможность войти в систему и отправить необходимые документы. Иначе из-за временных задержек компания теряет приличные суммы денег.

Более подробно описать ситуации я, к сожалению, не могу, т.к. есть договоренность о неразглашении подробностей этого кейса.

Как решить проблему потери времени? У сотрудника должна быть возможность коннектиться с CRM-системой с планшета или телефона.

Как осуществить задуманное?

Выход нашёлся быстро: создать чат-бот в Telegram.

И на это решение можно посмотреть с двух сторон: с позиции управленцев и со стороны айтишников.

Не буду кривить душой, мне ближе позиция программистов с небольшими оговорками. Моя идея хороша, как ни крути. Но давайте сначала рассмотрим позиции обеих сторон.

Если рассуждать со стороны управленцев, соединение CRM-системы с чат-ботом Telegram значительно снижает энергозатраты и финансовые расходы компании. И вот, почему:

  • Не нужно обучать большой штат новым программам-интеграторам CRM с телефоном.

  • Тем более, стоимость таких программ значительно выше, чем стоимость написания и поддержания работоспособности чат-бота для Telegram.

  • Это удобно. Сейчас у каждого есть возможность скачать Telegram, который не занимает много места в памяти телефона.

  • Работает Telegram-бот действительно быстрее, чем сложная программа. Кроме того, чат-бот помогает сотруднику сориентироваться во внутреннем документообороте фирмы.


Но со стороны безопасности и сохранности данных такое внедрение в электронный документооборот крупной компании нужно считать неприемлемым. Здесь на арену выходят возможные доводы IT-отдела.

  • Интеграция мессенджера в CRM-систему может привести к утечке информации. Сам по себе документооборот необходимо строить на основе внутренних ресурсов, также необходимо предусмотреть авторизацию пользователей. Если не учесть эти моменты, то данные могут уйти не в те руки.

  • Если изменить процесс документооборота, например, ввести отправку редактированных вариантов, то решение рассыпается. В таком случае сотруднику необходимо будет сначала отредактировать документ, а потом отправить его в чат с ботом.

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

  • Ещё один весомый аргумент: данные будут храниться в разных системах. Telegram-бот может быть напрямую привязан к CRM или ERP-системе, но в большинстве случаев он имеет свое хранилище, в котором агрегирует данные и обрабатывает их.

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

А что я думаю по этому поводу?

Более логичное решение, как программист, я вижу таким: выездным сотрудникам всё-таки работать с мобильной версией CRM-системы компании. Но напомню, это технически сложно для большой организации, и значительно бьёт по карману управленцев.

Тем более, если говорить об удобстве главных героев этой эпопеи - полевых работниках, то загрузить документ и отправить его на дальнейшее согласование, получить нужное уведомление гораздо проще через бот в Telegram, чем через специализированную программу, типа 1C, Диадок и т.д.

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

Даже удивительно, почему другие компании не используют подобные методы. А может и использует, кто их знает?

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

О технической стороне вопроса

Идея была реализована на основе Telegram API на вебхуках. Для разработки был использован любимый python, данные хранятся на базе postgresql. Для ускорения работы и асинхронности задач применили связку redis + celery, в качестве серверной операционной системы использована Ubuntu 18 Server.

К слову сказать, мой клиент остался доволен. Нововведение принесло компании прибыль, которая терялась на простоях из-за пауз в цепочках бизнес-процессов.

А вы на стороне программистов или управленцев? Делитесь своим мнением, задавайте вопросы!

Подробнее..

No-code в действии мастерим временный email-адрес

23.03.2021 14:22:27 | Автор: admin

No-code сейчас в тренде. Статей на эту тему пока не много, хотя они появляются достаточно регулярно. На Хабре по тегу no-code и его вариантам я нашел всего около 15 статей и первая из них появилась только в июне 2020 меньше года назад! Во время чтения одной из статей у меня возникла идея собрать разные варианты no-code сценариев и снабдить некоторых из них, наиболее востребованных, инструкциями по реализации. Мне кажется, это будет интересно многим. Внизу после туториала, вы найдете пока небольшой, но пополняемый список сценариев и опрос, а пока давайте посмотрим как реализовать один простой сценарий.

Он относительно многоцелевой и с его помощью можно сделать различные интеграции для электронной почты, в том числе временный адрес почты для регистрации на разных сайтах. Если вы считаете, что можно просто зарегистрировать очередной ящик на gmail, или если вы знаете реализации такого сервиса, можете написать об этом в комментарии и дальше не читать. Наверняка, можно сделать это проще, нужно меньше 10 строчек кода. Хорошо, если хотите, напишите и об этом. Ну а для остальных, кому интересны технологии no-code, но пока не доходили руки разобраться и что-то сконструировать самому, предлагаю подробное описание сценария и пошаговую инструкцию.

Описание задачи

Предположим, вам нужен временный адрес, который не жалко засветить при регистрации на малоизвестном сайте или сайте с репутацией, вызывающей вопросы. После регистрации или когда надобность в адресе отпадет, можем удалить или оставить, но временно заблокировать его (см. об этом шаг 10c ниже) вдруг нужно будет позже восстановить пароль. Идея простая и очевидная и такие сервисы наверняка есть, хотя я сам ими не пользовался. Говорят, что существует такой сервис у Apple, когда при регистрации с помощью Apple Id, он предлагает подменить основной почтовый адрес временным. Хорошая идея, но в данном случае она доступна только владельцам яблочных гаджетов, более того, сайт на котором нужна регистрация, должен принимать Apple Id. Также я сам видел бота, который предлагал временный адрес почты. Это был простейший бот, но он почему-то не работал.

Получаются два стартовых условия: 1) делаем свой, кастомный и настраиваемый сценарий; подробнее об этом см. варианты развития сценария шаг 11 почти в самом конце; 2) обходимся без единой строчки кода.

Конечно, сценарий будет зависеть от сторонних сервисов и их поставщиков, а также будет, скорее всего, платным. Но есть и хорошие новости, он может быть создан на коленке за считанные минуты. В самом худшем случае, если вы делаете это первый раз или если вдруг что-то пойдет не так, за 1-2 часа максимум. В последние несколько лет количество новых no-code сервисов растет как на дрожжах, так что сценарий может быть реализован разными способами и мы можем выбирать наиболее удобный вариант и таким образом снизить зависимость от провайдеров no-code. Поэтому добавляем еще условие: 3) задействованные сервисы должны быть легко заменяемыми и настраиваемыми. В одной статье не получится полностью описать, как реализовать все 3 условия, но будем считать это заделом на будущее развитие сценария (шаг 11). Кроме того, сейчас не будем подробно сравнивать разные альтернативы и объяснять, почему именно эти варианты выбраны. Об этом есть множество других публикаций (примеры есть по ссылкам в следующем абзаце) и, конечно же, можете написать обо всех альтернативах в комментариях.

Альтернативы no-code

Если вы в первый раз слышите о no-code, возможно вам будет интересно почитать вводные обзоры и статьи для знакомства с отдельными сервисами. Для старта подойдет небольшой обзор No-code как отличная альтернатива для быстрого решения бизнес-задач. Взвешиваем pro et contra Движение No-code конец программистов? Разбираем плюсы и минусы. Введение в один из инструментов на Хабре n8n. Автоматизация ИБ со вкусом смузи.

Мы подходим к задаче серьезно, поэтому изучив и выбрав лучшие (на сегодняшний день) из доступных альтернатив, уточним ТЗ.

Техническое задание

Нужно получить временный адрес и указать его при регистрации на каком-то левом сайте/сервисе сомнительного качества или с репутацией, вызывающей вопросы. И далее мы должны будем получить письмо или как-то прочитать его. Нас интересует только ссылка или код регистрации в теле письма, поэтому достаточно его извлечь и переслать дальше. Вот только куда? На основной адрес? Но зачем нам это письмо на почте, может лучше в виде короткого сообщения в чате или даже СМС-ки. Можно подключить WhatsApp, Slack или другой мессенджер. Но удобнее всего, конечно, Телеграм, для него и сделаем сценарий.

Проблемы, которые должен решать сценарий: 1) в общем случае текст письма может быть длинным, в то время как текст сообщения ТМ ограничен до 4096 символов, нужно обрезать длинные письма или разбивать их на части, 2) нам нужно также извлечь из письма ссылку или код для регистрации, т.е. нужно уметь обработать не только plain-text, но и HTML.

Кажется, что все совсем просто приступим. Все, что мы будем использовать это сервис Zapier и мессенджер Телеграм. Если у вас пока нет Телеграма, хороший повод его установить.

Шаг 1. Регистрируемся в Zapier

Если у вас есть аккаунт, этот шаг пропускаем. Если нет, нужно будет пройти стандартную процедуру регистрации на сайте Zapier и выбрать тарифный план или тестовый период. К сожалению, я регистрировался давно и точных условий сейчас не знаю, кажется, бесплатный тариф позволяет выполнить до 100 операций в месяц. Это совсем мало, но для тестирования сценария хватит. К тому же, посчитайте, как часто вы регистрируетесь на разных сайтах? И если этот сценарий придется вам по вкусу и вы захотите его и адрес почты использовать на всю катушку, можно будет попробовать заменить Zapier на другой сервис (например, бесплатный n8n) или заплатить за тариф, который вас устроит.

Шаг 2. Создайте новый Zap

Нажимаем [MAKE A ZAP] см. скриншот

Шаг 3: Укажите название запа и выберите триггер

Нужно как-то назвать Зап/сценарий и настроить триггер, который его запускает.

a) Жмем на Name your zap и вводим название запа. Вы можете выбрать любое. Я назвал его TMP Email Zap.
b) Далее в строке поиска вводим: email, Zapier покажет доступные почтовые сервисы.
c) В качестве триггера доступны различные приложения, но они потребуют дополнительных действий и регистрации новых сервисов, скорее всего. Нам не нужны такие трудности, выбираем простейший и первый в списке вариант Email by Zapier. См. скриншот выше.

Шаг 4: Выберите событие триггера

a) В разделе Trigger event нажмите на Choose an event
b) Тут вариантов не много: выбираем New inbound Email. См. скриншот выше.
c) Нажмите дальше [Continue]

Шаг 5: Выберите адрес email

Укажите адрес почты:

a) Появится поле для ввода email-адреса. Можете добавить любое слово. Но важно использовать ТОЛЬКО буквы в нижнем регистре или цифры, иначе вы не сможете пройти дальше.
b) Сохраните полученный адрес (кнопка [Copy]), вы будете использовать его для регистрации на левом сайте.
c) Нажмите дальше [Continue]. См. скриншот выше.

ВНИМАНИЕ!!!

Не показывайте никому этот адрес. Иначе вы рискуете попасть на спам. После чего, в лучшем случае, вы превысите бесплатные лимиты и сценарий перестанет работать, а в худшем случае придётся заплатить рублем, причём не деревянным, а зелёным по текущему курсу ЦБ. Хотя Zapier не очень дорогой, но платить только за спам совсем не хочется.

Шаг 6: Протестируйте email адрес

После того, как вы получили адрес почты, можете его протестировать.

a) Попробуйте отправить письмо на адрес, который вы получили на шаге 5b.
b) После отправки письма нажмите кнопку [Test Trigger]
c) Если ничего не происходит или Zapier пишет что-то вроде Request no found, подождите несколько секунд и еще раз нажмите кнопку письму нужно время, чтобы дойти до сервера Zapierа
d) Если письмо все еще не пришло, проверьте, правильно ли вы скопировали адрес
e) После того как Zapier получит тестовое письмо, он покажет содержание письмо и все доступные поля (sender, subject и пр. их довольно много).
f) После тестирования, нажмите кнопку [Continue]

Шаг 7: Настройте бота, получателя сообщения

Можно самостоятельно зарегистрировать бота есть множество инструкций, как это сделать. Но если оставаться строго в парадигме no-code, можно воспользоваться уже готовым решением телеграм-ботом.

a) Откройте Telegram и бота по этой ссылке @co_notbot. Если у вас еще нет Телеграма, его нужно установить.
b) При входе нажмите кнопку [Start] или введите команду /start. Ждите некоторое время пока бот отработает команду. Появится сообщение с Главным меню бота и две кнопки внизу.
c) Нажмите на кнопку [Подключить]. См. скриншот выше.
d) Откроется следующее окно, в котором появится больше вариантов и кнопок. Нас интересует кнопка [Webhook]. Нажмите на нее и подождите до 1-3 секунд. См. скриншот ниже:

e) В следующем сообщении от бота вы получите вебхук, который нужно будет скопировать и затем добавить в наш Zap на шаге 9a.

ВНИМАНИЕ!!!

Не показывайте никому этот вебхук/токен и храните его в достаточно надежном месте. Иначе можете легко получить неприятный поток спама в свой до сих пор уютный чатик.

Шаг 8: Выбираем Action

a) Вернитесь в Zapier и нажмите кнопку [Action].
b) В строке поиска наберите web
c) Из списка выберите Webhook by Zapier. См. скриншот выше

a) далее выберите Action event, нажмите на [Choose an Event]
b) из списка выберите вариант [POST]. См. на скриншоте выше.
c) Нажмите дальше [Continue]

Шаг 9: Добавьте вебхук и параметры

На этом шаге нужно будет правильно задать несколько параметров Вебхука. Будьте внимательны, заполните все необходимые поля, смотрите внимательно скриншот, размещенный ниже.

a) в поле [URL] введите адрес вебхука, который вы получили на шаге 7e. На скриншоте приведен пример. У вас должна быть точная копия с токеном и адресом.
b) в поле [Payload Type] оставьте вариант [Form]
c) в следующем разделе [Data] нужно будет добавить/задать передаваемые параметры вебхука. Нам нужно будет задать одно поле text и его значение, в котором будет передаваться сообщение.
d) в поле text можно сначала добавить значение [Subject], [Sender], [Body Plain] или [Stripped Text] из письма
e) если тестирование (шаг 10) пройдет успешно, можно попробовать обрабатывать и передавать значения из html (об этом см. шаг 11c). Можно пробовать разные варианты и смотреть, что получится в результате. Если после выполнения Zapier будет выдавать сообщения об ошибках, попробуйте задать статическую строку, например, Hello world! и посмотрите, что получится.
f) остальные поля, ниже раздела [Data], заполнять и изменять не нужно

Шаг 10: Тестирование отправки письма и всего сценария

a) после того как все поля будут заполнены вы можете снова протестировать отправку письма и весь сценарий. Отправьте новое тестовое письмо и нажмите кнопку [Test & Review]
b) если тест пройдет успешно, то вы получите ответ в зеленой зоне и сообщение вроде Test was successful включите Zap/сценарий, нажмите на переключатель [off] [on];
c) обратным действием можно выключить (или на время заблокировать) этот сценарий позже

Шаг 11: Развитие сценария: извлекаем ссылки, добавляем фильтр, укорачиваем текст

Можно продумать и сделать дальнейшие улучшения, которые я только кратко перечислю. Но если будет интерес, кто захочет сможет отдельно написать продолжение о том, как еще лучше реализовать этот и другие сценарии в парадигме no-code и не только.

a) проверка длины текста и самостоятельно решаем обрезать текст или делить его на куски < 4096 символов, чтобы не превысить лимиты Телеграма; можно реализовать по-разному, модулем Formatter by Zapier, например;
b) можно пересылать не каждое сообщение, а пропускать все сообщения через фильтр, который оставит только нужное и уберет спам, например. См. Filter by Zapier;
c) можно сделать более сложную обработку входящих писем и извлекать ссылки и/или картинки из HTML кода письма (Formatter by Zapier). Как вариант, после этого картинки можно пропустить через один из сервисов распознавания изображений для извлечения чисел/текста/номеров/лиц и пр.
d) можно самостоятельно зарегистрировать бота Телеграм и подключить один из бот-конструкторов; и тогда сможем реализовать бота по-своему и не будем зависеть от работоспособности стороннего бота. Правда попадем в новую зависимость от сервиса-конструктора;
e) можно сделать новый чат, куда с помощью аналогичного вебхука вместо письма настроить получение RSS, уведомлений или любого другого потока сообщений;
f) и наконец, можно сделать отдельные шаги взаимозаменяемыми, чтобы не зависеть от отдельного провайдера сервиса no-code. Например, вместо Zapierа можно использовать n8n или Integromat.

Как я обещал, кратко перечислю более-менее простые сценарии no-code. Выберите наиболее интересные на ваш взгляд.

  • Кастомный фильтр спама на базе AI/ML

  • Временная почта для регистраций (см. пример этого выше)

  • Агрегатор и фильтр вакансий/новостей/объявлений/rss

  • Сканирование и учет чеков и финансовых операций

  • Кастомный uptime-мониторинг для сайтов, серверов

  • Уведомления и команды Умного дома

  • No-code решения для скилов Алексы или навыков Алисы

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

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru