Kunyora teregiramu bot muR (chikamu 4): Kuvaka inowirirana, inonzwisisika nhaurirano ne bot.

Kana iwe wakatoverenga yapfuura zvinyorwa zvitatu kubva pane ino nhevedzano, saka iwe unotoziva kunyora yakazara-yakazara telegraph bots nekhibhodi.

Muchikamu chino, tichadzidza kunyora bot iyo inochengetedza nhaurirano inowirirana. Avo. Iyo bot ichakubvunza iwe mibvunzo uye yakamirira iwe kuti uise rumwe ruzivo. Zvichienderana nedata raunopinda, bot ichaita zvimwe zviito.

Uyewo munyaya ino tichadzidza nzira yekushandisa dhatabhesi pasi pehodhi yebhoti, mumuenzaniso wedu ichava SQLite, asi unogona kushandisa chero imwe DBMS. Ndakanyora zvakadzama nezvekudyidzana nemadhatabhesi mumutauro weR mukati ichi chinyorwa.

Kunyora teregiramu bot muR (chikamu 4): Kuvaka inowirirana, inonzwisisika nhaurirano ne bot.

Zvese zvinyorwa kubva munhevedzano "Kunyora teregiramu bot muR"

  1. Isu tinogadzira bot uye tinoishandisa kutumira mameseji muteregiramu
  2. Wedzera rutsigiro rwekuraira uye meseji mafirita kune bot
  3. Maitiro ekuwedzera kiibhodhi rutsigiro kune bot
  4. Kuvaka inowirirana, inonzwisisika nhaurirano ne bot

Zviri mukati

Kana iwe uchifarira kuongorora data, unogona kunge uchifarira zvangu teregiramu и YouTube channels. Zvizhinji zvemukati zvakatsaurirwa kumutauro weR.

  1. Nhanganyaya
  2. Bot kuvaka maitiro
  3. Bot dhizaini chimiro
  4. Bot config
  5. Gadzira shanduko yezvakatipoteredza
  6. Kugadzira database
  7. Kunyora mabasa ekushanda nedatabase
  8. Bot nzira
  9. Masefa eMessage
  10. Handlers
  11. Bot kutanga kodhi
  12. mhedziso

Nhanganyaya

Kuti bot ikumbire data kubva kwauri uye yakamirira kuti iwe uise chero ruzivo, iwe unozofanirwa kurekodha mamiriro azvino enhaurirano. Nzira yakanaka yekuita izvi ndeye kushandisa imwe mhando yedatabase yakadzikwa, seSQLite.

Avo. Zvinonzwisisika zvichave sezvizvi. Isu tinodaidza iyo bot nzira, uye iyo bot sequentially inokumbira rumwe ruzivo kubva kwatiri, uye pane imwe neimwe nhanho inomirira kuti ruzivo urwu rwupinzwe uye runogona kutarisa.

Isu tichanyora iyo yakapusa inogoneka bot, kutanga ichabvunza zita rako, ipapo zera rako, uye ichachengetedza iyo yakagamuchirwa data kune database. Paunenge uchikumbira zera, ichatarisa kuti data rakapinda inhamba uye kwete zvinyorwa.

Nhaurirano yakapfava yakadaro ichava nematunhu matatu chete:

  1. kutanga ndiyo yakajairika mamiriro ebhoti, umo isingatarisiri chero ruzivo kubva kwauri
  2. wait_name - nyika iyo bot inomirira kuti zita ripinzwe
  3. wait_age ndiyo mamiriro ayo bot inomirira kuti zera rako ripinzwe, nhamba yemakore akazara.

Bot kuvaka maitiro

Munguva yechinyorwa, isu tichavaka bot nhanho nhanho; iyo yese maitiro anogona kuratidzwa schematically sezvinotevera:
Kunyora teregiramu bot muR (chikamu 4): Kuvaka inowirirana, inonzwisisika nhaurirano ne bot.

  1. Isu tinogadzira bot config umo isu tichachengeta mamwe marongero. Mune yedu kesi, iyo bot tokeni, uye nzira inoenda kune database faira.
  2. Isu tinogadzira shanduko yenharaunda umo nzira yeprojekiti ine bot ichachengetwa.
  3. Isu tinogadzira iyo dhatabhesi pachayo, uye akati wandei mabasa kuitira kuti bot igone kupindirana nayo.
  4. Tinonyora bot nzira, i.e. mabasa aichaita.
  5. Kuwedzera masefa emeseji. Nekubatsirwa kweiyo bot ichawana nzira dzinodiwa, zvichienderana nemamiriro ezvino ekutaura.
  6. Isu tinowedzera vanobata vanozobatanidza mirairo uye mameseji neinodiwa bot nzira.
  7. Ngatitangei bot.

Bot dhizaini chimiro

Kuti zvive nyore, tichagovanisa kodhi yebhoti yedu, uye mamwe mafaera ane hukama, mune inotevera chimiro.

  • bot.R - iyo huru kodhi yebhoti yedu
  • db_bot_function.R - block yekodhi ine mabasa ekushanda nedatabase
  • bot_methods.R - kodhi ye bot nzira
  • message_filters.R -meseji mafirita
  • vabati.R - vanobata
  • config.cfg - bot config
  • create_db_data.sql - SQL script yekugadzira tafura ine chat data mudhatabhesi
  • create_db_state.sql - SQL script yekugadzira tafura yezvino chat state mudhatabhesi
  • bot.db - bot database

Iwe unogona kuona iyo yese bot purojekiti, kana скачать kubva zvangu repository paGitHub.

Bot config

Tichashandisa yakajairika segadziriro ini file, fomu rinotevera:

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

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

Muchigadziro tinonyora bot token uye nzira ye database, i.e. kune bot.db faira; isu tichagadzira iyo faira pachayo munhanho inotevera.

Kuti uwane mamwe mabhoti akaoma, unogona kugadzira mamwe ma configs akaoma, kunze kwekuti, hazvidikanwi kunyora ini config, unogona kushandisa chero imwe fomati inosanganisira JSON.

Gadzira shanduko yezvakatipoteredza

PaPC yega yega, iyo folda ine bot purojekiti inogona kuwanikwa mune akasiyana madhairekitori uye pane akasiyana madhiraivha, saka mukodhi nzira inoenda kune purojekiti folda ichaiswa kuburikidza neyakasiyana siyana. TG_BOT_PATH.

Pane nzira dzinoverengeka dzekugadzira nharaunda inoshanduka, iri nyore ndeyekunyora mufaira .Renviron.

Iwe unogona kugadzira kana kugadzirisa iyi faira uchishandisa rairo file.edit(path.expand(file.path("~", ".Renviron"))). Iite uye wedzera mutsara mumwe kune faira:

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

Zvadaro chengetedza faira .Renviron uye tangazve RStudio.

Kugadzira database

Nhanho inotevera ndeyekugadzira database. Tichada 2 matafura:

  • chat_data - data iyo bot yakakumbira kubva kumushandisi
  • chat_state - mamiriro aripo ezvese chats

Unogona kugadzira matafura aya uchishandisa inotevera SQL mubvunzo:

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

Kana iwe wakarodha bot purojekiti kubva GitHub, wobva wagadzira dhatabhesi iwe unogona kushandisa inotevera kodhi muR.

# Скрипт создания базы данных
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'))

Kunyora mabasa ekushanda nedatabase

Isu tatova nefaira rekugadzirisa rakagadzirira uye dhatabhesi rakagadzirwa. Iye zvino iwe unofanirwa kunyora mabasa ekuverenga nekunyora data kune iyi database.

Kana iwe wakarodha purojekiti kubva GitHub, ipapo unogona kuwana mabasa mufaira db_bot_function.R.

Basa rekodhi rekushanda nedatabase

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

}

Isu takagadzira 4 mabasa akareruka:

  • get_state() - tora ikozvino chat mamiriro kubva kudhatabhesi
  • set_state() - nyora yazvino chat state kune database
  • get_chat_data() - gamuchira data inotumirwa nemushandisi
  • set_chat_data() - rekodha data yakagamuchirwa kubva kumushandisi

Ese mabasa ari nyore, ivo vanoverenga data kubva kudhatabhesi vachishandisa murairo dbGetQuery(), kana kuti kuzvipira UPSERT kushanda (kushandura data iripo kana kunyora data idzva kune dhatabhesi), uchishandisa basa dbExecute().

Iyo syntax yeUPSERT mashandiro ndeaya anotevera:

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

Avo. mumunda wematafura edu chat_id ine chinomanikidzira chakasiyana uye ndicho kiyi yekutanga yematafura. Pakutanga, tinoedza kuwedzera ruzivo patafura, uye tinowana chikanganiso kana data yekutaura kwazvino yatovepo, mune iyo nyaya tinongogadzirisa ruzivo rweiyi chat.

Tevere, isu tichashandisa mabasa aya munzira dzebhoti uye mafirita.

Bot nzira

Nhanho inotevera mukuvaka bot yedu kugadzira nzira. Kana iwe wakarodha purojekiti kubva GitHub, ipapo nzira dzese dziri mufaira bot_methods.R.

Bot nzira kodhi

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

}

Isu takagadzira 5 nzira:

  • kutanga - Tanga nhaurirano
  • state - Tora mamiriro ekutaura aripo
  • reset - Gadzirisa iyo yazvino chat state
  • enter_name - Iyo bot inobvunza zita rako
  • enter_age - Iyo bot inobvunza zera rako

Method start inobvunza zita rako, uye inoshandura chat state kuita wait_name, i.e. kumira pakuisa zita rako.

Zvadaro, unotumira zita uye rinogadziriswa nenzira enter_name, bhoti inokwazisa iwe, inonyora zita rakagamuchirwa mudhatabhesi, uye inoshandura chat kuenda kuhurumende wait_age.

Panguva ino, bot inotarisira kuti iwe upinde muzera rako. Iwe unotumira zera rako, bot inotarisa meseji, kana iwe wakatumira mamwe mameseji panzvimbo yenhamba, inozoti: Ты ввёл некорректные данные, введи число, uye ichakumirira iwe kuti uise zvakare data rako. Kana iwe wakatumira nhamba, bhoti ichashuma kuti yakagamuchira makore ako, nyora iyo yakagamuchirwa data kune database, taura data yose yakagamuchirwa kubva kwauri uye udzorere nyika yekutaura panzvimbo yayo yepakutanga, i.e. V start.

Nokudaidza nzira state iwe unogona kukumbira ikozvino chat mamiriro chero nguva, uye uchishandisa iyo reset dzorera chat kuchimiro chayo chepakutanga.

Masefa eMessage

Muchiitiko chedu, ichi ndicho chimwe chezvikamu zvakakosha pakuvaka bot. Iri nerubatsiro rwemasefa emeseji iyo bot inonzwisisa kuti ndeupi ruzivo rwainotarisira kubva kwauri uye kuti inofanirwa kugadziridzwa sei.

Muchirongwa pa GitHub mafirita anonyoreswa mufaira message_filters.R.

Mharidzo sefa kodhi:

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

Mumasefa tinoshandisa basa rakanyorwa kare get_state(), kuitira kukumbira mamiriro azvino ekutaura. Iri basa rinongoda nharo imwe chete, chat id.

Sefa inotevera wait_name inogadzirisa mameseji kana chat iri mumamiriro wait_name, uye maererano nesefa wait_age inogadzirisa mameseji kana chat iri mumamiriro wait_age.

Handlers

Iyo faira ine vanobata inonzi vabati.R, uye ine kodhi inotevera:

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

Chekutanga tinogadzira vanobata vemirairo vanokubvumidza kuti umhanye nzira dzekutanga dialog, kuigadzirisa, uye kubvunza mamiriro azvino.

Tevere, tinogadzira 2 meseji vanobata vachishandisa mafirita akagadzirwa munhanho yapfuura, uye towedzera sefa kwavari !MessageFilters$command, kuitira kuti isu tigone kushandisa mirairo mune chero chat state.

Bot kutanga kodhi

Iye zvino tine zvese zvakagadzirira kuvhura, iyo huru kodhi yekutanga bot iri mufaira 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()

Nekuda kweizvozvo, takawana iyi bot:
Kunyora teregiramu bot muR (chikamu 4): Kuvaka inowirirana, inonzwisisika nhaurirano ne bot.

Chero nguva uchishandisa murairo /state isu tinokwanisa kubvunza iyo yazvino chat state, uye nekushandisa murairo /reset dzosera chat kune yayo yekutanga uye tanga nhaurirano zvakare.

mhedziso

Muchinyorwa chino, takaona mashandisiro edhatabhesi mukati mebhoti, uye maitiro ekuvaka anotevedzana ane musoro nhaurirano nekurekodha mamiriro ekutaura.

Muchiitiko ichi, takatarisa muenzaniso wekare, kuitira kuti zvive nyore kwauri kuti unzwisise pfungwa yekuvaka mabhoti akadaro; mukuita, unogona kuvaka hurukuro dzakaoma zvikuru.

Muchinyorwa chinotevera mune ino nhevedzano, isu tichadzidza nzira yekudzora kodzero dzevashandisi bot kushandisa dzakasiyana nzira dzayo.

Source: www.habr.com

Voeg