СЛЕГ! <Z> ️
522 subscribers
678 photos
20 videos
12 files
307 links
Здесь создают авторских телеграм-ботов. Когда не справляются конструкторы и веб-студии - есть СЛЕГ.

Статистика ботов:
https://ssleg.tech/bots_view.html

Написать автору: @yesitsnew

TW: ещё тут политота, утечки баз и игры в товарища майора на минималках
加入频道
Когда написал реально большого бота. Это промежуточный итог, в релиз вышло 1636 строк кода и ещё 400+ в текстовых блоках.

Один четыре восемь восемь, кодить мы питон не бросим! 😁
И тут со дна постучали в зелёный люк. 😂
Говорят, что на линкус сложно играть. Мне тут захотелось в танчики какие-нибудь погонять - без проблем и даже бесплатно.

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

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

В телеграм для этого используются два разных хандлера.
Один - events.ChatAction(), для событий входа в чат и/или добавления юзера.
Второй - events.NewMessage(), срабатывает на сообщения в чате.

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

А теперь реальность. В чат входит бот и сразу что-то постит. Лог с таймингами:

Хандлер ChatAction() получил информацию и поставил ее в общую очередь команд админки.
INFO module_one [2020-09-25 06:26:23,321]
вход в <...> #729730 1386306872
INFO module_one [2020-09-25 06:26:23,321]
команда: (6, 0, 1xxxxxxxxx, 0, 0, 1386306872)


Но поскольку мой сервер загружен, ботов там уже трое, а процессор один, поток asyncio сжался по времени и всего через 11 миллисекунд уже пошла обработка хандлера NewMessage():
ERROR updates [2020-09-25 06:26:23,332]
Unhandled exception on mytask
Traceback (most recent call last):
<...>
File "/home/admin_utils/module_three.py", line 25, in mytask
values (%s, %s, %s, %s, %s, %s, %s)''', entry)
psycopg2.errors.ForeignKeyViolation: insert or update on table "vino" violates foreign key constraint "vino_users_user_id_fk"
DETAIL: Key (user_id)=(1386306872) is not present in table "users".


С очевидным итогом "отсутвует такой юзер в бд", ведь он еще никуда не записан, он только поставлен в очередь. Бдыщ!

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

Еще через 0,7 секунды (709 миллисекунд) поток доходит до своей очереди команд и записывает юзера в базу. Но уже поздно 😁
INFO module_one [2020-09-25 06:26:24,041]
обработчик начал
INFO module_one [2020-09-25 06:26:24,097]
(1386306872, 'Margarita Del Carmem', 'Peña Almonte', None, None)
INFO module_one [2020-09-25 06:26:24,098]
обработчик закончил


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

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

Об этом в следующем посте, не переключайтесь 👋
Как бы помягче объяснить, что Дуров и его команда плохие люди. (мат вырезан цензурой).

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

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

Было два идентификатора: ID канала (2584) и ID чата (0549). Теперь появился третий, виртуальный "пользователь" с ID оканчивающимся на 8824.

Естественно, мне сейчас придётся быстро переписывать в паре мест логику Фомы (моего бота).

P. S. Судя по всему, этот костыль команда телеграм сделала, чтобы "администраторы чатов могли отправлять в чат анонимные сообщения" (из пресс релиза) .

Upd: Ситуация не настолько плоха, как казалось вначале. Они сделали единый ID для костыля, и во всех чатах посты из канала идут от бота телеги. Теперь всегда from_id=1087968824.
Прошло пять часов, и у команды телеграм переполнилась панамка.

Всё вернули как было раньше.

Чтобы вы понимали, в тг порядка 2 млн ботов, владельцы которых были "невероятно счастливы" необходимостью в авральном режиме обновлять свой код.

Начало истории
Давно не хвастался. База данных фейсконтроля чатов на 1 октября 2020 года :)
СЛЕГ! <Z> ️
Асинхронное программирование это очень круто. Но надо иметь в виду, что все части программы исполняются в произвольном порядке, как будет удобнее планировщику и все что может пойти не так, рано или поздно произойдет. Например, мы собираем информацию о сообщениях…
Проблему асинхронности пришлось решить радикально.

Ведь благодаря новым фичам, в чатах теперь могут писать люди, в них в принципе не состоящие.

Поэтому алгоритм получился такой:

1) ловим ошибку постгрес, с отсутствием ключа. Запись помещается в кэш (откройте для себя класс питон queue, не пожалеете)

2) раз в минуту этот кэш проверяет обработчик. Если запись находится в очереди менее 30 секунд, он её пропускает.

3) если запись древнее 30 секунд, то проверяется, есть ли юзер в базе. Если его все ещё нет, то его можно записать через запрос get entity, это точно мимопроходивший. После чего внести наконец то запись в таблицу.

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

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

Upd: Паша официально сообщил, что задело только часть клиентов IOS. Отлично, то есть у них нюансы протокола зависят от платформы. 🙈

Upd2: Товарищ Эшу у себя сбоев не наблюдает. То есть все зависит от используемого фреймворка для ботоводства. 😁
01/10 +1835
02/10 +1707
03/10 +1433
04/10 +1104
05/10 +1241

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

И тишина. И только мёртвые с косами стоят ©
Текст, которому уже больше 10 лет, и он все так же актуален, как и был тогда. Автор - считайте что аноним. Беркем Аль Атоми всего лишь псевдоним.

"Молодцы,киргизы – есть еще ЛЮДИ,способные оторвать хлебало от корыта с комбикормом,и открыто заявить пидарасам в лицо,что они пидарасы,дать им по ебалу – этим пидарасам, убить их в конце концов. Может когда-нибудь и до русских это дойдет,очень на это надеюсь. Преступное государство надо уничтожать!

О как, епта. Государство уничтожать, вон оно как. Надавать пидарасам по эбалам, ага.
Преступное оно, видишь ли, не нравится оно пионэрам, айда его крушить.
Государство, дорогой, это единственная на свете вещь, из-за которой ты ложишься спать живым, сытым и неотпижженым. Ложишься, заметь, в чистую сухую койку, к живой и не свихнувшейся от страха жене. Заметь – не в канаву при дороге ложишься, с хорошей глубокой дыркой заместо правого глазика, а на сухую простыню под целой крышей, и дом твой при этом не горит, а во дворе не месятся на ножах какие-то мутные пассажыры. И никто не стреляет, даже вдалеке.
А в Киргизии сегодня вечером несколько десятков мудаков легло спать совсем не так.Эти мудаки не имели в башке мозгов, для того чтобы понять ими вот эту простую вещь: государство – единственная защита слабых, то есть нас с тобой, от Самого Полного И Беспросветного Пиздеца.
Этих мудаков настропалили “открыто позаявлять пидарасам” – и мудаки ломанулись.
А сейчас они сейчас лежат в куче во дворе республиканской больницы, и помаленьку подтекают на асфальт.
Не в морге в холодильнике, а на улице, и хорошо, если под навесом. Потому что в морге лежат милиционеры, которых мудаки прихватили с собой на тот свет.
Их уже не колышет ни Преступность Государства, ни Эбальники Пидарасов, а завтра-послезавтра, если все успокоится, их придут опознавать родственники с опухшими от горя мордами. И когда продерутся сквозь неизбежную в таких случаях неразбериху, (Тут родственники пришли, им че, выдавать жмуров? Нет? А как же…? А, ведомость составить? А кто будет составлять? Так его же нет! Да вот так нет, он с вечера в Баткен поехал! А я ебу что ли зачем… Так родственникам че сказать? Когда? Вечером пусть приходят? Ладно. Эй, щас вынесут, вы пока опознавайте, и там чем-нибудь своих подписывайте, вечером выдавать начнем! Паспорта чтоб с собой, и свой, и трупа, поняли?) то будут бегать и искать транспорт, чтобы перевезти дохлого мудака домой – ведь им надо отмывать насохшую кровищу и готовить начинающего вонять мудака к похоронам. Транспорт они найдут за совершенно неразумные деньги; завтра почему-то газель будет найти невозможно, а те, кто согласится ехать, дернет с родственников покойного мудака такое бабло, что хватило бы прожить месяц. А то и полтора.
Есличо, когда Люди-Молодцы ломают свои Преступные Государства, с траспортом всегда происходит одно и то же – вот такое, как я написал выше.
Впрочем, ровно то же самое происходит в ломаемом государстве со всем остальным.
И всем маленьким и слабым – а таких ровно 99,985 % от населения – становится от этого очень хуево и неудобно.
Хорошо при этом становится только тем, кто затеял и провернул всю эту хуету.

Поэтому, дорогой пионэр, НИКОГДА НЕ ХОДИ ЛОМАТЬ ПРЕСТУПНЫЕ ГОСУДАРСТВА. Особенно если это Преступное Государство – то самое, в котором живешь именно ты. Чужие – ломай, пожалуйста; это не запрещается. Но НИКОГДА НЕ ХОДИ ЛОМАТЬ СВОЕ.

Лично ты там сможешь нажыть не сбычу мечт, не ответы на мучающие тебя вопросы, а только проломленный череп или проникающее в брюшную полость, с прободением толстого кишечника и веселым скоротечным перитонитом и обширным сепсисом, которому хватит тех жалких полутора дней, пока из-за кипиша не будут работать больнички.
А добра со всего этого нажывут только большие сильные дяденьки, те самые Пидарасы, которых ты направился бить – и которые все это тщательно организовали, провели и порешали за счет сложившего дурные головы мудачья свои текущие задачи. За них не волнуйся, они еще выжмут кучу всяческого ништяка даже из твоего трупа, и из процедуры его закапывания в землю, где тебя давно уже ждут общительные пухлые червячки. Представь себе
хорошенько этих симпатичных нежно-белых красавчегов, копошащихся в твоей брюшине. Увидь их, мысленно – но четко, чтоб от отвращения перекосило всю рожу. И всегда вспоминай о них, когда вдруг захочется поддаться на гнилые разводки и пойти на улицу Бить Пидарасов и Ломать Преступное Государство.
Звать тебя на такие нехорошие дела могут ТОЛЬКО ТЕ САМЫЕ ПИДАРАСЫ, бить которых всякий раз отправляются пока еще живые мудаки. Так всегда было и будет, и никаких исключений из этого правила нету."
После обновления конца сентября, у меня не канал, а вестник "что ещё сломали в тг".

Сегодня сломали запросы iter_messages и iter_participants. Примерно 1.4% запросов успешно навернулись (14 из 1008).

Не удивляйтесь, если у вас что-то сегодня не сработало, а сразу читайте логфайл :)
Привинтил чат для комментариев к каналу. Штоб было.
Какое-то бурление возникло позавчера в брестском чате белорусской оппозиции. На фоне общей стагнации сети чатов "97%", больше 600 человек зашло позавчера и больше 1000 вчера.

Желающие подкормиться приобщиться, велкам - @brest97pro
Из переписки с читателями. Говорят, со стороны виднее 😁
ChatMessagesOrder.py
2.1 KB
Ещё одну проблему тележеньки решил: иногда её глючит и она присылает сообщения клиенту по несколько раз. Если это сообщение с командой для бота, получается некрасиво.

Сложность была в том, что сообщения в обработку попадают не по порядку, а как придётся, если в чате идёт интенсивное общение. То есть просто номера последнего сообщения недостаточно.

В итоге написал два класса. Один это простенький FIFO буфер, второй реализует произвольный набор чатов на этом буфере. Исходник прилагаю.

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

chat_order = ChatMessagesOrder()

И в хэндлере все входящие сообщения пропускать через вызов метода

if chat_order.new_mess (chat_id, mess_id):

В итоге дубликаты будут отсеяны и записаны в лог автоматически. Так же логируются пропуски номеров сообщений, это бывает, если программа криво реализована или проблемы на стороне телеграм.
Адейший совершенно шушпанцер в танчиках (war thunder), называется флак 8.8. Выносит все что видит, с одного выстрела. Странно что редко встречается, им очки за убитых набирать просто идеально.