ProHoster > Блог > Gudanarwa > Rubuta bot na telegram a cikin R (sashe na 4): Gina daidaito, tattaunawa mai ma'ana tare da bot
Rubuta bot na telegram a cikin R (sashe na 4): Gina daidaito, tattaunawa mai ma'ana tare da bot
Idan kun riga kun karanta baya labarai guda uku daga wannan silsilar, to kun riga kun san yadda ake rubuta cikakkun bots ɗin telegram tare da madannai.
A cikin wannan labarin, za mu koyi yadda ake rubuta bot wanda zai kiyaye daidaitaccen tattaunawa. Wadancan. Bot ɗin zai yi muku tambayoyi kuma ya jira ku don shigar da wasu bayanai. Dangane da bayanan da kuka shigar, bot ɗin zai yi wasu ayyuka.
Har ila yau, a cikin wannan labarin, za mu koyi yadda ake amfani da bayanai a ƙarƙashin murfin bot, a cikin misalinmu zai zama SQLite, amma kuna iya amfani da kowane DBMS. Na rubuta dalla-dalla game da hulɗa tare da bayanan bayanai a cikin harshen R a cikin wannan labarin.
Domin bot ɗin ya nemi bayanai daga gare ku kuma ya jira ku don shigar da kowane bayani, kuna buƙatar yin rikodin yanayin tattaunawar yanzu. Hanya mafi kyau don yin wannan ita ce amfani da wasu nau'ikan bayanan da aka haɗa, kamar SQLite.
Wadancan. Hankalin zai kasance kamar haka. Muna kiran hanyar bot, kuma bot ɗin yana buƙatar wasu bayanai a jere daga gare mu, kuma a kowane mataki yana jira don shigar da wannan bayanin kuma yana iya duba shi.
Za mu rubuta bot mafi sauƙi mai sauƙi, da farko zai nemi sunan ku, sannan shekarun ku, kuma zai adana bayanan da aka karɓa zuwa ma'ajin bayanai. Lokacin neman shekaru, zai duba cewa bayanan da aka shigar lamba ne ba rubutu ba.
Irin wannan tattaunawa mai sauƙi za ta kasance tana da jihohi uku ne kawai:
farawa shine yanayin al'ada na bot, wanda baya tsammanin wani bayani daga gare ku
wait_name - yanayin da bot ɗin ke jira don shigar da suna
wait_age shine yanayin da bot ke jira don shigar da shekarun ku, adadin cikakkun shekaru.
Tsarin ginin Bot
A yayin labarin, za mu gina bot mataki-mataki; za a iya kwatanta tsarin gaba ɗaya kamar haka:
Mun ƙirƙiri saitin bot wanda a ciki za mu adana wasu saitunan. A cikin yanayinmu, alamar bot, da kuma hanyar zuwa fayil ɗin bayanai.
Muna ƙirƙirar canjin yanayi inda za a adana hanyar zuwa aikin tare da bot.
Muna ƙirƙirar bayanan da kanta, da ayyuka da yawa don bot ɗin zai iya hulɗa da shi.
Muna rubuta hanyoyin bot, watau. ayyukan da zai yi.
Ƙara matatun saƙo. Tare da taimakon abin da bot zai sami dama ga hanyoyin da ake bukata, dangane da halin yanzu na hira.
Muna ƙara masu sarrafawa waɗanda za su haɗa umarni da saƙonni tare da hanyoyin bot masu dacewa.
Bari mu kaddamar da bot.
Bot tsarin aikin
Don saukakawa, za mu raba lambar bot ɗin mu, da sauran fayiloli masu alaƙa, cikin tsari mai zuwa.
bot.R - babban lambar mu bot
db_bot_aikin.R - toshe na lamba tare da ayyuka don aiki tare da bayanan bayanai
hanyoyin_bot.R - lambar hanyoyin bot
saƙon_filters.R - tace sakon
masu rikewa.R - masu sarrafa
saita.cfg - bot config
ƙirƙirar_db_data.sql - Rubutun SQL don ƙirƙirar tebur tare da bayanan taɗi a cikin bayanan
ƙirƙirar_db_state.sql - Rubutun SQL don ƙirƙirar tebur na yanayin taɗi na yanzu a cikin bayanan
A cikin tsarin sai mu rubuta alamar bot da kuma hanyar zuwa bayanan bayanai, watau. zuwa fayil ɗin bot.db; za mu ƙirƙiri fayil ɗin kanta a mataki na gaba.
Don ƙarin hadaddun bots, za ku iya ƙirƙirar ƙarin hadaddun saiti, ban da, ba lallai ba ne a rubuta saitin inini, kuna iya amfani da kowane tsari ciki har da JSON.
Ƙirƙirar canjin yanayi
A kan kowane PC, babban fayil tare da aikin bot na iya kasancewa a cikin kundayen adireshi daban-daban da kuma a kan faifai daban-daban, don haka a cikin lambar za a saita hanyar zuwa babban fayil ɗin aikin ta hanyar canjin yanayi. TG_BOT_PATH.
Akwai hanyoyi da yawa don ƙirƙirar canjin yanayi, mafi sauƙi shine rubuta shi a cikin fayil .Renviron.
Kuna iya ƙirƙira ko shirya wannan fayil ta amfani da umarnin file.edit(path.expand(file.path("~", ".Renviron"))). Yi shi kuma ƙara layi ɗaya zuwa fayil ɗin:
Mataki na gaba shine ƙirƙirar rumbun adana bayanai. Za mu buƙaci tebur 2:
chat_data - bayanan da bot ya nema daga mai amfani
chat_state - halin yanzu na duk taɗi
Kuna iya ƙirƙirar waɗannan tebur ta amfani da tambayar SQL mai zuwa:
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
);
Idan kun zazzage aikin bot daga GitHub, to, don ƙirƙirar bayanan bayanan za ku iya amfani da lambar mai zuwa a cikin 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'))
Ayyukan rubutu don aiki tare da bayanan bayanai
Mun riga mun shirya fayil ɗin sanyi da ƙirƙira bayanan bayanai. Yanzu kuna buƙatar rubuta ayyuka don karantawa da rubuta bayanai zuwa wannan bayanan.
Idan kun sauke aikin daga GitHub, sannan zaku iya nemo ayyukan a cikin fayil ɗin db_bot_aikin.R.
Lambar aiki don aiki tare da bayanan bayanai
# ###########################################################
# 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]])
}
Mun ƙirƙiri ayyuka masu sauƙi guda 4:
get_state() - sami yanayin taɗi na yanzu daga bayanan bayanai
get_chat_data() - karɓar bayanan da mai amfani ya aiko
set_chat_data() - rikodin bayanan da aka karɓa daga mai amfani
Duk ayyuka suna da sauƙi, ko dai suna karanta bayanai daga rumbun adana bayanai ta amfani da umarnin dbGetQuery(), ko aikata UPSERT aiki (canza bayanan da ke gudana ko rubuta sabon bayanai zuwa bayanan bayanai), ta amfani da aikin dbExecute().
Ma'anar aikin UPSERT shine kamar haka:
INSERT INTO chat_data (chat_id, ${field})
VALUES(${chat_id}, '${value}')
ON CONFLICT(chat_id)
DO UPDATE SET ${field}='${value}';
Wadancan. a filin teburin mu chat_id yana da ƙuntatawa na musamman kuma shine maɓalli na farko na tebur. Da farko, muna ƙoƙarin ƙara bayanai a kan tebur, kuma muna samun kuskure idan bayanai don tattaunawar yanzu sun riga sun kasance, a cikin wannan yanayin kawai muna sabunta bayanan wannan taɗi.
Na gaba, za mu yi amfani da waɗannan ayyuka a cikin hanyoyin bot da tacewa.
Bot hanyoyin
Mataki na gaba na gina bot ɗin mu shine ƙirƙirar hanyoyin. Idan kun sauke aikin daga GitHub, to duk hanyoyin suna cikin fayil ɗin hanyoyin_bot.R.
Lambar hanyar Bot
# ###########################################################
# 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')
}
}
Mun kirkiro hanyoyi 5:
fara - Fara tattaunawa
state - Samu halin taɗi na yanzu
sake saiti - Sake saita yanayin taɗi na yanzu
enter_name - Bot yana neman sunan ku
enter_age - Bot yana tambayar shekarun ku
Hanyar start yana neman sunan ku, kuma ya canza yanayin taɗi zuwa jira_name, i.e. don jiran aiki don shigar da sunan ku.
Bayan haka, zaku aika sunan kuma ana sarrafa shi ta hanyar enter_name, Bot yana gaishe ku, ya rubuta sunan da aka karɓa a cikin ma'ajin bayanai, kuma ya canza taɗi zuwa jihar jira_shekara.
A wannan matakin, bot yana tsammanin ku shigar da shekarun ku. Kuna aika shekarun ku, bot ɗin yana duba saƙon, idan kun aika da wani rubutu maimakon lamba, zai ce: Ты ввёл некорректные данные, введи число, kuma zai jira ku don sake shigar da bayanan ku. Idan ka aika lamba, bot ɗin zai ba da rahoton cewa ya karɓi shekarunka, rubuta bayanan da aka karɓa zuwa ma’adanar bayanai, ya ba da rahoton duk bayanan da aka karɓa daga gare ka sannan ya mayar da yanayin taɗi zuwa matsayinsa na asali, watau. V start.
Ta hanyar kiran hanyar state za ku iya neman halin taɗi na yanzu a kowane lokaci, da amfani da reset mayar da hirar zuwa ga asali.
Tace saƙo
A cikin yanayinmu, wannan shine ɗayan mahimman sassa na gina bot. Tare da taimakon matattarar saƙon bot ɗin zai fahimci irin bayanin da yake tsammani daga gare ku da kuma yadda ya kamata a sarrafa shi.
A cikin aikin akan GitHub ana yin rijistar tacewa a cikin fayil ɗin saƙon_filters.R.
Lambar tace saƙo:
# ###########################################################
# 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"
}
)
A cikin tacewa muna amfani da aikin da aka rubuta a baya get_state(), domin neman halin da ake ciki a yanzu. Wannan aikin yana buƙatar hujja 1 kawai, id taɗi.
Tace gaba jira_name aiwatar da saƙonni lokacin da taɗi ke cikin yanayi wait_name, sannan tace jira_shekara aiwatar da saƙonni lokacin da taɗi ke cikin yanayi wait_age.
Masu kulawa
Ana kiran fayil ɗin tare da masu kulawa masu rikewa.R, kuma yana da code mai zuwa:
# ###########################################################
# 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)
Da farko mun ƙirƙiri masu sarrafa umarni waɗanda za su ba ku damar gudanar da hanyoyin don fara tattaunawa, sake saita shi, da kuma bincika yanayin halin yanzu.
Bayan haka, muna ƙirƙira masu sarrafa saƙo guda 2 ta amfani da masu tacewa da aka ƙirƙira a matakin da ya gabata, sannan mu ƙara masu tacewa !MessageFilters$command, domin mu iya amfani da umarni a kowace jiha ta taɗi.
Lambar ƙaddamar da Bot
Yanzu muna da komai a shirye don ƙaddamarwa, babban lambar don ƙaddamar da bot yana cikin fayil ɗin 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()
A sakamakon haka, mun sami wannan bot:
A kowane lokaci ta amfani da umarnin /state za mu iya tambayar yanayin taɗi na yanzu, da amfani da umarnin /reset mayar da hiran zuwa matsayinsa na asali sannan a sake fara tattaunawar.
ƙarshe
A cikin wannan labarin, mun gano yadda ake amfani da bayanan bayanai a cikin bot, da kuma yadda ake gina tattaunawa mai ma'ana ta hanyar yin rikodin yanayin taɗi.
A wannan yanayin, mun kalli mafi kyawun misali, ta yadda zai kasance da sauƙi a gare ku don fahimtar ra'ayin gina irin waɗannan bots; a aikace, kuna iya gina tattaunawa mai rikitarwa.
A cikin labarin na gaba a cikin wannan silsilar, za mu koyi yadda ake tauye haƙƙin masu amfani da bot don amfani da hanyoyi daban-daban.