Timeweb Телеграм бот с бд

Сайт о том, как стать программистом и как с этим жить потом

Serverless Telegram бот на базе PHP и AWS Lambda

В Сети есть огромное количество мануалов, посвящённых работе бессерверным окружениям от Amazon Webservices (и не только) и даже запуску «Hello, World!» на PHP внутри этих окружений. Но, решив самостоятельно собрать что-то дельное при помощи этих инструментов, я столкнулся с огромным количеством пробелов и подводных камней. Обойдя их, я в конце концов запустил простенького Telegram-бота, которого можно дорабатывать в любом направлении. Но давайте обо всём по порядку!

Видеоверсия статьи доступна ниже, но я рекомендую сочетать её с текстом.

Что такое Serverless и AWS Lambda?

Если Вы ещё не знакомы с концепцией так называемой «Бессерверной Архитектуры» или Serverless, у Вас вполне может возникнуть совершенно логичный вопрос: «А зачем это всё нужно?». И начинать надо именно с понимания области применения данного подхода, чтобы потом не было мучительно больно.

Хостинг timeweb.ru. Работа с базами данных. 2023 год

Serverless — это относительно молодой метод запуска Ваших скриптов в облаках, таких как AWS. Сейчас довольно популярны подходы Something As A Service (*aaS — например, IaaS, PaaS, SaaS), который заключаются, грубо говоря, в предоставлении определённого уровня сервиса по клику мышки, будь то готовая среда выполнения для Вашей логики или, например, знакомый многим Office 365. Вам ничего не надо устанавливать, кроме браузера, для того, чтобы начать работу. Так вот, Serverless является реализацией подхода FaaS (Function as a Service), заключающегося в предоставлении потребителю готовой платформы для разработки, запуска и управления некой функциональностью без необходимости самостоятельной её подготовки и настройки.

Вам не важно, где запускается Ваш скрипт, откуда провайдер возьмёт ресурсы и сколько он их возьмёт. Это означает, что приложение может легко масштабироваться до любых размеров в зависимости от нагрузки. Для PHP-скриптов это означает, что Вам надо либо работать в парадигме Stateless, либо тщательно подумать о том, как будет храниться состояние (сессии). Благо Serverless не накладывает ограничения на вызов необходимых хранилищ, будь то привычная многим MySQL база или какое-то более навороченное решение.

Важной особенностью Serverless является короткий цикл работы скрипта (в зависимости от платформы — до нескольких часов). Если мы говорим про AWS, то их таймаут составляет 15 минут, поэтому аналитические расчёты или огромный map-reduce на час тут не прокатят. Но вот запустить того же telegram-бота, который должен быстро отвечать пользователю — это довольно штатная задача для Serverless приложений. Это означает, что на них нацелены те команды и разработчики, которые хотят быстро запустить небольшое приложение. И это же говорит о том, что стоимость данных услуг очень и очень низкая при понимании вышеозначенных ограничений.

Мощности Lambda являются настраиваемыми, но занятный факт в том, что у AWS мощности CPU для Lambda недоступны для настройки и увеличиваются автоматически прямо пропорционально объёму выделенной RAM. Таким образом, увеличивая объём RAM, Вы буквально ускоряете приложение по всем фронтам.

AWS Lambda работает по принципу «Триггер — Выполнение — Последствия». Триггер — это событие, которые побуждает Lambda к выполнению. Последствия — это то, что порождает Lambda — запись в БД, логи, вызов других Lambda. При первом вызове для выполнения Lambda на стороне AWS генерируется микро-виртуальная машина, которая будет жить некоторое время на случай последующих вызовов. На эту машину загружается код из S3 хранилища, готовится среда выполнения и происходит вызов функции.

Цены на сервис

На момент написания статьи AWS предоставляет 1 миллион запросов и 400 000 ГБ-секунд в месяц бесплатно. Если первый параметр очевиден, то второй стоит описать подробнее. Гигабайт-секунды — это метрика объёма вычислений, которая представляет собой отношение общего времени выполнения к выделенной оперативной памяти. Итак, если у Вас есть 1,5 миллиона запросов по 1 секунде каждый, а для скрипта выделено 256 мегабайт RAM, то суммарный объём вычислений будет равен

Еще по теме:  Делаем твой Телеграмм лучше с котиками

S = 1 500 000 * 1 * 256 / 1024 = 375 000 ГБ-с

Как видите, этот объём укладывается в лимит бесплатного сервиса, но количество запросов превышает 1 миллион и тарифицируется (по ценам на момент написания статьи) по 20 центов за миллион запросов. Это означает, что 1,5 миллиона запросов в месяц к своему скрипту Вы заплатите 10 центов.

Но не торопитесь бежать и открывать аккаунт в AWS. Помимо этого тарифицируются смежные сервисы:

  • API Gateway — самый простой, но самый дорогой способ вызова Lambda в AWS
  • Elastic LoadBalancing (ELB) — на мой взгляд, оптимальный способ вызова
  • Route 53 — для работы бота, например, понадобится доменное имя. За него надо платить
  • SSL-сертификат — также требование Telegram API
  • S3 — Вам потребуется хранилище для того, чтобы деплоить приложение

Тем не менее, если Вы не используете API Gateway, все сервисы суммарно тоже не очень дорогие. ELB при работе целый месяц в режиме 24/7 при 25 новых соединениях в секунду обойдётся Вам в 22.5 доллара в месяц. Это уже история для довольно плотной загрузки Вашего скрипта. При работе в режиме 1 запрос в минуту сумма будет значительно меньше. Сервис DNZ будет стоить 50 центов за месяц использования одной зоны (разумеется, выгоднее использовать DNS-зону не только для бота). 100 000 запросов обойдутся Вам в 0.04-0.06 доллара в месяц. Сертификат для 1 зоны будет стоить 0.75 долларов в месяц. S3 стоит 0.0245 доллара за 1 ГБ, которого Вам вполне хватит, если Вы будете деплоить логику несколько раз в неделю.

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

Тонкости организации работы

Теперь поговорим о практике. Как я уже написал выше, самым простым, но самым дорогим (в несколько раз дороже ELB) способом вызова Lambda в AWS является API Gateway. По интересному стечению обстоятельств, именно этот тип вызова указывается во всех мануалах по настройке окружения. Ценообразование вполне логично — чем меньше ты делаешь своими руками, тем больше платишь. Мы же будем рассматривать настройку при помощи ELB, чтобы экономить деньги.

Сам Amazon в своих мануалах предлагает деплоить код, упаковывая его в zip-архивы и загружая на их мощности через AWS API или через интерфейс. В воздухе запахло 2000-ными. Конечно же, это не подход к работе с доставкой кода в современных реалиях, поэтому мы будем использовать принятый многими как стандарт Serverless framework, который разработан на Node.js и позволяет управлять приложениями на базе AWS Lambda.

Ещё одной особенностью является то, что AWS Lambda не поддерживает из коробки вызов PHP-скриптов. А это означает, что нам придётся создавать среду исполнения самостоятельно. Благо сейчас на рынке появилась PHP-библиотека Bref, интегрированная с Serverless, решающая эту задачу. Тем не менее, Вы можете самостоятельно собрать среду исполнения и подружить её с Lambda API. Но дело это неблагодарное, так как проблема уже решена изящным и приемлемым способом.

Настраиваем окружение и AWS

AWS CLI

Начинать стоит с создания аккаунта в AWS и установки AWS CLI. Консольная оболочка от AWS основывается на Python версий 2.7+ или 3.4+. AWS рекомендуют 3 версию языка, поэтому спорить с этим решением мы не будем. Примеры приведу для Ubuntu, но Вы смело можете интерпретировать их для своих Linux-дистрибутивов.

sudo apt-get -y install python3-pip

Далее установим непосредственно утилиту AWS CLI

pip3 install awscli —upgrade —user

Проверку установки можно сделать при помощи

aws —version

После этого Вам нужно будет подключить aws cli к Вашему аккаунту. Конечно, можно использовать и Ваши логин и пароль, но лучше создать отдельного пользователя через AWS IAM и установить ему только необходимые права доступа. Сама конфигурация вызывается просто

aws configure

На этом шаге Вам нужны будут AWS Access Key и AWS Secret. Оба параметра можно найти в ASW IAM, зайдя на страницу нужного Вам пользователя и выбрав вкладку Security credentials. На ней будет кнопка «Create access key», которая позволит Вам сгенерировать ключи доступа. Зафиксируйте их у себя.

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

Serverless Framework

Для установки Вам также потребуется аккаунт на https://serverless.com/. Версия для разработки бесплатна, и её функционала нам хватит за глаза.
После регистрации нужно установить утилиту serverless у себя на рабочей станции. Я уже отметил, что нам потребуется Node.js (нужна версия 6 и выше).

sudo apt-get -y install nodejs

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

mkdir ~/.npm-global
export PATH=~/.npm-global/bin:$PATH
source ~/.profile

npm config set prefix ‘~/.npm-global’

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

Ещё один telegram-бот или реализация бота для знакомств

Ещё один telegram-бот или реализация бота для знакомств

2018-11-18 в 19:08, admin , рубрики: .net, c-sharp, C#, telegram, telegram bots, Системы обмена сообщениями

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

Краткая предыстория

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

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

Задача

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

Ещё один telegram-бот или реализация бота для знакомств - 1

Подготовка к работе

Как создавать бота через BotFather не знает только тот, кому это не интересно, так что наполнять статью лишней информацией я не стану.

Хранение «анкет»

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

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

public class user < [Key] public string tg_id < get; set; >//Уникальный айди пользователя public string name < get; set; >//Отображаемое имя public string age < get; set; >// Возраст public string country < get; set; >// Страна public string city < get; set; >//Город public string gender < get; set; >//Пол public string photo < get; set; >//Ссылка на фото public string tg_username < get; set; >//Телеграмовский ник-нейм, по которому можно будет перейти к пользователю в личную переписку public string tg_chat_id < get; set; >//Айди чата, куда отправлять ответ >

Для хранения была выбрана БД PostgreSQL, которая была развернута на удаленном сервере.
Предварительно, устанавливаем EntityFramework, через NuGet. Это нереально упрощает жизнь в работе с БД.

Для работы требуется пакет:

А для миграций требуется пакет:

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

public DbSet user < get; set; >protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)

В дальнейшем выполняем миграцию.

Для этого в Консоли диспетчера пакетов выполняем команды:
enable-migrations
Включаем механизм миграций
Add-migration *Имя миграции*
Создаем миграцию
update-database
Обновляем БД

Теперь у нас в БД появятся две таблицы: История миграций и сама таблица user.

Ещё один telegram-бот или реализация бота для знакомств - 2

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

Бот-обработчик

Сам telegram предлагает два варианта получения обновлений: webhook или постоянно дергать сервера, проверяя обновления. Webhook имеет большое количество сложностей, поэтому проще просто проверять обновления.

Получение обновлений их обработка

Для того, чтобы не создавать велосипед(иногда бывает полезно), проще использовать готовое решение: Telegram.Bot by MrRoundRobin — отличная, очень удобная библиотека для работы с Telegram.

Создаем в решение новый проект ConsoleApp, куда и устанавливаем этот пакет.

Таким образом, мы начали проверку на обновления и поставили свои обработчики ошибок.
BotOnMessageReceived — обработчик получения «обычных» сообщений
BotOnCallbackQueryReceived — обработчик нажатия кнопок, которые появляются под сообщением.

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

Еще по теме:  Почему выключается экран при прослушивании голосового сообщения Телеграм

IEnumerable>

При открытии бота, ему сразу же отправляется сообщение с текстом «/start», так что нам нужно в BotOnMessageReceived обработать это сообщение и отправить в ответ наши кнопки.

Регистрация

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

RegForm.cs
public class RegForm < public string tg_id < get; set; >public string name < get; set; >public string age < get; set; >public string country < get; set; >public string city < get; set; >public string gender < get; set; >public string photo < get; set; >public string tg_username < get; set; >public string tg_chat_id < get; set; >public int stage; public RegForm(string id, string chat_id, string username) < stage = 1; tg_id = id; tg_username = username; >public (string, int) StageText(string id) < if (stage == 1) return («Введите отображаемое имя:», stage); if (stage == 2) return («Введите возраст:», stage); if (stage == 3) return («Введите Вашу страну:», stage); if (stage == 4) return («Введите Ваш город:», stage); if (stage == 5) return («Введите Ваш пол:», stage); else return («Отправьте боту Ваше фото:», stage); >public bool SetParam(string param) < if (stage == 1) name = param; if (stage == 2) age = param; if (stage == 3) country = param; if (stage == 4) city = param; if (stage == 5) gender = param; if (stage == 6) photo = param; stage++; return true; >>

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

А самой памятью выступает static Dictionary registrations = new Dictionary(); , в который мы добавляем новый KeyValuePair, при нажатии на кнопку.

Чтобы бот знал, как ему реагировать на нажатие, нужно в BotOnCallbackQueryReceived добавить

var message = e.CallbackQuery; if (message.Data == «Registration») < RegForm form = new RegForm(message.From.Id.ToString(), message.Message.Chat.Id.ToString(), message.From.Username);//Создаем новую форму регистрации registrations.Add(message.From.Id.ToString(), form);//Добавляем форму в «память», где ключом будет telegram_id пользователя. var t = form.StageText(form.tg_id); //Получаем текст, который отправим пользователю, в зависимости от стадии регистрации. Bot.SendTextMessageAsync(message.Message.Chat.Id, t.Item1);//отправляем сообщение пользователю. return; >

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

using (Context db = new Context()) < IMapper mapper = new MapperConfiguration(cfg =>cfg.CreateMap()).CreateMapper(); if (db.user.Where(x => x.tg_id == message.From.Id.ToString()).Count() != 0) db.user.Update(mapper.Map(u)); else < db.user.Add(mapper.Map(u)); > db.SaveChanges(); >

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

Сохранение фото пользователя
if (message.Type == MessageType.Photo) < string file = Bot.GetFileAsync(message.Photo[message.Photo.Count() — 1].FileId).Result.FilePath; string filepath = message.From.Id + «.» + file.Split(‘.’).Last(); using (FileStream fileStream = new FileStream(«C:images» + filepath, FileMode.OpenOrCreate, FileAccess.ReadWrite)) < var st = Bot.DownloadFileAsync(file).Result; st.Position = 0; st.CopyTo(fileStream); >u.SetParam(«C:images» + filepath); >

Показ остальных анкет

Для этого просто нужно брать данные из БД и отправлять пользователю.

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

public static User GetRandom() < Stopwatch s = new Stopwatch(); s.Start(); User u; using (Context db = new Context()) < Random r = new Random(); int count = db.user.Count(); if (count >1) count = count — 1; List users = mapper.Map, List>(db.user.ToList()); u = users.ElementAt(r.Next(0, count)); > Console.WriteLine(«[» + DateTime.Now + «] For finding » + s.ElapsedMilliseconds + » ms»); s = null; return u; >

Обработчик нажатия кнопки Next:

if (message.Data == «Next») < if (searchForms.Count != 0) < searchForms.Remove(message.From.Id.ToString()); >IMapper mapper = new MapperConfiguration(cfg => cfg.CreateMap()).CreateMapper(); User user = BaseWorker.GetRandom(); SendAnket(user, message.Message.Chat.Id.ToString());//Метод, который создает форматирование в сообщении. return; >

Заключение

При всей своей простоте, бот понравился публике.

Меньше чем за сутки, 134 юзера оставили свои анкеты, есть положительные отклики. И без особой рекламы — лишь один пост на сайте, который особо плюсов не набрал.

Боты — это давно забытое старое, которое обрело новую жизнь. Они помогают реально автоматизировать многие процессы и даже искать себе пару в интернете. В обход забитых монетизацией сайтов знакомств.

Спасибо, что дочитали до конца.

Good luck, have fun, dont eat yellow snow.

Источник: www.pvsm.ru

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