Mysql Телеграмм бот с файла

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

Бота я реализовал с помощью фреймворка telegraf.js для node.js. Бот называется UKRentBot доступен для всех желающих. Исходный код находится на GitHub по ссылке https://github.com/VeXell/UKRentHomeHunter. В этой статье я хотел бы рассказать как создавался этот бот и как по аналогии можно создавать других ботов.

Telegram предоставляет прекрасное api которое позволяет создавать ботов с разным функционалом. К этому api уже написано множество разных фреймфорков которые позволяют с ним взаимодействовать и упрощают работу. Я взял telegraf.js из-за того, что он один из самых популярных, имеет поддержку Typescript и постоянно обновляется под новое api Telegram. В качестве базы данных я решил попробовать использовать Google Firebase Database которая отлично подходит для создания MVP проектов или небольших приложений как у меня. Она доступна из коробки и не требует какой-то установки на собственный сервер.

Telegram бот на PHP за 10 минут

Прежде всего, перед созданием бота, необходимо обратится к BotFather боту https://t.me/botfather который отвечает за создание новых ботов. После заполнения минимального количества полей вам будет доступен api ключ для выполнения запросов к Telegram api.

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

import ‘./env’; import from ‘telegraf’; import TelegrafI18n from ‘telegraf-i18n’; import from ‘types’; // Read ENV variables import from ‘config’; import enLocale from ‘./locales/en’; import ruLocale from ‘./locales/ru’; import from ‘actions’; import from ‘wizards’; import from ‘jobs’; import from ‘services/db’; initDatabase(FIREBASE_AUTH, DATABASE); const i18n = new TelegrafI18n(< defaultLanguage: ‘en’, allowMissing: true, useSession: true, defaultLanguageOnMissing: true, >); i18n.loadLocale(‘en’, enLocale); i18n.loadLocale(‘ru’, ruLocale); const bot = new Telegraf(BOT_TOKEN); bot.use(session()); bot.use(i18n.middleware()); initWizards(bot); initActions(bot); // Start bot bot.launch();

Telegram api поддерживает различные команды, действия и сцены которые можно реализовать как форму с шагами (визарды). Например, в функции initActions я сделал начальную инициализацию всех действий.

export function initActions(bot: Telegraf) < // Две обязательные команды для бота bot.start(actionStart); bot.help(actionHelp); // Быстрое меню bot.settings(async (ctx) =>< await ctx.setMyCommands([ < command: GLOBAL_ACTIONS.search, description: ctx.i18n.t(`actions.$`), >, < command: GLOBAL_ACTIONS.searches, description: ctx.i18n.t(`actions.$`), >, < command: GLOBAL_ACTIONS.share, description: ctx.i18n.t(`actions.$`), >, ]); >); bot.command(GLOBAL_ACTIONS.search, actionSearch); // Остальные команды описаны ниже // Кнопки можно делать указывая RegExp формат // Я использую такие действия для удаления заданного поиска bot.action(new RegExp(`$_(?.*)?$`), actionRemove); >

При команде /start я вывожу основную информацию по боту, а также основные действия с ним.

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

export default async function actionSearch(ctx: TelegrafContext) < const message = ctx.i18n.t(«wizardSearch.intro»); const chatId = ctx.from?.id; if (chatId) < // Сохраняем данные в БД updateChat(chatId, < firstName: ctx.from?.first_name || «», lastName: ctx.from?.last_name || «», username: ctx.from?.username || «», language: ctx.from?.language_code || «», >); try < const activeSearches = await getSearches(chatId); ctx.session.activeSearches = activeSearches; if ( activeSearches Object.keys(activeSearches).length >= MAX_SEARCHES ) < // Не больше 3 поисков за раз return ctx.replyWithMarkdown( ctx.i18n.t(«error.maxSearchesReached», < maxSearches: MAX_SEARCHES, >), Markup.inlineKeyboard([ Markup.button.callback(» My Searches», GLOBAL_ACTIONS.searches), ]) ); > else < await ctx.replyWithMarkdown(message, Markup.removeKeyboard()); // Входим в визард return ctx.scene.enter(SEARCH_WIZARD_TYPE); >> catch (error) < console.log(«error»); >> else < return ctx.replyWithMarkdown( ctx.i18n.t(«error.emptyChatId»), Markup.removeKeyboard() ); >>

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

Еще по теме:  Как написать Телеграмм бот на python с меню

export function initWizards(bot: Telegraf) < // Инициализация сцен const stage = new Scenes.Stage([searchWizard]); // Глобальная команда для отменя визарда поиска stage.action(ACTIONS.CANCEL, (ctx) => < ctx.reply(ctx.i18n.t(«operationCanceled»)); return ctx.scene.leave(); >); stage.command(ACTIONS.CANCEL, (ctx) => < ctx.reply(ctx.i18n.t(«operationCanceled»)); return ctx.scene.leave(); >); bot.use(stage.middleware()); >

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

export default new Scenes.WizardScene( WIZARD_TYPE, async (ctx) => < const chatId = ctx.chat?.id; ctx.scene.session.search = < chatId, >; await ctx.replyWithMarkdown( ctx.i18n.t(«wizardSearch.actions.location») ); return ctx.wizard.next(); >, processLocation, // Other actions. );

В функции processLocation ниже как раз и происходит обработка ввода. Если все прошло успешно, то необходимо вызывать следующую сцену с помощью метода wizard.next() .

export default async function processLocation(ctx: TelegrafContext) < try < if ( !ctx.message || !(«text» in ctx.message) || ctx.message.text.length try < const location = await detectLocation(ctx.message.text); ctx.scene.session.search.area = location.locationName; ctx.scene.session.search.searchAreaId = location.locationId; >catch (error) <> if (!ctx.scene.session.search.area) < throw new NoLocationFoundError( ctx.i18n.t(«wizardSearch.errors.locationNotFound») ); >let locationAlreadyInSearch = false; if (ctx.session.activeSearches) < const searches = ctx.session.activeSearches; Object.keys(searches).forEach((key) => < const searchObject = searches[key]; if ( searchObject.searchAreaId === ctx.scene.session.search.searchAreaId ) < locationAlreadyInSearch = true; >>); > if (locationAlreadyInSearch) < throw new LocationAlreadyInSearchError( ctx.i18n.t(«wizardSearch.errors.locationAlreadyInSearch», < location: ctx.scene.session.search.area, >) ); > // После все валидации данных переходим на след шаг. await askForDistance(ctx); return ctx.wizard.next(); > catch (error) < return cancelSearchReply(ctx, error.message); >>

Ниже показан результат визарда бота. Пользователь в любой момент может отменить поиск с помощью команды /cancel

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

export function saveSearch( searchRequest: ISearchRequestInput ): Promise < const searchesListRef = getDB().ref(`$/$`); const searchRef = searchesListRef.push(); return searchRef.set(< . searchRequest, . < createdAt: moment.utc().format(), expiredAt: moment.utc().add(30, «days»).format(), lastSearchAt: null, >, >); > export async function getSearches( chatId: number ): Promise < const searchesList = await getDB().ref(`$/$`).get(); if (searchesList.exists()) < return searchesList.toJSON() as ISearchRecords; >return null; > export async function removeSearch( chatId: number, index: string ): Promise < await getDB().ref(`$/$/$`).remove(); return true; > type IUpdateSearchRecord = Partial; export function updateSearch( chatId: number, index: string, search: IUpdateSearchRecord ) < return getDB().ref(`$/$/$`).update(search); >

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

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

Очень здорово, что Firebase позволяет подписываться на изменение структуры вместо постоянных опросов БД. Делается достаточно просто. Теперь как только изменятся данные по указанному пути, они автоматически загрузятся в бота.

function getAllSearchesRef() < return getDB().ref(`$`); > let searches: ISearchEntries | null = null; getAllSearchesRef().on(«value», (snapshot) => < if (snapshot.exists()) < searches = snapshot.val(); >>);

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

function formatTgMessage( area: string, searchResult: ISearchResult ): < media: < type: «photo»; media: string; caption?: string >[]; text: string; > < const images = Array.isArray(searchResult.images) ? searchResult.images : []; return < media: images.map((imageUrl) =>< return < type: «photo», media: imageUrl, >; >), text: ` $ / *$* Available from *$* *$* Search in $`, >; > const message = formatTgMessage(area, searchResult); const media = message.media.slice(0, 10); let submitted = false; try < if (media.length) < await telegramBot.telegram.sendMediaGroup(chatId, media); >await telegramBot.telegram.sendMessage(chatId, message.text, < parse_mode: «Markdown», reply_markup: < inline_keyboard: [[Markup.button.url(«↗️ Open», searchResult.openUrl)]], >, >); submitted = true; > catch (error) < if (error.response?.error_code === 400) < // Чат не найден >if (error.response?.error_code === 403) < // Чат был заблокирован. Удаляем поиск await removeSearch(chatId, searchId); await removeSearchResults(chatId, searchId); >break; >

Еще по теме:  Varg pro отзывы Телеграм канал

Результат работы бота можно посмотреть на изображении снизу

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

Как я писал выше — исходный код бота доступен по ссылке https://github.com/VeXell/UKRentHomeHunter и вы можете использовать мой пример для написания своих ботов. Если вам понравился мой бот — поставьте мне звезду на GitHub.

О Блоге

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

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

Telemonitor — объединяем Telegram и 1С

Не так давно Telegram предоставил API для создания ботов. Telemonitor — программа, позволяющая легко настроить собственного бота для работы с 1С.

Что это такое?

Telegram набирает всё большую популярность. Недавно сервис предоставил платформу для создания ботов. Telemonitor — это прослойка между API Telegram и 1С/OneScript, позволяющая легко настроить функционал собственного бота. Кто-то задастся вопросом, а зачем вообще нужна какая-то дополнительная программа, ведь все можно организовать и в 1С. Конечно можно, но, на мой взгляд, это не всегда удобно. Во-первых, более или менее удобный функционал есть только в версии 8.3. Во-вторых, надо постоянно держать запущенным сеанс. Telemonitor, конечно, тоже имеет свои недостатки, но работать с ним, думаю будет удобнее.

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

Схема работы Telegram и Telemonitor 1С

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

Как настроить своего бота?

Настройка Telegram и Telemonitor 1С

Как зарегистрировать бота рассказывать, думаю, смысла нет — в интернете полно примеров, И так, открываем каталог Telemonitor и видим файл settings.ini. В нем необходимо задать token для бота, полученный при регистрации. При желании можно изменить интервал опроса бота и параметры соединения. Теперь рассмотрим папку databases, в ней будем описывать базы и команды.

Для каждой базы данных, в которой будем использовать бота создаем папку с произвольным названием латиницей. Для примера я использую базы FileAccounting82 и ServerTrade83. В каждой папке необходимо разместить файл database.ini, в котором указывается строка соединения с базой (сейчас в меня полетят тухлые помидоры, но да, пароль хранится в чистом виде) и используемая версия 1С. Кстати, 8.1 не поддерживается. Кодировка у ini файла должна быть Windows-1251.

Команды Telegram и Telemonitor 1С

Теперь настало время описать команды. В той же папке создаем файлы *.tcm. Каждый такой файл — это просто текст в кодировке UTF-8, содержащий описание команды и код, выполняемый в 1С. Первой строкой идет описание, далее — исполняемый код.

Если мы хотим увидеть какой-либо отклик от бота, тогда необходимо заполнить переменную Результат . В данном примере бот вернет описание пользователей, работающих в базе или скажет: «Нет активных пользователей». При создании своих команд помните, что весь код помещается в конструкцию Выполнить() , поэтому он имеет некоторые ограничения, думаю сами догадываетесь какие. Чтобы бот вернул файл, например, вы хотите получать какой-нибудь отчет или прайс, то в коде команды необходимо заполнить переменную Результат_Файл .

Что получилось в итоге?

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

Имя каждой команды складывается из имени базы данных и имени файла tcm. Запросим у бота список команд. И так, бот, /start !
Список команд бота Telegram
Ух ты! Работает! Давай-ка, бот, нам список активных пользователей.
Выполнение команд ботом Telegram
Эх, не было печали, а теперь вот каждое утро общаюсь с ботом и смотрю, все ли с базами в порядке

Что дальше?

Программу, она кстати использует NET Framework 4.0, писал для собственных нужд, но, если кому пригодится, буду очень рад. Буду рад предложениям по улучшению и расширению функционала.

Еще по теме:  Как убрать чат из архива в Телеграмме на Айфоне

Последние изменения:

Команды в виде кнопок доп.клавиатуры

  • 12.08.2015
    Добавил команду /screen для получения скриншота.
    Добавил возможность отправки файлов.
  • 23.10.2015
    В команду теперь можно передавать параметры. В 1С все параметры будут доступны в реквизите «ПараметрыКоманды» через запятую
    В settings.ini добавил параметр [SafeMode1C] для запуска кода в небезопасном режиме.
  • 07.10.2015
    Добавил возможность выводить команды в виде кнопок клавиатуры. Такие команды описываются отдельным файлом, но расширение у него должно быть *.tcm_b вместо *.tcm. Параметры кнопок задаются в секции [Buttons] ini-файла.
  • 17.03.2016
    Добавил ограничение доступа по имени пользователя Telegram (username). Ограничения можно задать как на бота целиком, так и на базу данных. Для этого в файлах settings.ini и database.ini есть секция [WhiteList] и параметр Users. Именя пользователей, которым разрешен доступ, следует указывать через запятую. В этой же секции файла settings.ini можно ограничить доступ пользователям к получению скриншотов. Имя параметра, отвечающего за данное ограничение — ScreenOwners
  • 15.04.2016
    Добавил поддержку команд с запросом параметров. Для того, чтобы бот запросил параметр, необходимо в коде команды использовать переменную ДиалогСПараметрами .
    Ниже представлен пример команды с запросом трех параметров

// Подключение к базе данных МассивПараметров = Новый Массив(); Подстроки = СтрЗаменить(ПараметрыКоманды, «,», Символы.ПС); Для Сч = 1 По СтрЧислоСтрок(Подстроки) Цикл Параметр = СокрЛП(СтрПолучитьСтроку(Подстроки, Сч)); Если ЗначениеЗаполнено(Параметр) Тогда МассивПараметров.Добавить(Параметр); КонецЕсли; КонецЦикла; Если МассивПараметров.Количество() < 3 Тогда ДиалогСПараметрами = Истина; Заголовки = Новый Соответствие(); Заголовки[0] = «Введите первый параметр:»; Заголовки[1] = «Отлично! Теперь укажите второй:»; Заголовки[2] = «Почти готово! Третий параметр и заканчиваем:»; Результат = Заголовки[МассивПараметров.Количество()]; Иначе // Здесь выполнение какого-то кода. Результат = «Команда выполнена со следующими параметрами:» + Символы.ПС; Результат = Результат + «1) » + МассивПараметров[0] + Символы.ПС; Результат = Результат + «2) » + МассивПараметров[1] + Символы.ПС; Результат = Результат + «3) » + МассивПараметров[2]; КонецЕсли;

Ну и результат работы Команда с запросом параметровКоманда с запросом параметровПри написании таких команд надо понимать, что Telemonitor не поддерживает COM-соединение между запросами параметров у пользователя. При передаче каждого параметра создается новое соединение и в код каманды передаются все полученные параметры, поэтому в описании команды нет смысла инициализировать какие-либо переменные и выполнять действия, в надежде, что они будут доступны при передаче следующего параметра.
Также, теперь в коде команды есть доступ к имени пользователя Telegram, и полному идентификатору команды. Для этого используются переменные username , first_name , last_name и command

  • 22.11.2016
    Добавлена поддержка OneScript(1Script). Для тех, кто не в курсе, что это такое вот ссылка и вот. Скрипты необходимо размещать в папке scripts c расширением *.os. Примеры скриптов есть в архиве с программой. Команды для OneScript имеют некоторые особенности, но не сильно отличаются от таковых для 1С. Все пробелы в параметрах, переданных в команду заменяются на знак подчеркивания «_».
  • 06.04.2018
    Команды для OScript можно делать в виде кнопок. Для этого файл команды должен быть с расширением *.os_b
  • 18.04.2018
    Добавлена поддержка SOCKS5. В settings.ini секция [Proxy], параметр Type
  • Описание settins.ini

    [Main] — основные настройки

    BotToken — токен бота, для которого настраивается Telemonitor
    Interval — интервал опроса бота на наличие новых команд для выполнения (сек)

    [Proxy] — подключение через прокси-сервер

    UseProxy (0/1) — Использовать прокси для соединения с сервером telegram
    Server — Адрес прокси
    Port — Порт прокси
    Username — Имя пользователя
    Password — Пароль
    Type — (0 — HTTP, 1 — SOCKS5) — тип прокси

    [Debug] — отладка (логгирование)

    Enabled (0/1) — включение режима отладки для записи расширенной информации в telemonitor.log

    [SafeMode1C] — безопасный режим

    Enabled (0/1) — запуск кода 1С в безопасном режиме

    [Buttons] — дополнительная клавиатура Telegram

    ShowStartButton (0/1) — показывать кнопку для запроса списка команд
    HideButtonsAfterMessage (0/1) — скрывать кнопки доп.клавиатуры после получения сообщения
    NumRowsOfButtons — количество кнопок доп.клавиатуры в одном ряду
    UsePictures (0/1) — показывать пиктограммы на кнопках доп.клавиатуры

    [WhiteList] — ограничение доступа к боту

    Users — именя пользователей Telegram (username), которым разрешен доступ
    ScreenOwners- именя пользователей, которым разрешено получить скриншоты
    [/stextbox]

    P.S. Писал быстро, поэтому возможны какие-нибудь ошибки. Буду благодарен, если вы сообщите о таковых.

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

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