Select message Telegram что это

Напишу сразу, о том что данную статью я изначально выложил на habr — с целью узнать популярное мнение к такому подходу, методы улучшения и просто разные мнения. Однако получил всего пять комментариев, из которых только один информативный, но не по теме. Проанализировал немного статистику и увидев, что за последний год посты новых акаунтов не читаются и не поднимаются в рейтинге. Я решил на Хабре быть ReadOnly пользователем, а здесь буду писать. Я буду рад получить критику и советы по улучшению данного метода.

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

Но готового решения для пагинации, которое бы нам подходило мы не нашли. Поэтому было принято решение изобретать велосипед. Решение моих товарищей было максимально странным, брать количество записей и перебирать их в цикле от 1 до N (конца, записей), но данная идея сразу была отброшена. Поэтому предоставляю вашему вниманию наше творчество, которое мы изобрели.

How to Translate Messages on Telegram Messenger #shorts

Демонстрация результата

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

Рис. 1. Демонстрация результата
Создание «шаблонного» бота

Для упрощения описания алгоритма, я буду описывать его на шаблоном боте. Который будет отвечать на любое отправленное ему сообщение — «Привет»ю

Создание inline кнопок

Сначало прописываем зависимость в начале кода:

from telebot.types import ReplyKeyboardMarkup, InlineKeyboardMarkup, InlineKeyboardButton
Реализуем кнопку скрыть

Перед тем, как отправить сообщение пользователю создадим markup с inline кнопкой «скрыть» после чего отправим пользователю сообщение с данной кнопкой.

markup = InlineKeyboardMarkup() markup.add(InlineKeyboardButton(text=’Скрыть’, callback_data=’unseen’)) bot.send_message(m.from_user.id, «Привет», reply_markup = markup)

Чтобы кнопка работала, нам для нее нужен отдельный обработчик он выглядит так:

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

Рис 2. Реализации кнопки «скрыть»

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

Кнопки навигации

Теперь перейдем непосредственно к кнопкам «Вперед« и «Назад» для перехода по страницам? которые будут располагаться под кнопкой »скрыть».

К уже существующему markup добавим еще две новые кнопки. Т. к при первом сообщение от бота приходит первая страница, добавим пока что только кнопку «Вперед».

Это и многое другое только у нас в телеграм канале (ссылка в комментариях)

Кнопка вперед будет в callback_data отправлять строку «next-page«, а в обработчике мы будем прибавлять к page 1. После чего пересоздадим markap уже с кнопкой назад и новым сообщением. Аналогичным образом для кнопки назад в callback_data будем отправлять строку »back-page»

Теперь наш код выглядит вот так:

На данном этапе для простоты демонстрации я делаю count и page глобальными переменными, позже я заменю их.

Теперь мы можем перемещаться по страницам:

Рис. 3. Демонстрация внешнего вида inline кнопок

Да, но перед нами встает две проблемы:

  • Нужно писать отдельные исключения, чтобы при возврате кнопкой назад на первую страницу — кнопка назад больше не отображалась. А при переходе на последнюю не было кнопки вперед.
  • Проблема передачи локальной переменной (page и count) от главной функции в обработчик нажатия кнопки. Telebot в отличие от например aiogramm не может передать другие параметры вместе с callback_data. А callback_data – это строка. Решение этой проблемы, я увидел в передаче в callback_data склеенного через разделитель json в который и запишу count и page. Мой товарищ вышел из данной ситуации более странным на мой взгляд решением – он записывал во временную таблицу бд id узера, id сообщение и страницу, которую он смотрит и потом удалял их. Достаточно радикальный способ по ряду многих причин (что если не удалиться запись из БД; БД вообще не для этого сделана; нам нужно будет столько таблиц, во скольких местах будет пагинация), но переубедить я его не смог) .Как вариант еще можно создать публичный словарь, но ради двух переменных это странно + способ с передачей json с двумя параметрами, как строку в callback_data на мой взгляд кажется самым универсальным и адекватным решением при данной проблеме.

Для начала решим 2 проблему:

  • Удалим глобальные переменный page и count и создадим их внутри функции start
  • В callback будем отправлять такую строку:

Для кнопки вперед, это выглядит вот так:

markup.add(InlineKeyboardButton(text=f’Вперёд —>’, callback_data=»»))

На данном этапе видно, что я начал отдавать номер строки, на которую перехожу. Если нажму «Назад» со второй строки в обработчик уйдет 1. Это избавляет меня от необходимости использовать теперь разные обработчик для кнопки назад (back-page) и вперед (next-page) (их можно просто удалить)

Еще по теме:  Телеграм долго считает размер кэша

Теперь за пагинацию будет отвечать новый обработчик, который увидит в полученной строке вхождение ‘pagination’:

После чего строка полученная в callback_data будет распаршена в json. И уже из JSON мы получим необходимые нам Count и Page.

elif ‘pagination’ in req[0]: json_string = json.loads(req[0]) count = json_string[‘CountPage’] page = json_string[‘NumberPage’]

Пока пишу новый обработчик, сразу решу проблему 1. Сделаю три условия вывода кнопок.

  • Вывод кнопки «Назад» для последний страницы
  • Вывод «Вперед» и «Назад» для всех страниц между первой и последней
  • Вывод кнопки «Назад» для последний страницы

Рис. 4. Демонстрация конечного этапа реализации кнопок пагинации

А вот и полученный код:

Получения нужных строк по страницам из БД

Вернемся к «главной» функции start, которая принимает сообщения от пользователя. Я оставил count = 10 и page = 1; Пора это исправить!

count — необходимо будет получать из БД, а в сообщение пользователю отдавать необходимые строки.

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

Что бы выводить построчно записи из БД я буду использовать конструкцию SQL: OFFSET-FETCH. Она предназначена, как раз для разбиения результирующего набора на части (страницы)

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

Рис. 5. Демонстрация запроса с использованием конструкции OFFSET-FETCH.

Делаем сортировку по id и отображаем 15 записей от 0 (т.е самой первой). Это будет наша первая страница, что бы показать 2 страницу нужно будет пропустить столько записей, сколько было на первой странице.

Таким образом число после NEXT – является всегда статичным это будет переменная SkipSize. А число после OFFSET — то после которой надо забрать следующие (SkipSize) строк. Записать это можно, как (Номер страницы – 1)*SkipSize

На псевдо-коде это выглядит вот так:

Рис. 6. Реализация запроса, для пагинации на псевдо коде.

Теперь перейдем к написанию самого класса. Он вышел вот таким:

import psycopg2 from psycopg2 import sql from psycopg2._psycopg import AsIs class Database: def __init__(self): self.conn = psycopg2.connect(database=’myDataBase’, user=’MyUsers’, password=SECRET’, host=’ip_host’, port=5432) self.cursor = self.conn.cursor() #Функцию пытался сделать максимально адаптивной под разные потребности и таблицы, поэтому у нее есть такие параметры, как: # tables – имя самой таблицы # schema – схема, по умолчанию organization т.к большая часть таблиц лежит именно в этой схеме # Page – непосредственно номер страницы, который нужно вывести # SkipSize – сколько строк, необходимо вывести # order – аргумент, по которому происходит сортировка # where строка в которую можно передать строку where (по хорошему так делать не надо, это слишком костыльно) def listColledjeForPage(self, tables, order, schema=’organization’, Page=1, SkipSize=1, wheres=»): sql = f»»»select * from %(schemas)s.%(tables)s o %(wheres)s ORDER BY o.%(orders)s OFFSET %(skipsPage)s ROWS FETCH NEXT %(SkipSizes)s ROWS only;»»» self.cursor.execute(sql, <‘schemas’: AsIs(schema), ‘tables’: AsIs(tables), ‘orders’: AsIs(order), ‘skipsPage’: ((Page — 1) * SkipSize), ‘SkipSizes’: SkipSize, ‘wheres’: AsIs(wheres)>) res = self.cursor.fetchall() return res, len(res)

Теперь в main нам надо объявить наш новый класс:

from database import Database database = Database()

А вот так к нему можно обратиться:

stringsearch = ‘колледж связи’ sqlTransaction = database.listColledjeForPage(tables = ‘organization’, order=’title_full’, Page=1, SkipSize=1, wheres=f»where lower(title_full) like lower(‘%%’) OR lower(title) like lower(‘%%’)») data = sqlTransaction[0] #Набор строк count = sqlTransaction[1] #Количество строк print(data) print(count)

Или вот так

sqlTransaction = database.listColledjeForPage(tables = ‘organization’, order=’title_full’, Page=1, SkipSize=15) data = sqlTransaction[0] # Набор строк count = sqlTransaction[1] # Количество строк print(data) print(count)

Вот такой вывод получаем по итогу:

Рис. 7. Ответ от функции на запрос 15 записей с 1 страницы из БД

И тут я понял, что общие количество записей так и не получил (тот самый count). В return к функции (listColledjeForPage) вывода записей добавлю еще вывод общего количества записей в запросе.

self.cursor.execute(f»»»select Count(*) from %(schemas)s.%(tables)s o %(wheres)s;»»», <‘schemas’: AsIs(schema), ‘tables’: AsIs(tables),’wheres’: AsIs(wheres)>) count = self.cursor.fetchone()[0] return res, len(res), count

Я еще раз убедился, что все работает и пошел дописывать main

Сделаем вывод уже полученной строки из нашего нового класса. В «главной функции» переменную page оставляем равной 1, а count получаем из функции класса database, которая выполняет нужный нам запрос.

page = 1 sqlTransaction = database.listColledjeForPage(tables = ‘organization’, order=’title’, Page=1, SkipSize=1) # SkipSize — т.к я буду отображать по одной записи data = sqlTransaction[0] # Набор строк count = sqlTransaction[2] # Количество строк print() markup = InlineKeyboardMarkup() markup.add(InlineKeyboardButton(text=’Скрыть’, callback_data=’unseen’)) markup.add(InlineKeyboardButton(text=f’/’, callback_data=f’ ‘), InlineKeyboardButton(text=f’Вперёд —>’, callback_data=»»)) bot.send_message(m.from_user.id, str(data[0]), reply_markup = markup)

Вот, что получили:

Рис. 8. Вывод информации из БД в не отформатированном виде

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

Форматируем тест сообщения с помощью HTML

bot.send_message(m.from_user.id, f’ nn’ f’Короткое название: n’ f’Email: n’ f’Сайт: ‘, parse_mode=»HTML», reply_markup = markup)

Рис. 9. Вывод информации из БД в отформатированном виде

Теперь такое же форматирование вставляем в обработчик при редактировании сообщения после нажатия кнопок «Впред»/»Назад».

Рис. 10. Итоговый результат

import psycopg2 from psycopg2 import sql from psycopg2._psycopg import AsIs class Database: def __init__(self): self.conn = psycopg2.connect(database=’MyDataBase’, user=’MyUser’, password=’SECRET’, host=’MeServ’, port=5432) self.cursor = self.conn.cursor() def listColledjeForPage(self, tables, order, schema=’organization’, Page=1, SkipSize=1, wheres=»): sql = f»»»select * from %(schemas)s.%(tables)s o %(wheres)s ORDER BY o.%(orders)s OFFSET %(skipsPage)s ROWS FETCH NEXT %(SkipSizes)s ROWS only;»»» self.cursor.execute(sql, <‘schemas’: AsIs(schema), ‘tables’: AsIs(tables), ‘orders’: AsIs(order), ‘skipsPage’: ((Page — 1) * SkipSize), ‘SkipSizes’: SkipSize, ‘wheres’: AsIs(wheres)>) res = self.cursor.fetchall() self.cursor.execute(f»»»select Count(*) from %(schemas)s.%(tables)s o %(wheres)s;»»», <‘schemas’: AsIs(schema), ‘tables’: AsIs(tables),’wheres’: AsIs(wheres)>) count = self.cursor.fetchone()[0] return res, len(res), count

Источник: vc.ru

Объект MessageEntity — приятный бонус от Телеграм

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

Еще по теме:  Имя пользователя в Телеграмме пример для девушки на английском

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

Если текстовая часть имеет форматирование, то Телеграм вместе с текстом направить в бот массив объектов MessageEntity, при этом если посмотреть на сам текст, то он без тегов форматирования, то есть все лежит в объекте entities .

Нам останется только получить фрагмент по указанным координатам [offset, length], и что-то с ним сделать — например закрыть каждый символ знаком звездочки (*).

Пример приведу в окружении Google App Script на JavaScript, как работать в этом окружении можете ознакомиться в статье про бота обратной связи

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

В этой функции разделим объекты форматирования на две группы [запрещенные и остальные], если запрещенные обнаружены, то передадим в функцию преобразования prepareText()

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

Функция replaceText() получаем исходный текст и объект с форматированием, по координатам offset и length заменим все символы кроме пробелов на знак звездочки (*)

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

Результат работы бота

Весь код бота вы можете скачать и использовать его как пример

Источник: imakebots.ru

Telegram в качестве хранилища данных для IT проектов

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

Весь проект выложен на github, ссылка будет в конце статьи.

image

Основная проблема

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

В итоге нужно было выбрать способ хранить эти данные.

  1. Вариант — глобальные переменные, оперативная память. Вариант сразу провальный, так как при падении программы мы теряем все
  2. Вариант — запись в файл на диске. Для такого проекта может и пойдет, но я планировал деплой бота на heroku, который каждый день стирает все данные с диска. Так что этот вариант не подошел
  3. Вариант — Google-таблицы. Изначально я хотел остановится на этом варианте, но начал разбираться и понял, что есть ограничение на количество запросов к таблице, и чтобы только начать использовать таблицу нужно написать кучу строк кода и разобраться в их не самом простом апи
  4. Вариант — база данных. Да, это наилучший вариант во всем. Но для такого проекта это даже смешно использовать. Также развертывание и поддержка базы данных на стороннем сервере обойдется в копеечку.

Решение

Идея очень простая, для хранения данных мы будем использовать in memory базу данных sqllite, так как она уже встроена в python 3 и будем делать бэкапы нашей таблицы на сервера Telegram с небольшим интервалом (примерно каждые 30 секунд) и бэкап при закрытие процесса программы.

Если сервер упал, то при первом запросе мы автоматически загрузим нашу таблицу с сервера Telegram и восстановим данные в sqllite.

Можно использовать и любую другую in memory бд, кому как нравится.

Плюсы

  1. Быстродействие — за счет работы с данными в оперативной памяти скорость выполнения программы даже быстрее, чем при использовании бд на стороннем сервере (графики скорости выполнения и тестирования будут в конце)
  2. Бесплатно — не нужно покупать сторонние сервера для баз данных и все данные хранятся в виде бэкапа бесплатно на серверах Telegramа
  3. Относительно надежно — если сервер падает по непонятным причинам, то мы максимум теряем данные за последние 30 секунд (время интервала бэкапов), для рабочего прототипа или небольшого проекта будет достаточно.
  4. Минимальные затраты при переходе на обычную бд — нужно заменить данные подключения, убрать код бекапов и перенести данные таблицы из бэкапа на новую бд.

Минусы

  1. Отсутствие горизонтального масштабирования
  2. Нужно два аккаунта в Telegramе (один для администратора, другой для тестирования пользователя)
  3. Сервер не будет работать в России из-за блокировок
  4. В комментариях я думаю Вы найдете еще десяток других нюансов.

Время говнокодить

Напишем простой кликер и проведем тесты на скорость выполнения.

Бот будет написан на языке программирования python с использованием асинхронной библиотеки взаимодействия с api телеграмма aiogram.

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

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

Для того, чтобы получить admin_id и config_id нам нужно запустить бота с аккаунта администратора и написать боту «admin», после чего он создаст первый бекап, и напишет ваш admin_id, config_id. Заменяем и запускаем бота заново.

#———————Настройки бота————————- # Ваш токен от BotFather TOKEN = ‘1234567:your_token’ # Логирование logging.basicConfig(level=logging.INFO) bot = Bot(token=TOKEN) dp = Dispatcher(bot) # Ваш айди аккаунта администратора и айди сообщения где хранится файл с данными admin_id=12345678 config_id=12345 conn = sqlite3.connect(«:memory:») # настройки in memory бд cursor = conn.cursor()

Еще по теме:  Анимированное изображение для Телеграм

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

Если боту приходит сообщение со словом «admin», то мы создаем таблицу пользователей с такой моделью данных:

  • chatid — уникальный чат айди пользователя
  • name — имя пользователя
  • click — количество кликов
  • state — значение для машины состояний, в данном проекте не используется, но в более сложных без него не обойтись

# Логика для администратора if message.text == ‘admin’: cursor.execute(«CREATE TABLE users (chatid INTEGER , name TEXT, click INTEGER, state INTEGER)») cursor.execute(«INSERT INTO users VALUES (1234, ‘eee’, 1,0)») conn.commit() sql = «SELECT * FROM users » cursor.execute(sql) data = cursor.fetchall() str_data = json.dumps(data) await bot.send_document(message.chat.id, io.StringIO(str_data)) await bot.send_message(message.chat.id, ‘admin_id = <>’.format(message.chat.id)) await bot.send_message(message.chat.id, ‘config_id = <>’.format(message.message_id+1))

Логика для пользователя

Первым делом пытаемся получить из in memory бд данные пользователя, который отправил сообщение. Если ловим ошибку, то загружаем данные с бекапа сервера Telergam, заполняем нашу бд данными с бекапа и повторно пытаемся найти пользователя.

# Логика для пользователя try: sql = «SELECT * FROM users where chatid=<>».format(message.chat.id) cursor.execute(sql) data = cursor.fetchone() # or use fetchone() except Exception: data = await get_data() cursor.execute(«CREATE TABLE users (chatid INTEGER , name TEXT, click INTEGER, state INTEGER)») cursor.executemany(«INSERT INTO users VALUES (. )», data) conn.commit() sql = «SELECT * FROM users where chatid=<>».format(message.chat.id) cursor.execute(sql) data = cursor.fetchone() # or use fetchone()

Если мы нашли пользователя в бд, то обрабатываем кнопки:

  • При нажатие «Клик» мы обновляем количество кликов у данного пользователя
  • При нажатие «Рейтинг» мы выводим список пятнадцати человек у которых наибольшее количество кликов.

#При нажатии кнопки клик увеличиваем значение click на один и сохраняем if data is not None: if message.text == ‘Клик’: sql = «UPDATE users SET click = <> WHERE chatid = <>».format(data[2]+1,message.chat.id) cursor.execute(sql) conn.commit() await bot.send_message(message.chat.id, ‘Кликов: <> ‘.format(data[2]+1)) # При нажатии кнопки Рейтинг выводим пользователю топ 10 if message.text == ‘Рейтинг’: sql = «SELECT * FROM users ORDER BY click DESC LIMIT 15» cursor.execute(sql) newlist = cursor.fetchall() # or use fetchone() sql_count = «SELECT COUNT(chatid) FROM users» cursor.execute(sql_count) count=cursor.fetchone() rating=’Всего: <>n’.format(count[0]) i=1 for user in newlist: rating=rating+str(i)+’: ‘+user[1]+’ — ‘+str(user[2])+’n’ i+=1 await bot.send_message(message.chat.id, rating) else: await bot.send_message(message.chat.id, ‘Вы не зарегистрированы’)

Напишем логику для регистрации пользователя

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

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

sql_select = «SELECT * FROM users where chatid=<>».format(message.chat.id) sql_insert = «INSERT INTO users VALUES (<>, ‘<>’, <>,<>)».format(message.chat.id,message.chat.first_name, 0, 0) try: cursor.execute(sql_select) data = cursor.fetchone() if data is None: cursor.execute(sql_insert) conn.commit() await save_data() except Exception: data = await get_data() cursor.execute(«CREATE TABLE users (chatid INTEGER , name TEXT, click INTEGER, state INTEGER)») cursor.executemany(«INSERT INTO users VALUES (. )», data) conn.commit() cursor.execute(sql_select) data = cursor.fetchone() if data is None: cursor.execute(sql_insert) conn.commit() await save_data() # Создаем кнопки button = KeyboardButton(‘Клик’) button2 = KeyboardButton(‘Рейтинг’) # Добавляем kb = ReplyKeyboardMarkup(resize_keyboard=True).add(button).add(button2) # Отправляем сообщение с кнопкой await bot.send_message(message.chat.id,’Приветствую <>’.format(message.chat.first_name),reply_markup=kb)

Так, ну и самое интересное.

Сохранение и получение данных с сервера Telergam

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

#———————Сохранение данных————————- async def save_data(): sql = «SELECT * FROM users » cursor.execute(sql) data = cursor.fetchall() # or use fetchone() try: # Переводим словарь в строку str_data=json.dumps(data) # Обновляем наш файл с данными await bot.edit_message_media(InputMediaDocument(io.StringIO(str_data)), admin_id, config_id) except Exception as ex: print(ex)

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

Ну вот почти и все, осталось только написать таймер, чтобы делал бэкапы и протестировать бота.
Создаем поток, который каждые 30 секунд выполняет наш метод save_data()

def timer_start(): threading.Timer(30.0, timer_start).start() try: asyncio.run_coroutine_threadsafe(save_data(),bot.loop) except Exception as exc: pass

Ну и в главной программе мы запускаем таймер и самого бота.

#———————Запуск бота————————- if __name__ == ‘__main__’: timer_start() executor.start_polling(dp, skip_updates=True)

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

Как запустить

  1. Скачиваем проект с гитхаба. Запускаем проект в любой среде разработки для python (Например: PyCharm).
  2. Среда разработки автоматически подгрузит необходимые библиотеки с файла requirements.
  3. Заменяем Token от BotFather в файле main.py

  • Запускаем проект
  • Со второго аккаунта нажимаем /start и пишем слово «admin»
  • Тестирование и графики

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

    Графики сделаны по выборкам из ~100 запрос-ответов. И представлены средние показатели выборки.

    В качестве базы данных на стороннем сервере использовался PostgreSQL на Amazon RDS с минимальными характеристиками.

    При одном миллионе пользователей время бэкапов становится проблемой.

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

    Вывод

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

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

    Подобие чатвдвоем и чатрулет, но только в телеграмме.

    Он ищет в радиусе 100 км человека противоположного пола для общения и реализует закрытый чат с новым собеседником.

    Если будет интересно могу скинуть исходный код проекта. Так же если данная тема будет актуальна, то в следующей статье могу описать создание Rest api без внешних БД. То есть такой стек django-sqllite-Telegram.

    Буду рад любой критике, спасибо за внимание!

    Источник: temofeev.ru

    Рейтинг
    ( Пока оценок нет )
    Загрузка ...