Sau ib lub telegram bot hauv R (ib ntu 4): Tsim kom muaj kev sib raug zoo, kev sib tham nrog tus bot

Yog koj twb tau nyeem yav dhau los lawm peb tsab xov xwm los ntawm no series, ces koj twb paub yuav ua li cas sau tag nrho-fledged telegram bots nrog ib tug keyboard.

Hauv tsab xov xwm no, peb yuav kawm yuav ua li cas sau ib tus bot uas yuav tswj tau qhov kev sib tham zoo ib yam. Cov. bot yuav nug koj cov lus nug thiab tos koj nkag mus rau qee cov ntaub ntawv. Nyob ntawm cov ntaub ntawv koj nkag mus, bot yuav ua qee yam haujlwm.

Tsis tas li hauv tsab xov xwm no peb yuav kawm paub siv cov ntaub ntawv hauv qab hood ntawm bot, hauv peb qhov piv txwv nws yuav yog SQLite, tab sis koj tuaj yeem siv lwm yam DBMS. Kuv tau sau kom ntxaws ntxiv txog kev cuam tshuam nrog cov ntaub ntawv hauv R hom lus hauv qhov no tsab xov xwm.

Sau ib lub telegram bot hauv R (ib ntu 4): Tsim kom muaj kev sib raug zoo, kev sib tham nrog tus bot

Tag nrho cov ntawv los ntawm koob "Sau ib lub xov tooj bot hauv R"

  1. Peb tsim ib lub bot thiab siv nws los xa cov lus hauv telegram
  2. Ntxiv cov lus txhawb nqa thiab cov lus lim rau bot
  3. Yuav ua li cas ntxiv cov keyboard txhawb rau bot
  4. Tsim kom muaj kev sib raug zoo, kev sib tham nrog cov bot

Txheem

Yog tias koj txaus siab rau cov ntaub ntawv tsom xam, tej zaum koj yuav txaus siab rau kuv telegram и youtube cov channel. Cov ntsiab lus feem ntau yog mob siab rau R hom lus.

  1. Taw qhia
  2. Bot lub tsev txheej txheem
  3. Bot qhov project qauv
  4. Bot config
  5. Tsim ib puag ncig hloov pauv
  6. Tsim ib tug database
  7. Sau cov haujlwm ua haujlwm nrog cov ntaub ntawv
  8. Cov txheej txheem bot
  9. Cov lus lim
  10. Cov tuav
  11. Bot tso cai code
  12. xaus

Taw qhia

Txhawm rau kom bot thov cov ntaub ntawv los ntawm koj thiab tos kom koj nkag mus rau txhua yam ntaub ntawv, koj yuav tsum tau sau lub xeev tam sim no ntawm kev sib tham. Txoj hauv kev zoo tshaj los ua qhov no yog siv qee yam ntawm cov ntaub ntawv embedded, xws li SQLite.

Cov. Lub logic yuav ua raws li nram no. Peb hu rau txoj kev bot, thiab bot tau thov qee cov ntaub ntawv los ntawm peb, thiab ntawm txhua kauj ruam nws tos cov ntaub ntawv no nkag mus thiab tuaj yeem tshawb xyuas nws.

Peb yuav sau qhov yooj yim tshaj plaws ua tau bot, ua ntej nws yuav nug koj lub npe, tom qab ntawd koj lub hnub nyoog, thiab yuav khaws cov ntaub ntawv tau txais mus rau hauv cov ntaub ntawv. Thaum nug txog hnub nyoog, nws yuav xyuas tias cov ntaub ntawv nkag yog tus lej thiab tsis yog ntawv.

Xws li kev sib tham yooj yim yuav muaj tsuas yog peb lub xeev:

  1. pib yog lub xeev ib txwm ntawm bot, uas nws tsis cia siab tias yuav muaj cov ntaub ntawv los ntawm koj
  2. wait_name - lub xeev uas tus bot tos rau lub npe nkag
  3. wait_age yog lub xeev uas tus bot tos koj lub hnub nyoog nkag, tus naj npawb ntawm xyoo.

Bot lub tsev txheej txheem

Nyob rau hauv tsab xov xwm, peb yuav tsim ib tug bot ib kauj ruam; tag nrho cov txheej txheem yuav schematically depicted raws li nram no:
Sau ib lub telegram bot hauv R (ib ntu 4): Tsim kom muaj kev sib raug zoo, kev sib tham nrog tus bot

  1. Peb tsim bot config uas peb yuav khaws qee qhov chaw. Hauv peb qhov xwm txheej, bot token, thiab txoj hauv kev mus rau cov ntaub ntawv database.
  2. Peb tsim ib qho kev hloov pauv ib puag ncig uas txoj hauv kev mus rau qhov project nrog bot yuav khaws cia.
  3. Peb tsim cov ntaub ntawv nws tus kheej, thiab ntau lub luag haujlwm kom tus bot tuaj yeem cuam tshuam nrog nws.
  4. Peb sau bot txoj kev, i.e. cov haujlwm uas nws yuav ua.
  5. Ntxiv cov ntawv lim. Nrog kev pab los ntawm cov bot yuav nkag mus rau cov kev tsim nyog, nyob ntawm seb lub xeev tam sim no ntawm kev sib tham.
  6. Peb ntxiv cov neeg ua haujlwm uas yuav txuas cov lus txib thiab cov lus nrog cov txheej txheem tsim nyog bot.
  7. Cia peb pib lub bot.

Bot qhov project qauv

Txhawm rau kom yooj yim, peb yuav faib cov cai ntawm peb cov bot, thiab lwm yam ntaub ntawv ntsig txog, rau hauv cov qauv hauv qab no.

  • bot. R - lub ntsiab cai ntawm peb bot
  • db_bot_function.R - ib qho thaiv ntawm cov lej nrog cov haujlwm rau kev ua haujlwm nrog cov ntaub ntawv
  • bot_methods.R - cov cai ntawm bot txoj kev
  • message_filters.R — lus lim
  • cov kws kho mob.R - tus tuav
  • config.cfg - bot config
  • tsim_db_data.sql - SQL tsab ntawv tsim ib lub rooj nrog cov ntaub ntawv sib tham hauv cov ntaub ntawv
  • tsim_db_state.sql - SQL tsab ntawv los tsim ib lub rooj ntawm lub xeev tam sim no tham nyob rau hauv lub database
  • bot.db ib - bot database

Koj tuaj yeem saib tag nrho bot project, lossis download los ntawm kuv repository ntawm GitHub.

Bot config

Peb yuav siv qhov ib txwm ua raws li kev teeb tsa ib file, daim ntawv hauv qab no:

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

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

Nyob rau hauv lub config peb sau lub bot token thiab txoj kev mus rau lub database, i.e. mus rau bot.db cov ntaub ntawv; peb yuav tsim cov ntaub ntawv nws tus kheej hauv cov kauj ruam tom ntej.

Rau ntau cov bots nyuaj, koj tuaj yeem tsim ntau txoj kev teeb tsa, dua li, nws tsis tas yuav sau ib qho ini config, koj tuaj yeem siv lwm hom ntawv suav nrog JSON.

Tsim ib puag ncig hloov pauv

Ntawm txhua lub PC, cov ntawv tais ceev tseg nrog qhov project bot tuaj yeem nyob hauv cov npe sib txawv thiab ntawm cov tsav sib txawv, yog li hauv txoj cai txoj kev mus rau qhov project folder yuav raug teeb tsa los ntawm ib puag ncig sib txawv. TG_BOT_PATH.

Muaj ntau ntau txoj hauv kev los tsim ib qho kev hloov pauv ib puag ncig, qhov yooj yim tshaj plaws yog sau rau hauv cov ntaub ntawv .Renviron.

Koj tuaj yeem tsim lossis kho cov ntaub ntawv no siv cov lus txib file.edit(path.expand(file.path("~", ".Renviron"))). Ua nws thiab ntxiv ib kab rau hauv cov ntaub ntawv:

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

Tom ntej no txuag cov ntaub ntawv .Renviron thiab rov pib RStudio.

Tsim ib tug database

Cov kauj ruam tom ntej yog los tsim ib lub database. Peb yuav xav tau 2 lub rooj:

  • chat_data - cov ntaub ntawv uas tus bot thov los ntawm tus neeg siv
  • chat_state - lub xeev tam sim no ntawm txhua qhov kev sib tham

Koj tuaj yeem tsim cov ntxhuav no siv cov lus nug SQL nram qab no:

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

Yog tias koj rub tawm qhov project bot los ntawm GitHub, tom qab ntawd los tsim cov ntaub ntawv koj tuaj yeem siv cov cai hauv qab no hauv 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'))

Sau cov haujlwm ua haujlwm nrog cov ntaub ntawv

Peb twb muaj ib tug configuration ntaub ntawv npaj thiab ib tug database tsim. Tam sim no koj yuav tsum sau cov haujlwm los nyeem thiab sau cov ntaub ntawv rau hauv cov ntaub ntawv no.

Yog hais tias koj downloaded qhov project los ntawm GitHub, ces koj tuaj yeem pom cov haujlwm hauv cov ntaub ntawv db_bot_function.R.

Function code rau kev ua haujlwm nrog 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]])

}

Peb tsim 4 txoj haujlwm yooj yim:

  • get_state() - tau txais lub xeev sib tham tam sim no los ntawm database
  • set_state() - sau lub xeev kev sib tham tam sim no rau hauv database
  • get_chat_data() - tau txais cov ntaub ntawv xa los ntawm tus neeg siv
  • set_chat_data() - sau cov ntaub ntawv tau txais los ntawm tus neeg siv

Tag nrho cov haujlwm yog qhov yooj yim heev, lawv yog nyeem cov ntaub ntawv los ntawm cov ntaub ntawv siv cov lus txib dbGetQuery(), los yog cog lus UPSERT kev ua haujlwm (hloov cov ntaub ntawv uas twb muaj lawm lossis sau cov ntaub ntawv tshiab rau hauv cov ntaub ntawv), siv cov haujlwm dbExecute().

Cov syntax rau UPSERT kev ua haujlwm yog raws li hauv qab no:

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

Cov. hauv peb lub rooj teb chat_id muaj ib tug uniqueness txwv thiab yog lub ntsiab tseem ceeb ntawm cov ntxhuav. Thaum pib, peb sim ntxiv cov ntaub ntawv rau lub rooj, thiab peb tau txais qhov yuam kev yog tias cov ntaub ntawv rau kev sib tham tam sim no twb muaj lawm, qhov twg peb tsuas hloov kho cov ntaub ntawv rau kev sib tham no.

Tom ntej no, peb yuav siv cov haujlwm no hauv bot txoj kev thiab cov lim dej.

Cov txheej txheem bot

Cov kauj ruam tom ntej hauv kev tsim peb bot yog los tsim cov txheej txheem. Yog hais tias koj downloaded qhov project los ntawm GitHub, ces txhua txoj kev yog nyob rau hauv cov ntaub ntawv bot_methods.R.

Bot txoj kev code

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

}

Peb tsim 5 txoj kev:

  • pib - Pib lub dialog
  • xeev - Tau txais lub xeev sib tham tam sim no
  • rov pib dua - Rov pib dua lub xeev kev sib tham tam sim no
  • enter_name - Tus bot nug koj lub npe
  • enter_age - Tus bot nug koj lub hnub nyoog

Txujci start nug koj lub npe, thiab hloov lub xeev kev sib tham rau tos_npe, i.e. mus standby rau sau koj lub npe.

Tom ntej no, koj xa lub npe thiab nws yog ua tiav los ntawm txoj kev enter_name, bot txais tos koj, sau lub npe tau txais rau hauv cov ntaub ntawv, thiab hloov cov kev sib tham mus rau lub xeev tos_age.

Nyob rau theem no, bot xav kom koj nkag mus rau koj lub hnub nyoog. Koj xa koj lub hnub nyoog, bot tshawb xyuas cov lus, yog tias koj xa qee cov ntawv tsis yog tus lej, nws yuav hais tias: Ты ввёл некорректные данные, введи число, thiab yuav tos kom koj rov nkag koj cov ntaub ntawv. Yog tias koj xa tus lej, bot yuav tshaj tawm tias nws tau txais koj lub hnub nyoog, sau cov ntaub ntawv tau txais mus rau hauv cov ntaub ntawv, tshaj tawm tag nrho cov ntaub ntawv tau txais los ntawm koj thiab xa rov qab lub xeev kev sib tham mus rau nws txoj haujlwm qub, i.e. V start.

Los ntawm kev hu rau txoj kev state koj tuaj yeem thov qhov kev sib tham tam sim no txhua lub sijhawm, thiab siv lub reset rov qab sib tham mus rau nws lub xeev qub.

Cov lus lim

Hauv peb qhov xwm txheej, qhov no yog ib qho tseem ceeb tshaj plaws hauv kev tsim lub bot. Nws yog nrog kev pab los ntawm cov lus lim uas bot yuav nkag siab txog cov ntaub ntawv nws xav tau los ntawm koj thiab yuav ua li cas nws yuav tsum tau ua.

Hauv qhov project ntawm GitHub cov ntxaij lim dej tau sau npe rau hauv cov ntaub ntawv message_filters.R.

Message filter code:

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

Hauv cov ntxaij lim dej peb siv cov haujlwm sau yav dhau los get_state(), txhawm rau thov lub xeev tam sim no ntawm kev sib tham. Txoj haujlwm no tsuas yog 1 qhov kev sib cav, sib tham id.

Tom ntej no lim tos_npe ua cov lus thaum sib tham nyob rau hauv ib lub xeev wait_name, thiab raws li cov lim tos_age ua cov lus thaum sib tham nyob rau hauv ib lub xeev wait_age.

Cov tuav

Cov ntaub ntawv nrog tus tuav yog hu ua cov kws kho mob.R, thiab muaj cov cai hauv qab no:

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

Ua ntej peb tsim cov neeg tuav cov lus txib uas yuav tso cai rau koj los khiav txoj hauv kev los pib sib tham, rov pib dua, thiab nug txog lub xeev tam sim no.

Tom ntej no, peb tsim 2 cov lus tuav siv cov ntxaij lim dej tsim hauv cov kauj ruam dhau los, thiab ntxiv cov lim rau lawv !MessageFilters$command, yog li peb tuaj yeem siv cov lus txib hauv txhua lub xeev sib tham.

Bot tso cai code

Tam sim no peb muaj txhua yam npaj txhij mus tso tawm, lub ntsiab cai rau launching bot yog nyob rau hauv cov ntaub ntawv 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()

Yog li ntawd, peb tau txais no bot:
Sau ib lub telegram bot hauv R (ib ntu 4): Tsim kom muaj kev sib raug zoo, kev sib tham nrog tus bot

Thaum twg los tau siv cov lus txib /state peb tuaj yeem nug lub xeev kev sib tham tam sim no, thiab siv cov lus txib /reset rov qab sib tham mus rau nws lub xeev qub thiab pib qhov kev sib tham dua.

xaus

Hauv tsab xov xwm no, peb xav txog yuav ua li cas siv cov ntaub ntawv hauv ib lub bot, thiab yuav ua li cas los tsim cov kev sib tham sib txuas lus los ntawm kev sau cov lus sib tham.

Hauv qhov no, peb tau saib cov piv txwv tseem ceeb tshaj plaws, yog li ntawd nws yuav yooj yim dua rau koj kom nkag siab txog lub tswv yim ntawm kev tsim cov bots; hauv kev xyaum, koj tuaj yeem tsim ntau cov kev sib tham nyuaj.

Nyob rau hauv tsab xov xwm tom ntej no, peb yuav kawm yuav ua li cas txwv txoj cai ntawm cov neeg siv bot siv ntau yam ntawm nws txoj kev.

Tau qhov twg los: www.hab.com

Ntxiv ib saib