Qorista bot telegram ee R (qaybta 4): Dhisida wada hadal macquul ah oo joogto ah oo lala yeesho bot-ka
Haddii aad hore u akhriday saddex qodob Taxanahan, ka dib waxaad horay u taqaanay sida loo qoro bots telegram oo buuxa oo leh kiiboodhka.
Maqaalkan, waxaan ku baran doonaa sida loo qoro bot kaas oo ilaalin doona wadahadal joogto ah. Kuwaas. Botku wuxuu ku weydiin doonaa su'aalo wuxuuna ku sugi doonaa inaad geliso macluumaad. Iyada oo ku xidhan xogta aad geliso, bot-ku waxa uu samayn doonaa talaabooyinka qaarkood.
Sidoo kale maqaalkan waxaan ku baran doonaa sida loo isticmaalo database hoostiisa bot, tusaale ahaan waxay noqon doontaa SQLite, laakiin waxaad isticmaali kartaa DBMS kasta oo kale. Waxaan si faahfaahsan u qoray wax ku saabsan la falgalka xogta macluumaadka ee luqadda R gudaha maqaalkani.
Dhammaan maqaallada taxanaha ah "Qoritaanka bot telegram ee R"
Haddii aad xiisaynayso falanqaynta xogta, waxaa laga yaabaa inaad xiisaynayso aniga telegram и youtube kanaalada. Inta badan waxa ku jira waxa u heellan luqadda R.
Si bot-ku uu xogta kaaga codsado oo uu kuugu sugo inaad geliso macluumaad kasta, waxaad u baahan doontaa inaad diiwaangeliso xaaladda wada hadalka hadda. Sida ugu fiican ee tan loo sameeyo waa in la isticmaalo nooc ka mid ah xog-ururinta, sida SQLite.
Kuwaas. Caqligu wuxuu noqonayaa sidan soo socota. Waxaan u yeernaa habka bot-ka, bot-kuna wuxuu si isdaba-joog ah nooga codsadaa xoogaa macluumaad ah, tallaabo kastana waxay sugaysaa in macluumaadkan la galo oo uu hubiyo.
Waxaan qori doonaa bot-ka ugu fudud ee suurtogalka ah, marka hore waxay ku weydiin doontaa magacaaga, ka dibna da'daada, waxayna ku kaydin doontaa xogta la helay kaydka. Marka la waydiiyo da'da, waxay hubin doontaa in xogta la galiyay ay tahay lambar oo aanay ahayn qoraal.
Waxaan qornaa hababka bot, i.e. hawlaha ay qaban doonto.
Ku darida filtarrada fariimaha Iyada oo la kaashanayo kaas oo bot-ku uu heli doono hababka lagama maarmaanka ah, taas oo ku xidhan xaaladda hadda jirta ee sheekada.
Habaynta waxaan ku qornaa bot token iyo dariiqa loo maro xogta, i.e. faylka bot.db; waxaanu abuuri doonaa faylka laftiisa talaabada xigta.
Bots-ka adag, waxaad abuuri kartaa qaabab badan oo adag, ka sokow, muhiim maaha in la qoro ini config, waxaad isticmaali kartaa qaab kasta oo kale oo ay ku jiraan JSON.
Samee doorsoome deegaan
Kumbuyuutar kasta, galka mashruuca bot wuxuu ku yaalaa hageyaal kala duwan iyo darawalo kala duwan, markaa koodhka dariiqa loo maro galka mashruuca waxaa lagu dejin doonaa doorsoomiyaha deegaanka. TG_BOT_PATH.
Waxaa jira dhowr siyaabood oo loo abuuro doorsoome deegaan, tan ugu fudud waa in lagu qoro fayl .Renviron.
Waxaad samayn kartaa ama wax ka beddeli kartaa faylkan adoo isticmaalaya amarka file.edit(path.expand(file.path("~", ".Renviron"))). Fulin oo ku dar hal sadar faylka:
TG_BOT_PATH=C:/ПУТЬ/К/ВАШЕМУ/ПРОЕКТУ
Marka xigta kaydi faylka .Renviron oo dib u bilow RStudio.
Abuuritaanka xog ururin
Tallaabada xigta waa in la abuuro database. Waxaan u baahan doonaa 2 miis:
chat_data - xogta uu botku ka codsaday isticmaalaha
chat_state - xaalada hada ee dhamaan wada sheekaysiga
Waxaad samayn kartaa jaantusyadan adigoo isticmaalaya weydiinta SQL ee soo socota:
CREATE TABLE chat_data (
chat_id BIGINT PRIMARY KEY
UNIQUE,
name TEXT,
age INTEGER
);
CREATE TABLE chat_state (
chat_id BIGINT PRIMARY KEY
UNIQUE,
state TEXT
);
Haddii aad ka soo dejisay mashruuca bot GitHub, ka dib si aad u abuurto database-ka waxaad isticmaali kartaa code soo socda ee R.
# Скрипт создания базы данных
library(DBI) # интерфейс для работы с СУБД
library(configr) # чтение конфига
library(readr) # чтение текстовых SQL файлов
library(RSQLite) # драйвер для подключения к SQLite
# директория проекта
setwd(Sys.getenv('TG_BOT_PATH'))
# чтение конфига
cfg <- read.config('config.cfg')
# подключение к SQLite
con <- dbConnect(SQLite(), cfg$db_settings$db_path)
# Создание таблиц в базе
dbExecute(con, statement = read_file('create_db_data.sql'))
dbExecute(con, statement = read_file('create_db_state.sql'))
Shaqooyinka qorista si ay ula shaqeeyaan kaydka xogta
Waxaan horey u haysanay faylka qaabeynta oo diyaar ah iyo xog ururin la sameeyay. Hadda waxaad u baahan tahay inaad qorto hawlaha si aad u akhrido oo aad u qorto xogta xogtan.
Haddii aad ka soo dejisay mashruuca GitHub, markaa waxaad ka heli kartaa hawlaha faylka db_bot_function.R.
Koodhka shaqada ee la shaqaynta xogta macluumaadka
# ###########################################################
# Function for work bot with database
# получить текущее состояние чата
get_state <- function(chat_id) {
con <- dbConnect(SQLite(), cfg$db_settings$db_path)
chat_state <- dbGetQuery(con, str_interp("SELECT state FROM chat_state WHERE chat_id == ${chat_id}"))$state
return(unlist(chat_state))
dbDisconnect(con)
}
# установить текущее состояние чата
set_state <- function(chat_id, state) {
con <- dbConnect(SQLite(), cfg$db_settings$db_path)
# upsert состояние чата
dbExecute(con,
str_interp("
INSERT INTO chat_state (chat_id, state)
VALUES(${chat_id}, '${state}')
ON CONFLICT(chat_id)
DO UPDATE SET state='${state}';
")
)
dbDisconnect(con)
}
# запись полученных данных в базу
set_chat_data <- function(chat_id, field, value) {
con <- dbConnect(SQLite(), cfg$db_settings$db_path)
# upsert состояние чата
dbExecute(con,
str_interp("
INSERT INTO chat_data (chat_id, ${field})
VALUES(${chat_id}, '${value}')
ON CONFLICT(chat_id)
DO UPDATE SET ${field}='${value}';
")
)
dbDisconnect(con)
}
# read chat data
get_chat_data <- function(chat_id, field) {
con <- dbConnect(SQLite(), cfg$db_settings$db_path)
# upsert состояние чата
data <- dbGetQuery(con,
str_interp("
SELECT ${field}
FROM chat_data
WHERE chat_id = ${chat_id};
")
)
dbDisconnect(con)
return(data[[field]])
}
Waxaan abuurnay 4 hawlood oo fudud:
get_state() - ka hel xaaladda wada sheekaysiga hadda ee kaydka
set_state() - u qor xaaladda sheekeysiga hadda jirta keydka macluumaadka
get_chat_data() - Hel xogta uu soo diray isticmaaluhu
set_chat_data() - xogta diiwaanka laga helay isticmaalaha
Dhammaan hawluhu aad bay u fudud yihiin, ama waxay akhriyaan xogta kaydka iyagoo isticmaalaya amarka dbGetQuery(), ama ballan UPSERT hawlgalka (beddelka xogta hadda jirta ama qorista xog cusub database), iyadoo la isticmaalayo shaqada dbExecute().
Erayga hawlgalka UPSERT waa sida soo socota:
INSERT INTO chat_data (chat_id, ${field})
VALUES(${chat_id}, '${value}')
ON CONFLICT(chat_id)
DO UPDATE SET ${field}='${value}';
Kuwaas. garoonka miisaska chat_id waxay leedahay caqabad gaar ah waana furaha shaxanka. Ugu horreyntii, waxaan isku dayeynaa inaan ku darno macluumaadka miiska, waxaana helnaa qalad haddii xogta sheekada hadda jirta ay horeyba u jirtay, taas oo aan si fudud u cusbooneysiineyno macluumaadka sheekadan.
Marka xigta, waxaan u isticmaali doonaa shaqooyinkan hababka bot iyo filtarrada.
Hababka bot
Talaabada xigta ee dhisitaanka botkeena waa in la abuuro habab. Haddii aad ka soo dejisay mashruuca GitHub, ka dibna dhammaan hababka ayaa ku jira faylka hababka bot.R.
Bot habka code
# ###########################################################
# bot methods
# start dialog
start <- function(bot, update) {
#
# Send query
bot$sendMessage(update$message$chat_id,
text = "Введи своё имя")
# переключаем состояние диалога в режим ожидания ввода имени
set_state(chat_id = update$message$chat_id, state = 'wait_name')
}
# get current chat state
state <- function(bot, update) {
chat_state <- get_state(update$message$chat_id)
# Send state
bot$sendMessage(update$message$chat_id,
text = unlist(chat_state))
}
# reset dialog state
reset <- function(bot, update) {
set_state(chat_id = update$message$chat_id, state = 'start')
}
# enter username
enter_name <- function(bot, update) {
uname <- update$message$text
# Send message with name
bot$sendMessage(update$message$chat_id,
text = paste0(uname, ", приятно познакомится, я бот!"))
# Записываем имя в глобальную переменную
#username <<- uname
set_chat_data(update$message$chat_id, 'name', uname)
# Справшиваем возраст
bot$sendMessage(update$message$chat_id,
text = "Сколько тебе лет?")
# Меняем состояние на ожидание ввода имени
set_state(chat_id = update$message$chat_id, state = 'wait_age')
}
# enter user age
enter_age <- function(bot, update) {
uage <- as.numeric(update$message$text)
# проверяем было введено число или нет
if ( is.na(uage) ) {
# если введено не число то переспрашиваем возраст
bot$sendMessage(update$message$chat_id,
text = "Ты ввёл некорректные данные, введи число")
} else {
# если введено число сообщаем что возраст принят
bot$sendMessage(update$message$chat_id,
text = "ОК, возраст принят")
# записываем глобальную переменную с возрастом
#userage <<- uage
set_chat_data(update$message$chat_id, 'age', uage)
# сообщаем какие данные были собраны
username <- get_chat_data(update$message$chat_id, 'name')
userage <- get_chat_data(update$message$chat_id, 'age')
bot$sendMessage(update$message$chat_id,
text = paste0("Тебя зовут ", username, " и тебе ", userage, " лет. Будем знакомы"))
# возвращаем диалог в исходное состояние
set_state(chat_id = update$message$chat_id, state = 'start')
}
}
Waxaan abuurnay 5 hab:
bilow - Bilow wada hadal
state - Hel xaaladda wada sheekaysiga hadda
dib u dejin - Dib u deji xaaladda sheekaysiga hadda
enter_name - Botku wuxuu ku weydiinayaa magacaaga
enter_age - Botku wuxuu ku weydiinayaa da'daada
Habka start ku weydiiyo magacaaga, oo u beddelaa xaaladda wada sheekaysiga sug_name, i.e. inaad u diyaar garowdo gelida magacaaga.
Marka xigta, waxaad soo dirtaa magaca waxaana lagu farsameeyaa habka enter_name, bot-ku wuu ku salaamayaa, wuxuu ku qorayaa magaca la helay kaydka xogta, oo wuxuu u beddelayaa sheekeysiga gobolka da'da sugitaanka.
Marxaladdan, bot-ku wuxuu kaa filayaa inaad gasho da'daada. Waxaad soo dirtaa da'daada, bot-ku wuxuu hubiyaa fariinta, haddii aad dirto xoogaa qoraal ah halkii lambar, waxay odhan doontaa: Ты ввёл некорректные данные, введи число, oo waxay ku sugi doontaa inaad dib u geliso xogtaada. Haddii aad dirto nambar, bot-ku wuxuu ka warbixin doonaa inuu aqbalay da'daada, ku qor xogta la helay kaydka, ka warbixi dhammaan xogta lagaa helay oo ku soo celiso xaaladda sheekeysiga meeshiisii asalka ahayd, i.e. V start.
Adigoo wacaya habka state waxaad codsan kartaa xaalada wada sheekaysiga ee wakhti kasta, iyo adigoo isticmaalaya reset ku soo celi sheekadii sidii ay ahayd.
filtarrada fariimaha
Xaaladeena, tani waa mid ka mid ah qaybaha ugu muhiimsan ee dhismaha bot. Waa iyadoo la kaashanayo filtarrada fariinta in botku uu fahmi doono macluumaadka uu kaa filayo iyo sida loo habayn doono.
In mashruuca on GitHub filtarrada ayaa ka diiwaan gashan faylka filtarrada fariinta.R.
Koodhka filter fariinta:
# ###########################################################
# message state filters
# фильтр сообщений в состоянии ожидания имени
MessageFilters$wait_name <- BaseFilter(function(message) {
get_state( message$chat_id ) == "wait_name"
}
)
# фильтр сообщений в состоянии ожидания возраста
MessageFilters$wait_age <- BaseFilter(function(message) {
get_state( message$chat_id ) == "wait_age"
}
)
Shaandhooyinka waxaanu isticmaalnaa hawshii hore loo qoray get_state(), si aad u codsato xaalada sheekeysiga hadda. Shaqadani waxay u baahan tahay 1 dood oo keliya, id chat
Shaandhaynta xigta sug_name socodsiinta fariimaha marka sheekadu xaalad ku jirto wait_name, iyo si waafaqsan shaandhada da'da sugitaanka socodsiinta fariimaha marka sheekadu xaalad ku jirto wait_age.
Gacan-qaadayaasha
Faylka leh maamulayaasha ayaa la yiraahdaa maamulayaasha.R, wuxuuna leeyahay koodka soo socda:
# ###########################################################
# handlers
# command handlers
start_h <- CommandHandler('start', start)
state_h <- CommandHandler('state', state)
reset_h <- CommandHandler('reset', reset)
# message handlers
## !MessageFilters$command - означает что команды данные обработчики не обрабатывают,
## только текстовые сообщения
wait_age_h <- MessageHandler(enter_age, MessageFilters$wait_age & !MessageFilters$command)
wait_name_h <- MessageHandler(enter_name, MessageFilters$wait_name & !MessageFilters$command)
Marka hore waxaanu abuurnaa maamulayaasha amarka kuwaas oo kuu ogolaanaya inaad socodsiiso hababka aad ku bilaabi lahayd wada hadal, dib u dejintiisa, oo aad waydiiso xaaladda hadda jirta.
Marka xigta, waxaan abuurnaa 2 maareeyaha fariinta anagoo adeegsanayna filtarrada lagu sameeyay tallaabadii hore, waxaana ku darnaa shaandhooyin !MessageFilters$command, si aan u isticmaali karno amarrada xaalad kasta oo lagu sheekeysto.
Bot furitaanka code
Hadda waxaan haysanaa wax kasta oo diyaar u ah in la bilaabo, koodhka ugu muhiimsan ee bilaabista bot ayaa ku jira faylka bot.R.
library(telegram.bot)
library(tidyverse)
library(RSQLite)
library(DBI)
library(configr)
# переходим в папку проекта
setwd(Sys.getenv('TG_BOT_PATH'))
# читаем конфиг
cfg <- read.config('config.cfg')
# создаём экземпляр бота
updater <- Updater(cfg$bot_settings$bot_token)
# Загрузка компонентов бота
source('db_bot_function.R') # функции для работы с БД
source('bot_methods.R') # методы бота
source('message_filters.R') # фильтры сообщений
source('handlers.R') # обработчики сообщений
# Добавляем обработчики в диспетчер
updater <- updater +
start_h +
wait_age_h +
wait_name_h +
state_h +
reset_h
# Запускаем бота
updater$start_polling()
Natiijo ahaan, waxaan helnay bot-kan:
Waqti kasta adoo isticmaalaya amarka /state Waxaan waydiin karnaa xaaladda wada sheekaysiga ee hadda, iyo adeegsiga amarka /reset ku soo celi sheekadii sidii ay ahayd oo dib u bilow wadahadalka.
gunaanad
Maqaalkan, waxaan ku ogaanay sida loo isticmaalo xogta gudaha bot, iyo sida loo dhiso wada-hadallo macquul ah oo isdaba-joog ah iyadoo la duubayo xaaladda sheekada.
Xaaladdan oo kale, waxaan eegnay tusaalaha ugu horreeya, si ay kuugu fududaato inaad fahamto fikradda dhisidda bots-yadaas; ficil ahaan, waxaad dhisi kartaa wada-hadallo aad u adag.
Maqaalka xiga ee taxanahan, waxaan ku baran doonaa sida loo xaddido xuquuqda isticmaalayaasha bot si ay u adeegsadaan habab kala duwan.