Kulemba telegalamu bot mu R (gawo 4): Kupanga zokambirana zosasinthika, zomveka ndi bot

Ngati mudawerengapo kale nkhani zitatu kuchokera mndandandawu, ndiye kuti mukudziwa kale kulemba ma telegram bots ndi kiyibodi.

M'nkhaniyi, tiphunzira momwe tingalembere bot yomwe idzakhalabe ndi zokambirana zokhazikika. Iwo. Bot idzakufunsani mafunso ndikudikirira kuti mulowetse zina. Kutengera deta yomwe mwalowetsa, bot idzachitapo kanthu.

Komanso m'nkhaniyi tiphunzira momwe tingagwiritsire ntchito deta pansi pa bot bot, mu chitsanzo chathu chidzakhala SQLite, koma mungagwiritse ntchito DBMS ina iliyonse. Ndinalemba mwatsatanetsatane za kuyanjana ndi ma database mu chilankhulo cha R nkhaniyi.

Kulemba telegalamu bot mu R (gawo 4): Kupanga zokambirana zosasinthika, zomveka ndi bot

Zolemba zonse zakuti "Kulemba telegalamu bot mu R"

  1. Timapanga bot ndikugwiritsa ntchito kutumiza mauthenga pa telegalamu
  2. Onjezani thandizo lamalamulo ndi zosefera za mauthenga ku bot
  3. Momwe mungawonjezere thandizo la kiyibodi ku bot
  4. Kupanga zokambirana zokhazikika, zomveka ndi bot

Zamkatimu

Ngati mukufuna kusanthula deta, mungakhale ndi chidwi changa uthengawo и Youtube njira. Zambiri mwazomwe zimaperekedwa ku chilankhulo cha R.

  1. Mau oyamba
  2. Njira yomanga bot
  3. Bot dongosolo la polojekiti
  4. Bot config
  5. Pangani kusintha kwa chilengedwe
  6. Kupanga database
  7. Kulemba ntchito zogwirira ntchito ndi database
  8. Njira za bot
  9. Zosefera mauthenga
  10. Ogwira ntchito
  11. Bot kukhazikitsa kodi
  12. Pomaliza

Mau oyamba

Kuti bot ikufunseni deta kuchokera kwa inu ndikudikirira kuti mulowetse chidziwitso chilichonse, muyenera kulemba zomwe zikuchitika panopa. Njira yabwino yochitira izi ndikugwiritsa ntchito mtundu wina wa database, monga SQLite.

Iwo. Mfundo zake zidzakhala motere. Timatcha njira ya bot, ndipo bot imapempha zambiri kuchokera kwa ife, ndipo pa sitepe iliyonse imadikirira kuti chidziwitsochi chilowetsedwe ndikuchiyang'ana.

Tidzalemba bot yosavuta kwambiri, choyamba idzafunsa dzina lanu, ndiye zaka zanu, ndikusunga zomwe mwalandira ku database. Pofunsa zaka, idzayang'ana kuti deta yomwe yalowa ndi nambala osati malemba.

Kukambitsirana kosavuta koteroko kudzakhala ndi zigawo zitatu zokha:

  1. chiyambi ndi chikhalidwe chachibadwa cha bot, momwe sichimayembekezera chidziwitso chilichonse kuchokera kwa inu
  2. wait_name - tchulani momwe bot imadikirira kuti dzina lilowe
  3. wait_age ndi gawo lomwe bot imadikirira kuti zaka zanu zilowe, chiwerengero cha zaka zonse.

Njira yomanga bot

M'nkhaniyi, tipanga bot sitepe ndi sitepe; ndondomeko yonseyi ikhoza kuwonetsedwa motere:
Kulemba telegalamu bot mu R (gawo 4): Kupanga zokambirana zosasinthika, zomveka ndi bot

  1. Timapanga bot config momwe tidzasungirako zina. Kwa ife, chizindikiro cha bot, ndi njira yopita ku fayilo ya database.
  2. Timapanga kusintha kwa chilengedwe komwe njira yopita ku polojekiti ndi bot idzasungidwa.
  3. Timapanga database yokha, ndi ntchito zingapo kuti bot igwirizane nayo.
  4. Timalemba njira za bot, i.e. ntchito zomwe zidzagwire.
  5. Kuonjezera zosefera mauthenga. Mothandizidwa ndi zomwe bot idzapeza njira zofunika, malingana ndi momwe macheza akuyendera.
  6. Timawonjezera othandizira omwe adzalumikiza malamulo ndi mauthenga ndi njira zofunikira za bot.
  7. Tiyeni tiyambitse bot.

Bot dongosolo la polojekiti

Kuti zitheke, tigawa khodi ya bot yathu, ndi mafayilo ena okhudzana nawo, muzotsatira zotsatirazi.

  • boti.R - nambala yayikulu ya bot yathu
  • db_bot_function.R - chipika cha code chokhala ndi ntchito zogwirira ntchito ndi database
  • bot_methods.R - kodi njira za bot
  • message_filters.R - zosefera uthenga
  • ogwira ntchito.R - othandizira
  • config.cfg - bot config
  • create_db_data.sql - Zolemba za SQL zopangira tebulo lokhala ndi macheza ochezera pankhokwe
  • create_db_state.sql - SQL script popanga tebulo la zomwe zikuchitika pano mu database
  • bot.db - bot database

Mutha kuwona projekiti yonse ya bot, kapena скачать kuchokera mwa posungira pa GitHub.

Bot config

Tidzagwiritsa ntchito mwachizolowezi ngati config ine file, mawonekedwe otsatirawa:

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

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

Mu config timalemba chizindikiro cha bot ndi njira yopita ku database, i.e. ku fayilo ya bot.db; tidzapanga fayilo yokha mu sitepe yotsatira.

Kwa bots zovuta kwambiri, mutha kupanga ma configs ovuta kwambiri, kupatulapo, sikoyenera kulemba ini config, mungagwiritse ntchito mtundu wina uliwonse kuphatikizapo JSON.

Pangani kusintha kwa chilengedwe

Pa PC iliyonse, chikwatu chomwe chili ndi projekiti ya bot chikhoza kupezeka m'madongosolo osiyanasiyana komanso pama drive osiyanasiyana, kotero mu code njira yopita ku chikwatu cha polojekiti idzakhazikitsidwa kudzera pakusintha kwachilengedwe. TG_BOT_PATH.

Pali njira zingapo zopangira kusintha kwa chilengedwe, chosavuta ndikulemba mufayilo .Renviron.

Mutha kupanga kapena kusintha fayiloyi pogwiritsa ntchito lamulo file.edit(path.expand(file.path("~", ".Renviron"))). Chitani ndikuwonjezera mzere umodzi ku fayilo:

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

Kenako sungani fayiloyo .Renviron ndikuyambitsanso RStudio.

Kupanga database

Chotsatira ndikupanga database. Tidzafunika 2 tables:

  • chat_data - zomwe bot idapempha kwa wogwiritsa ntchito
  • chat_state - momwe macheza onse alipo

Mutha kupanga matebulo awa pogwiritsa ntchito funso la 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
);

Ngati mudatsitsa pulojekiti ya bot kuchokera GitHub, kenako kuti mupange database mutha kugwiritsa ntchito nambala iyi mu 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'))

Kulemba ntchito zogwirira ntchito ndi database

Tili ndi kale fayilo yokonzekera ndipo nkhokwe yapangidwa. Tsopano muyenera kulemba ntchito kuti muwerenge ndi kulemba deta ku database iyi.

Ngati mudatsitsa pulojekitiyi kuchokera GitHub, ndiye inu mukhoza kupeza ntchito mu wapamwamba db_bot_function.R.

Code yogwira ntchito ndi 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]])

}

Tinapanga ntchito 4 zosavuta:

  • get_state() - pezani macheza apano kuchokera kunkhokwe
  • set_state() - lembani zomwe zikuchitika panopa ku database
  • get_chat_data() - kulandira deta yotumizidwa ndi wogwiritsa ntchito
  • set_chat_data() - lembani zomwe mwalandira kuchokera kwa wogwiritsa ntchito

Ntchito zonse ndi zophweka, mwina amawerenga deta kuchokera ku database pogwiritsa ntchito lamulo dbGetQuery(), kapena kudzipereka UPSERT ntchito (kusintha zomwe zilipo kapena kulemba zatsopano ku database), pogwiritsa ntchito ntchitoyi dbExecute().

Ma syntax a ntchito ya UPSERT ali motere:

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

Iwo. m'munda wa matebulo athu chat_id ili ndi cholepheretsa chapadera ndipo ndiye fungulo loyambirira la matebulo. Poyamba, timayesa kuwonjezera zambiri patebulo, ndipo timapeza zolakwika ngati deta ya macheza apano ilipo kale, momwemo timangosintha zambiri zamacheza awa.

Kenako, tidzagwiritsa ntchito izi munjira za bot ndi zosefera.

Njira za bot

Chotsatira pomanga bot yathu ndikupanga njira. Ngati mudatsitsa pulojekitiyi kuchokera GitHub, ndiye njira zonse zili mu fayilo bot_methods.R.

Bot njira kodi

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

}

Tinapanga njira 5:

  • kuyamba - Yambitsani kukambirana
  • state - Pezani macheza apano
  • konzanso - Bwezeretsaninso macheza omwe alipo
  • enter_name - Bot imakufunsani dzina lanu
  • enter_age - Bot imakufunsani zaka zanu

Njira start akufunsa dzina lanu, ndikusintha macheza kukhala wait_name,ndi. kuyimirira polemba dzina lanu.

Kenako, mumatumiza dzinalo ndipo limakonzedwa ndi njira enter_name, bot ikupatsani moni, imalemba dzina lolandilidwa mu database, ndikusintha macheza ku boma dikirani_zaka.

Pakadali pano, bot ikuyembekeza kuti mulowe m'zaka zanu. Mumatumiza zaka zanu, bot imayang'ana uthengawo, ngati mwatumiza mameseji m'malo mwa nambala, imati: Ты ввёл некорректные данные, введи число, ndikudikirira kuti mulowetsenso deta yanu. Ngati munatumiza nambala, bot idzanena kuti yavomereza zaka zanu, lembani zomwe mwalandira ku database, lipoti zonse zomwe mwalandira kuchokera kwa inu ndikubwezeretsani chikhalidwe cha macheza ku malo ake oyambirira, i.e. V start.

Poyimba njira state mutha kupempha macheza apano nthawi iliyonse, ndikugwiritsa ntchito reset bwezerani macheza kukhala momwe adakhalira.

Zosefera mauthenga

Kwa ife, ichi ndi chimodzi mwazinthu zofunika kwambiri pomanga bot. Ndi chithandizo cha zosefera mauthenga kuti bot idzamvetsetsa zomwe ikuyembekezera kuchokera kwa inu ndi momwe iyenera kusinthidwa.

Mu polojekiti pa GitHub zosefera zimalembetsedwa mufayilo message_filters.R.

Khodi yosefera uthenga:

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

Muzosefera timagwiritsa ntchito zomwe zidalembedwa kale get_state(), kuti mufunse momwe macheza akuyendera. Izi zimafuna mkangano umodzi wokha, id yochezera.

Chosefera chotsatira wait_name amakonza mauthenga pamene macheza ali mu chikhalidwe wait_name, ndipo molingana ndi fyuluta dikirani_zaka amakonza mauthenga pamene macheza ali mu chikhalidwe wait_age.

Ogwira ntchito

Fayilo yokhala ndi othandizira imatchedwa ogwira ntchito.R, ndipo ili ndi code iyi:

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

Choyamba timapanga owongolera omwe angakuthandizeni kuyendetsa njira zoyambira kukambirana, kukonzanso, ndikufunsa momwe zilili.

Kenako, timapanga 2 osamalira mauthenga pogwiritsa ntchito zosefera zomwe zidapangidwa kale, ndikuwonjezera fyuluta kwa iwo !MessageFilters$command, kotero kuti titha kugwiritsa ntchito malamulo pamacheza aliwonse.

Bot kukhazikitsa kodi

Tsopano tili ndi zonse zokonzeka kuyambitsa, nambala yayikulu yoyambitsa bot ili mufayilo boti.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()

Zotsatira zake, tapeza bot iyi:
Kulemba telegalamu bot mu R (gawo 4): Kupanga zokambirana zosasinthika, zomveka ndi bot

Nthawi iliyonse pogwiritsa ntchito lamulo /state titha kufunsa momwe macheza apano, ndikugwiritsa ntchito lamulo /reset bwezerani machezawo momwe adakhalira ndikuyambanso kukambirana.

Pomaliza

M'nkhaniyi, tawona momwe tingagwiritsire ntchito nkhokwe mkati mwa bot, ndi momwe tingapangire zokambirana zotsatizana pojambula macheza.

Pankhaniyi, tidayang'ana chitsanzo choyambirira, kuti zikhale zosavuta kuti mumvetsetse lingaliro la kupanga ma bots otere; pochita, mutha kupanga zokambirana zovuta kwambiri.

M'nkhani yotsatirayi, tiphunzira momwe tingaletsere ufulu wa ogwiritsa ntchito bot kugwiritsa ntchito njira zake zosiyanasiyana.

Source: www.habr.com

Kuwonjezera ndemanga