R хэл дээр телеграм бот бичих (4-р хэсэг): Боттой тууштай, логик яриа хэлцлийг бий болгох

Хэрэв та өмнөхийг аль хэдийн уншсан бол гурван нийтлэл Энэ цувралаас та гараараа бүрэн хэмжээний телеграм роботуудыг хэрхэн бичихээ аль хэдийн мэддэг болсон.

Энэ нийтлэлд бид тогтвортой харилцан яриаг хадгалах роботыг хэрхэн бичих талаар сурах болно. Тэдгээр. Бот танаас асуулт асууж, зарим мэдээлэл оруулахыг хүлээх болно. Таны оруулсан өгөгдлөөс хамааран робот зарим үйлдлийг гүйцэтгэх болно.

Мөн энэ нийтлэлд бид bot-ийн өгөгдлийн санг хэрхэн ашиглах талаар сурах болно, бидний жишээнд энэ нь SQLite байх болно, гэхдээ та өөр ямар ч DBMS ашиглаж болно. Би R хэл дээрх мэдээллийн сантай харилцах талаар илүү дэлгэрэнгүй бичсэн энэ нийтлэл.

R хэл дээр телеграм бот бичих (4-р хэсэг): Боттой тууштай, логик яриа хэлцлийг бий болгох

"R-д телеграм бот бичих" цувралын бүх нийтлэл

  1. Бид робот үүсгээд түүгээрээ телеграмм руу мессеж илгээдэг
  2. Ботод тушаалын дэмжлэг болон мессежийн шүүлтүүрийг нэмнэ үү
  3. Бот дээр гарын тусламжийг хэрхэн нэмэх вэ
  4. Боттой тууштай, логик харилцан яриаг бий болгох

Агуулга

Хэрэв та өгөгдлийн шинжилгээг сонирхож байгаа бол миний мэдээллийг сонирхож магадгүй юм цахилгаан мэдээ и YouTube-ийн сувгууд. Ихэнх контент нь R хэлэнд зориулагдсан.

  1. Танилцуулга
  2. Бот бүтээх үйл явц
  3. Бот төслийн бүтэц
  4. Ботын тохиргоо
  5. Орчны хувьсагч үүсгэх
  6. Мэдээллийн сан үүсгэх
  7. Өгөгдлийн сантай ажиллах функц бичих
  8. Бот аргууд
  9. Мессежийн шүүлтүүрүүд
  10. Ажиллагчид
  11. Бот эхлүүлэх код
  12. дүгнэлт

Танилцуулга

Бот танаас мэдээлэл хүсч, ямар нэгэн мэдээлэл оруулахыг хүлээхийн тулд та харилцан ярианы одоогийн төлөвийг бүртгэх шаардлагатай болно. Үүнийг хийх хамгийн сайн арга бол SQLite гэх мэт агуулагдсан мэдээллийн санг ашиглах явдал юм.

Тэдгээр. Логик нь дараах байдалтай байх болно. Бид bot аргыг дууддаг бөгөөд бот нь биднээс зарим мэдээллийг дараалан авах бөгөөд алхам бүртээ энэ мэдээллийг оруулахыг хүлээж, шалгаж болно.

Бид хамгийн энгийн бот бичих бөгөөд эхлээд таны нэрийг, дараа нь насыг асууж, хүлээн авсан өгөгдлийг мэдээллийн санд хадгалах болно. Насыг асуухад оруулсан өгөгдөл нь текст биш харин тоо эсэхийг шалгах болно.

Ийм энгийн яриа хэлцэл нь зөвхөн гурван төлөвтэй байх болно.

  1. эхлэх нь ботын ердийн төлөв бөгөөд энэ нь танаас ямар ч мэдээлэл хүлээхгүй байх явдал юм
  2. хүлээх_нэр - бот нэрийг оруулахыг хүлээж буй төлөв
  3. хүлээх_нас нь таны насыг оруулахыг робот хүлээж буй төлөв буюу бүтэн жилийн тоо юм.

Бот бүтээх үйл явц

Өгүүллийн үеэр бид алхам алхмаар робот бүтээх болно, бүх үйл явцыг схемийн дагуу дараах байдлаар дүрсэлж болно.
R хэл дээр телеграм бот бичих (4-р хэсэг): Боттой тууштай, логик яриа хэлцлийг бий болгох

  1. Бид зарим тохиргоог хадгалах bot тохиргоог үүсгэдэг. Манай тохиолдолд бот токен, мэдээллийн сангийн файлд хүрэх зам.
  2. Бид боттой төсөлд хүрэх замыг хадгалах орчны хувьсагчийг бий болгодог.
  3. Бид мэдээллийн сан болон хэд хэдэн функцийг бий болгодог бөгөөд ингэснээр бот түүнтэй харьцах боломжтой.
  4. Бид bot аргуудыг бичдэг, өөрөөр хэлбэл. түүний гүйцэтгэх функцууд.
  5. Зурвас шүүлтүүр нэмж байна. Үүний тусламжтайгаар бот чатын одоогийн байдлаас хамааран шаардлагатай аргуудад хандах болно.
  6. Бид тушаалууд болон мессежүүдийг шаардлагатай ботын аргуудтай холбох зохицуулагчийг нэмж өгдөг.
  7. Ботыг ажиллуулцгаая.

Бот төслийн бүтэц

Тохиромжтой болгох үүднээс бид өөрийн роботын код болон бусад холбогдох файлуудыг дараах бүтцэд хуваана.

  • bot.R — манай ботын үндсэн код
  • db_bot_function.R — мэдээллийн сантай ажиллах функц бүхий кодын блок
  • bot_methods.R — ботын аргын код
  • message_filters.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.

Орчны хувьсагчийг үүсгэх хэд хэдэн арга байдаг бөгөөд хамгийн энгийн нь файлд бичих явдал юм .Ренвирон.

Та тушаалыг ашиглан энэ файлыг үүсгэх эсвэл засах боломжтой file.edit(path.expand(file.path("~", ".Renviron"))). Үүнийг ажиллуулаад файлд нэг мөр нэмнэ:

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

Дараа нь файлаа хадгална уу .Ренвирон 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 аргыг бий болгосон:

  • эхлэх — Харилцах цонхыг эхлүүлэх
  • state — Одоогийн чатын төлөвийг авна уу
  • дахин тохируулах — Одоогийн чатын төлөвийг дахин тохируулах
  • enter_name — Бот таны нэрийг асууна
  • enter_age — Бот таны насыг асууна

арга start таны нэрийг асууж, чатын төлөвийг өөрчилнө хүлээх_нэр, өөрөөр хэлбэл нэрээ оруулахын тулд зогсох.

Дараа нь та нэрийг илгээж, энэ нь аргаар боловсруулагдана enter_name, bot тантай мэндчилж, хүлээн авсан нэрийг мэдээллийн санд бичиж, чатыг төлөв рүү шилжүүлнэ. хүлээх_нас.

Энэ үе шатанд робот таныг насаа оруулна гэж найдаж байна. Та насаа илгээнэ үү, бот мессежийг шалгана, хэрэв та дугаарын оронд мессеж илгээсэн бол дараахь зүйлийг хэлэх болно. Ты ввёл некорректные данные, введи число, мөн таныг мэдээллээ дахин оруулахыг хүлээх болно. Хэрэв та дугаар илгээсэн бол бот таны насыг хүлээн зөвшөөрч, хүлээн авсан өгөгдлийг мэдээллийн санд бичиж, танаас хүлээн авсан бүх өгөгдлийг тайлагнаж, чатын төлөвийг анхны байрлал руу нь буцаана. В 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_age.

Ажиллагчид

Ажиллагчидтай файлыг дуудна зохицуулагчид.Р, мөн дараах кодтой байна:

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

Үүний үр дүнд бид энэ роботыг авсан:
R хэл дээр телеграм бот бичих (4-р хэсэг): Боттой тууштай, логик яриа хэлцлийг бий болгох

Ямар ч үед тушаалыг ашиглан /state Бид командыг ашиглан одоогийн чатын төлөвийг асууж болно /reset чатыг анхны байдалд нь буцааж, харилцан яриаг дахин эхлүүлнэ үү.

дүгнэлт

Энэ нийтлэлд бид бот доторх мэдээллийн санг хэрхэн ашиглах, чатын төлөвийг бүртгэх замаар дараалсан логик харилцан яриаг хэрхэн бий болгох талаар олж мэдсэн.

Энэ тохиолдолд бид хамгийн энгийн жишээг авч үзсэн бөгөөд ингэснээр ийм роботуудыг бий болгох санааг ойлгоход хялбар байх болно; практик дээр та илүү төвөгтэй харилцан яриа үүсгэж болно.

Энэ цувралын дараагийн өгүүллээр бид бот хэрэглэгчдийн янз бүрийн аргыг ашиглах эрхийг хэрхэн хязгаарлах талаар сурах болно.

Эх сурвалж: www.habr.com

сэтгэгдэл нэмэх