Барои он ки бот аз шумо маълумот талаб кунад ва интизор шавед, ки шумо ягон маълумот ворид кунед, шумо бояд ҳолати кунунии муколамаро сабт кунед. Роҳи беҳтарини ин кор ин истифодаи як намуди пойгоҳи додаҳо, ба монанди SQLite мебошад.
Онхое. Мантиқ чунин хоҳад буд. Мо усули ботро даъват мекунем ва бот пай дар пай баъзе маълумотро аз мо талаб мекунад ва дар ҳар қадам интизори ворид шудани ин маълумот аст ва метавонад онро тафтиш кунад.
chat_data — маълумоте, ки бот аз корбар дархост кардааст
chat_state — ҳолати кунунии ҳамаи чатҳо
Шумо метавонед ин ҷадвалҳоро бо истифода аз дархости зерини SQL эҷод кунед:
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]])
}
Мо 4 функсияи оддиро офаридаем:
get_state() — ҳолати кунунии чатро аз базаи маълумот гиред
# ###########################################################
# 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')
}
}
Мо 5 усулро таҳия кардем:
оғоз — Муколамаро оғоз кунед
давлат — Ҳолати ҷории чатро гиред
аз нав танзим кардан — Ҳолати ҷории сӯҳбатро аз нав танзим кунед
enter_name — Бот номи шуморо мепурсад
enter_age — Бот синну соли шуморо мепурсад
метод start номи шуморо мепурсад ва ҳолати чатро ба тағйир медиҳад интизор_ном, яъне. барои ворид кардани номи худ интизор шавед.
Баъдан, шумо номро мефиристед ва он бо усул коркард карда мешавад enter_name, бот ба шумо салом мерасонад, номи гирифташударо ба базаи маълумот менависад ва чатро ба ҳолати гузаранда медиҳад давраи интизорӣ.
Бо даъват кардани усул state шумо метавонед дар вақти дилхоҳ ҳолати кунунии чатро дархост кунед ва бо истифода аз reset чатро ба ҳолати аввалааш баргардонед.
Филтрҳои паёмҳо
Дар ҳолати мо, ин яке аз қисмҳои муҳимтарини сохтани бот мебошад. Маҳз бо ёрии филтрҳои паёмҳо, бот дарк хоҳад кард, ки кадом маълумотро аз шумо интизор аст ва чӣ гуна онро бояд коркард кард.
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()
Дар натиҷа мо ин ботро гирифтем:
Ҳар вақт бо истифода аз фармон /state мо метавонем ҳолати кунунии чат пурсед, ва бо истифода аз фармон /reset чатро ба ҳолати аввалааш баргардонед ва муколамаро дубора оғоз кунед.