Scribens telegraphum autocinetum in R (parte 4): Aedificium constans, dialogus logicus cum autocineto

Si iam lege prior tria vasa ex hac serie, tunc iam scis telegraphum telegraphum claviaturae plenae scribere cum automata sua.

In hoc articulo discemus quomodo scribere autocinetum qui constantem dialogum servabit. Illae. Bot e te rogabit et te exspectabo ut aliquas notitias ineas. Prout notitias quas intras, actus aliquas bot aget.

Etiam in hoc articulo discemus quomodo uti database sub cucullo automati, in exemplo nostro erit SQLite, sed alia DBMS uti potes. Scripsi planius de mutuo cum databases in R lingua in hoc articulum.

Scribens telegraphum autocinetum in R (parte 4): Aedificium constans, dialogus logicus cum autocineto

Articuli omnes ex serie "Scribere telegraphum bot in R"

  1. Nos creare automati et utimur eo ut mittere nuntios in telegraphum
  2. Adde imperium subsidium et nuntium Filtra ad bot
  3. Quam addere tincidunt auxilium ad bot
  4. Aedificationem constantem, dialogum logicum cum autocineto

contentus

Si vos es interested in Analysis analysi, fortasse interesse in my telegraphum и YouTube rivos. Pleraque contenti r lingua dedicata est.

  1. introduction
  2. Bot aedificium processus
  3. Bot project structure
  4. Bot aboutconfig
  5. Create an environment variabilis
  6. Creando database
  7. Scribere munera cum database laborare
  8. Bot modi
  9. Nuntius filters
  10. Tracto
  11. Bot Lorem codice
  12. conclusio,

introduction

Ut automataria data a te petant et exspectent te ut aliqua indicia ineas, necesse est hodiernum dialogi statum referre. Optime ad hoc faciendum est utendum qualicumque datorum infixo, ut SQLite.

Illae. Ratio talis erit. Methodum bot vocamus, et successiue bot notitias aliquas a nobis petit, et in unoquoque gradu hanc informationem ineundam exspectat et eam coercere potest.

Simplicissima automata scribemus, primum nomen tuum rogabit, deinde aetas tua, et data accepta datorum servabis. Cum aetatem petens, notitias inscriptas reprehendo numerum et non textum esse.

Talis dialogus simplex tantum tres status habebit;

  1. initium est normale status automati, in quo nulla a te exspectata notitia
  2. wait_name - state in qua nomen automati exspectatur ingressus
  3. wait_age est status in quo moratur aetas tua ineundo, numerus plenus annorum.

Bot aedificium processus

Per articulum gradatim aedificabimus autocinetum, totum processum schematically depingi potest hoc modo:
Scribens telegraphum autocinetum in R (parte 4): Aedificium constans, dialogus logicus cum autocineto

  1. Nos creare automati config in quo aliquas occasus congregemus. In casu nostro, signum automati et via ad fasciculi datorum.
  2. Ambitum variabile creamus in quo via ad consilium cum autocineto reponenda erit.
  3. Ipsum database creamus et nonnulla munera ita ut autocinetus cum eo correspondere possit.
  4. bot modos scribimus, i.e. quae tibi munera praestabunt.
  5. Filtra nuntium addit. Cuius ope autocinetus accessurus methodos necessarios, secundum praesentem statum chat.
  6. Tractatores addimus qui mandata ac mandata connectunt cum methodis autocineticis necessariis.
  7. Lorem bot.

Bot project structure

Pro commodo, codicem nostrorum autocinetorum et aliorum imaginum cognatorum in structuram sequentem dividemus.

  • bot.R - pelagus codice nostrae bot
  • db_bot_function.R - truncum codicem munera ad operandum cum database
  • bot_methods.R - codice modi bot
  • message_filters.R - nuntius Filtra
  • handlers.R* - tracto
  • config.cfg - bot config
  • create_db_data.sql - SQL scriptum est ad partum mensam cum chat notitia in database
  • create_db_state.sql - SQL scriptum pro creando mensam hodiernae chat status in database
  • bot.db - bot database

Potes totam rem autocineticam inspicere, or скачать ex my repositio in GitHub.

Bot aboutconfig

Nos autem solito utemur quasi config ini filehac forma;

[bot_settings]
bot_token=ТОКЕН_ВАШЕГО_БОТА

[db_settings]
db_path=C:/ПУТЬ/К/ПАПКЕ/ПРОЕКТА/bot.db

In aboutconfig scribimus bot signum et iter datorum, i.e. ad bot.db fasciculum: ipsam tabellam in proximo gradu creabimus.

Automata pro magis implicata, magis implicatas configas creare potes, praeterea, non est necesse scribere ini config, alia forma cum JSON uti potes.

Create an environment variabilis

In unaquaque PC, folder cum autocineto incepto collocari potest in diversis directoriis et in diversis agitationibus, sic in codice via ad folder consilium ponetur per ambitum variabile. TG_BOT_PATH.

Plures modi ambitum variabilem creandi, simplicissimus eam in tabella scribere est .Renviron.

Potes creare vel creare hunc fasciculum utens imperio file.edit(path.expand(file.path("~", ".Renviron"))). Hoc age, et unam tabellam adde:

TG_BOT_PATH=C:/ПУТЬ/К/ВАШЕМУ/ПРОЕКТУ

Next file servare .Renviron et sileo RStudio.

Creando database

Proximus gradus database creare est. Non opus est nobis 2 tabulis;

  • chat_data - notitia ut automati postulavit a user
  • chat_state - current status omnium chats

Has tabulas creare potes utentes interrogatione sequenti 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
);

Si downloaded bot project a GitHubtum creare datorum sequenti codice uti potes in 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'))

Scribere munera cum database laborare

Configurationis lima paratam et database creatum iam habemus. Nunc opus est tibi munera scribere ut notitias legere et scribere huic datorum.

Si downloaded project a GitHub, functiones in tabella invenire potes db_bot_function.R.

Function code for working with the database

# ###########################################################
# 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 munera simplicia creavimus;

  • get_state() - adepto hodiernam chat status a database
  • set_state() - scribe hodiernam chat publica ad database
  • get_chat_data() - accipere notitia a user
  • set_chat_data() - recordum notitia accepi a user

Munera omnia admodum simplicia sunt, vel data a database lege utentes imperio dbGetQuery()Aut committere UPSERT operatio (mutatione existentium notitia vel scribens nova notitia ad database), utens ad munus dbExecute().

Syntaxis in opere UPSERT sic est:

INSERT INTO chat_data (chat_id, ${field})
VALUES(${chat_id}, '${value}') 
ON CONFLICT(chat_id) 
DO UPDATE SET ${field}='${value}';

Illae. in tabulis nostris agri chat_id unicitatem coactionem habet ac primarium clavem tabularum. Initio conamur informationes addere tabulae et errorem consequimur si notitia chat praesentis iam praesens est, quo in casu tantum informationes huius chat renovamus.

Deinde his muneribus utemur in methodis et percolationibus bot.

Bot modi

Proximus gradus nostrae aedificationis autocineti est methodos creare. Si downloaded project a GitHubergo omnes modi sunt in tabella bot_methods.R.

Bot modum codice

# ###########################################################
# 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')
  }

}

V modos creavimus;

  • satus - Satus a alternis
  • status - Adepto hodiernam chat publica
  • Reset - Reset hodiernam chat publica
  • enter_name - Bot quaerit pro nomine tuo
  • enter_age - Bot quaerit propter aetatem

modum start petit nomen tuum, et mutat statum chat wait_name, i.e. ad standby intrantes nomen tuum.

Deinde nomen mittis et per modum processit enter_nameautomati te salutat, nomen receptum datorum et permutat chat ad rem publicam wait_age.

Hac scaena, expectat bot te ad tuam aetatem ingredi. Aetatem tuam mittis, autocinetum nuntium compescit, si textum aliquem loco numero misisti, dicet: Ты ввёл некорректные данные, введи числоet te exspectabo ut notitias tuas reintraham. Si plures misisti, automati nuntiabit receptam aetatem tuam, datam datorum scribe, omnia indicia a te accepta refer et chat statum suum in statum pristinum redde, i.e. V start.

Per modum vocant state postulare potes statum chat currentem quovis tempore, ac utens reset chat ad statum pristinum revertetur.

Nuntius filters

In nobis, haec est una ex maximis partibus in automati aedificando. Auxilio nuntiis eliquarum in eo intelleget automati quid indicio a te expectet et quomodo procedendum sit.

In project on GitHub Filtra sunt in tabella message_filters.R.

Nuntius codice filter:

# ###########################################################
# 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"
}
)

In odio utimur functione antea scripta get_state()ad petendam statum hodiernum chat. Munus hoc solum 1 argumentum requirit, Curabitur id.

Colloquium proximum wait_name processus nuntiis cum chat in civitate wait_nameac proinde colum wait_age processus nuntiis cum chat in civitate wait_age.

Tracto

Tabella tracto dicitur handlers.R*et sequenti codice habet;

# ###########################################################
# 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)

Primum tractatores iubemus creamus qui methodos currere permittet ut dialogum incipias, illud reset et praesentem quaestionem statuas.

Deinceps tractatores nuntium 2 creamus columellas in priore gradu creatos utentes, eis filtrum addimus !MessageFilters$commandut in quacumque re publica uti possimus.

Bot Lorem codice

Nunc omnia parata habemus ad deducendum, signum principale ad quod autocinetum in tabella deducendum est 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()

Quam ob rem hoc bot venimus:
Scribens telegraphum autocinetum in R (parte 4): Aedificium constans, dialogus logicus cum autocineto

Quando utens imperio /state statum hodiernam chat percontari et imperio uti possumus /reset chat in statum pristinum revertere et dialogum denuo committitur.

conclusio,

In hoc articulo figurati sumus quomodo utendi database in autocineto, et quomodo in dialogis logicis congruentibus aedificetur status chat memoria.

In hoc casu exemplum primitivum inspeximus, ut facilius esset ideam aedificandi huiusmodi automata perspicere, in praxi multo magis implicatas dialogos aedificare potes.

In sequenti articulo in hac serie, discemus restringere iura usorum autocinetorum variis modis uti.

Source: www.habr.com

Add a comment