د دې لپاره چې بوټ له تاسو څخه د معلوماتو غوښتنه وکړي او تاسو ته انتظار وکړئ چې کوم معلومات داخل کړئ، تاسو اړتیا لرئ د خبرو اترو اوسنی حالت ثبت کړئ. د دې کولو غوره لاره دا ده چې یو ډول ایمبیډ شوي ډیټابیس وکاروئ ، لکه SQLite.
هغوی. منطق به په لاندې ډول وي. موږ د بوټ میتود ته زنګ وهو، او بوټ په ترتیب سره زموږ څخه ځینې معلومات غوښتنه کوي، او په هر ګام کې دا د دې معلوماتو د ننوتلو انتظار کوي او کولی شي دا وګوري.
موږ به ترټولو ساده ممکن بوټ ولیکئ، لومړی به ستاسو نوم، بیا ستاسو عمر، او ترلاسه شوي معلومات به ډیټابیس ته خوندي کړي. کله چې د عمر غوښتنه وکړئ، دا به وګوري چې داخل شوي معلومات یو شمیر دی او متن نه دی.
دا ډول ساده خبرې اترې به یوازې درې حالتونه ولري:
پیل د بوټ عادي حالت دی، په کوم کې چې دا ستاسو څخه د کوم معلوماتو تمه نلري
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
);
که تاسو د بوټ پروژه له دې څخه ډاونلوډ کړې GitHub، بیا د ډیټابیس جوړولو لپاره تاسو کولی شئ لاندې کوډ په 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'))
د ډیټابیس سره کار کولو لپاره د لیکلو افعال
موږ دمخه د ترتیب کولو فایل چمتو کړی او یو ډیټابیس جوړ شوی. اوس تاسو دې ډیټابیس ته د معلوماتو لوستلو او لیکلو لپاره فنکشن لیکلو ته اړتیا لرئ.
که تاسو پروژه له دې څخه ډاونلوډ کړئ GitHub، بیا تاسو کولی شئ په فایل کې افعال ومومئ db_bot_function.R.
د ډیټابیس سره کار کولو لپاره د فعالیت کوډ
# ###########################################################
# 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]])
}
INSERT INTO chat_data (chat_id, ${field})
VALUES(${chat_id}, '${value}')
ON CONFLICT(chat_id)
DO UPDATE SET ${field}='${value}';
هغوی. زموږ د میزونو په ډګر کې chat_id د انفرادیت محدودیت لري او د جدولونو لومړنۍ کلیدي ده. په پیل کې، موږ هڅه کوو چې په میز کې معلومات اضافه کړو، او موږ یوه تېروتنه ترلاسه کوو که چیرې د اوسني چیٹ لپاره معلومات لا دمخه شتون ولري، په دې حالت کې موږ په ساده ډول د دې چیٹ لپاره معلومات تازه کوو.
بیا، موږ به دا دندې د بوټو میتودونو او فلټرونو کې وکاروو.
د بوټو میتودونه
زموږ د بوټ په جوړولو کې بل ګام د میتودونو رامینځته کول دي. که تاسو پروژه له دې څخه ډاونلوډ کړئ GitHub، بیا ټول میتودونه په فایل کې دي bot_methods.R.
د بوټ میتود کوډ
# ###########################################################
# 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')
}
}
موږ پنځه میتودونه جوړ کړل:
پیل - یو ډیالوګ پیل کړئ
حالت - د چیٹ اوسنی حالت ترلاسه کړئ
بیا تنظیم کول - د چیٹ اوسنی حالت بیا تنظیم کړئ
enter_name - بوټ ستاسو نوم غوښتنه کوي
enter_age - بوټ ستاسو د عمر غوښتنه کوي
میتود start ستاسو د نوم غوښتنه کوي، او د چیٹ حالت بدلوي انتظار_نوم, i.e. د خپل نوم د داخلولو لپاره ولاړ شئ.
بیا، تاسو نوم لیږئ او دا د میتود لخوا پروسس کیږي enter_name، بوټ تاسو ته ښه راغلاست وايي ، ترلاسه شوی نوم په ډیټابیس کې لیکي ، او چیټ دولت ته بدلوي انتظار_عمر.
پدې مرحله کې، بوټ تمه لري چې تاسو خپل عمر ته ننوځي. تاسو خپل عمر واستوئ، بوټ پیغام چیک کوي، که تاسو د شمیرې پرځای یو څه متن واستوئ، دا به ووایي: Ты ввёл некорректные данные, введи число، او ستاسو د معلوماتو بیا ننوتلو ته به انتظار وباسي. که تاسو یو شمیره واستوئ، بوټ به راپور ورکړي چې دا ستاسو عمر منلی دی، ترلاسه شوي ډاټا ډیټابیس ته ولیکئ، ستاسو څخه ترلاسه شوي ټول معلومات راپور کړئ او د چیٹ حالت بیرته خپل اصلي حالت ته راولي، د بیلګې په توګه. وی start.
د طريقه په بلنه state تاسو کولی شئ په هر وخت کې د اوسني چیٹ حالت غوښتنه وکړئ، او د کارولو څخه reset چیټ خپل اصلي حالت ته راستانه کړئ.
د پیغام فلټرونه
زموږ په قضیه کې ، دا د بوټ جوړولو کې یو له خورا مهم برخو څخه دی. دا د پیغام فلټرونو په مرسته ده چې بوټ به پوه شي چې کوم معلومات ستاسو څخه تمه لري او څنګه باید پروسس شي.