Wenn Sie die vorherigen drei Artikel dieser Reihe bereits gelesen haben , wissen Sie bereits, wie man vollwertige Telegramm-Bots mit einer Tastatur schreibt.
In diesem Artikel lernen wir, wie man einen Bot schreibt, der einen konsistenten Dialog aufrechterhĂ€lt. Jene. Der Bot wird Ihnen Fragen stellen und darauf warten, dass Sie Informationen eingeben. AbhĂ€ngig von den von Ihnen eingegebenen Daten fĂŒhrt der Bot einige Aktionen aus.
In diesem Artikel erfahren Sie auch, wie Sie eine Datenbank unter der Haube eines Bots verwenden. In unserem Beispiel handelt es sich um SQLite. Sie können jedoch auch jedes andere DBMS verwenden. In diesem Artikel habe ich ausfĂŒhrlicher ĂŒber die Interaktion mit Datenbanken in der Sprache R geschrieben .

Alle Artikel aus der Reihe "Schreiben eines Telegrammbot in der Sprache R"
- Wir erstellen einen Bot und senden damit Nachrichten an das Telegramm
- FĂŒgen Sie dem Bot BefehlsunterstĂŒtzung und Nachrichtenfilter hinzu
- So fĂŒgen Sie Ihrem Bot TastaturunterstĂŒtzung hinzu
- Aufbau eines konsistenten, logischen Dialogs mit dem Bot
- Verwaltung der Bot-Benutzerrechte
Inhalt
Wenn Sie an Datenanalyse interessiert sind, interessieren Sie sich möglicherweise fĂŒr meine Telegramm- und Youtube- KanĂ€le. Der gröĂte Teil des Inhalts ist der R-Sprache gewidmet.
, , - . , , SQLite.
.. . , - , , .
, , , . , , .
:
- start â ,
- wait_name â ,
- wait_age â , , .
, :

- , . , .
- , .
- , , .
- , .. .
- . , .
- , .
- .
, .
- bot.R â
- db_bot_function.R â
- bot_methods.R â
- message_filters.R â
- handlers.R â
- config.cfg â
- create_db_data.sql â SQL
- create_db_state.sql â SQL
- bot.db â
, GitHub.
ini , :
[bot_settings]
bot_token=__
[db_settings]
db_path=C://///bot.db
, , .. bot.db, .
, ini , JSON.
, , TG_BOT_PATH.
, â .Renviron.
, file.edit(path.expand(file.path("~", ".Renviron"))). :
TG_BOT_PATH=C:////
.Renviron RStudio.
â . 2 :
- 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()âset_state()âget_chat_data()âset_chat_data()â
, dbGetQuery(), UPSERT ( ), dbExecute().
UPSERT :
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')
}
}5 :
- start â
- state â
- reset â
- enter_name â
- enter_age â
start , wait_name, .. .
, enter_name, , , wait_age.
. , , - : , , . , , , , , .. start.
state , reset .
. , .
GitHub message_filters.R.
:
# ###########################################################
# 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"
}
)
get_state(), , . 1 , id .
wait_name wait_name, wait_age wait_age.
handlers.R, :
# ###########################################################
# 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)
, , , .
2 , !MessageFilters$command, , .
, 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()
, :

/state , /reset .
, .
In diesem Fall haben wir das primitivste Beispiel betrachtet. Um Ihnen das VerstÀndnis der Idee des Erstellens solcher Bots zu erleichtern, können Sie in der Praxis viel komplexere Dialoge erstellen.
Im nÀchsten Artikel dieser Reihe erfahren Sie, wie Sie die Rechte von Bot-Benutzern auf die Verwendung verschiedener Methoden einschrÀnken.