add logic for render and send text type question

This commit is contained in:
Pavel 2024-09-05 17:29:13 +03:00
parent cf1518cfef
commit 18fab9828e
7 changed files with 119 additions and 17 deletions

@ -32,7 +32,7 @@ fn (mut bm BotManager) start_bot(bot models.TelegramIntegration) ! {
eprintln('already started: $bot.id')
return
}
tg_bot := tg_handle.new_tg_bot(bot.bot_token, bm.repo,bot.id)
tg_bot := tg_handle.new_tg_bot( bm.repo,bot)
bm.active_bots[bot.id] = tg_bot
println('started: $bot.id')
}

BIN
main.exe

Binary file not shown.

12
main.v

@ -63,8 +63,16 @@ fn main() {
spawn wc.start()
// tg_handle.new_tg_bot('7127966184:AAG1steOCH4wDvHRe9QcsXJPS4dWRyRYsqg',repo,5)
// tg_handle.new_tg_bot('6712573453:AAFqTOsgwe_j48ZQ1GzWKQDT5Nwr-SAWjz8',repo,4)
// tg_handle.new_tg_bot(repo,models.TelegramIntegration{
// id: 5
// quiz_id: 26357
// bot_token: '7127966184:AAG1steOCH4wDvHRe9QcsXJPS4dWRyRYsqg'
// })
// tg_handle.new_tg_bot(repo,models.TelegramIntegration{
// id: 4
// quiz_id: 26384
// bot_token: '6712573453:AAFqTOsgwe_j48ZQ1GzWKQDT5Nwr-SAWjz8'
// })
mut app := &models.App{}
mut integration_controllers := &controllers.IntegrationControllers{repo:repo}

@ -53,6 +53,7 @@ pub struct RespondentState {
lang string @[sql: 'lang']
contact string @[sql: 'contact']
finish bool @[sql: 'finish']
session string @[sql:'session']
}
@[table: 'telegram_integration_instance']

@ -81,6 +81,20 @@ pub fn (mut r Repo) finish_state(id i64) ! {
}
}
pub fn (r Repo) get_state_by_tg_quiz_id(tg_id int,quiz_id i64)!models.RespondentState {
result := sql r.pg_db {
select from models.RespondentState where quiz_id == quiz_id && telegram_id == tg_id && finish == false
}or{
return error('error getting state from db')
}
if result.len == 0{
return error('state not found')
}
return result[0]
}
// методы с question
// получение вопроса по id
pub fn (mut r Repo) get_question_by_id(id i64) !models.QuizQuestion {

@ -5,6 +5,7 @@ import repository
import time
import json
import models
import utils
pub struct TgBot {
pub mut:
@ -13,18 +14,20 @@ pub struct TgBot {
stop_ch chan int
bot_id i64
liner bool
quiz_id i64
}
// todo нужно наверное ограничить возврат пользователя на предыдущие вопросы, потому что храним только
// последние положение, а предыдущие не храним, наверное стоит потом с базой продумать
pub fn new_tg_bot(token string,repo repository.Repo,bot_id i64) &TgBot{
bot := vgram.new_bot(token)
pub fn new_tg_bot(repo repository.Repo,bot_data models.TelegramIntegration) &TgBot{
bot := vgram.new_bot(bot_data.bot_token)
mut b := &TgBot{
bot: bot
repo: repo
stop_ch: chan int{}
bot_id: bot_id
bot_id: bot_data.id
quiz_id: bot_data.quiz_id
}
spawn b.start()
return b
@ -63,6 +66,7 @@ fn (mut b TgBot) start() {
}
fn (mut b TgBot) start_handler(update vgram.Update) {
session := utils.generate_signature(b.quiz_id.str(),update.message.from.id.str())
chat_id_str := update.message.from.id.str()
// todo приветствие такое как дима писал надо
b.bot.send_message(chat_id: chat_id_str, text: 'Привет мир')
@ -90,11 +94,12 @@ fn (mut b TgBot) start_handler(update vgram.Update) {
b.bot.send_message(chat_id: chat_id_str, text: 'Ошибка при получении первого вопроса')
return
}
// todo работа со стейтами
state_id:=b.repo.create_state(models.RespondentState{
telegram_id: update.message.from.id
quiz_id: integration_data.quiz_id
state: 0
session: session
})or{
b.bot.send_message(chat_id: chat_id_str, text: 'Ошибка при сохранении данных респондента')
return
@ -105,10 +110,51 @@ fn (mut b TgBot) start_handler(update vgram.Update) {
fn (mut b TgBot) message_handler(update vgram.Update) {
if update.message.text !='/start' {
b.bot.send_message(
chat_id: update.message.from.id.str(),
text: 'Используйте команду /start для начала',
)
chat_id := update.message.from.id
chat_id_str := update.message.from.id.str()
state := b.repo.get_state_by_tg_quiz_id(chat_id,b.quiz_id)or{
b.bot.send_message(
chat_id: chat_id_str,
text: 'Используйте команду /start для начала',
)
return
}
current_state := b.repo.get_state(state.id)or{
b.bot.send_message(chat_id: chat_id_str, text: 'Ошибка при получении текущего состояния')
return
}
previous_question:= b.repo.get_question_by_id(current_state.state)or{
b.bot.send_message(chat_id: chat_id_str, text: 'Ошибка при получении предыдущего вопроса')
return
}
if previous_question.question_type !in [models.question_type_text.str(), models.question_type_file.str(), models.question_type_number.str(), models.question_type_result.str(), models.question_type_date.str()] {
b.bot.send_message(
chat_id: chat_id_str,
text: 'Используйте команду /start для начала',
)
return
}
if previous_question.question_type == models.question_type_text.str(){
mut message_text := update.message.text
if message_text != '' {
b.bot.send_message(
chat_id: chat_id_str,
text: 'Ответ должен содержать текст'
)
return
}
// todo отправка в answerer
println(message_text)
b.render_message(current_state.id,chat_id_str,previous_question)
return
}
}
}
@ -614,7 +660,16 @@ fn (mut b TgBot) render_varimg_question(state_id i64, chat_id_str string, questi
}
fn (mut b TgBot)render_text_question(state_id i64,chat_id_str string, question models.QuizQuestion, content models.QuizQuestionText){
b.bot.send_message(
chat_id: chat_id_str,
text: '*$question.title*\n\n${question.description}'+ if content.placeholder != '' { '\n\n${content.placeholder}' } else { '' },
parse_mode: 'Markdown'
)
b.repo.update_state(state_id, question.id) or {
b.bot.send_message(chat_id: chat_id_str, text: 'Ошибка при обновлении состояния респондента')
return
}
}
fn (mut b TgBot)render_date_question(state_id i64,chat_id_str string, question models.QuizQuestion, content models.QuizQuestionDate){
@ -673,10 +728,34 @@ fn (mut b TgBot)render_page_question(state_id i64,chat_id_str string, question m
)
}
b.repo.update_state(state_id, find_next_question_id(content.rule, models.CallbackData{
answer_id: '',
state_id: state_id,
})) or {
b.repo.update_state(state_id, question.id) or {
b.bot.send_message(chat_id: chat_id_str, text: 'Ошибка при обновлении состояния респондента')
return
}
}
fn (mut b TgBot)render_message(state_id i64,chat_id_str string, question models.QuizQuestion){
mut keyboard := []vgram.InlineKeyboardButton{}
callback_data_json := json.encode(models.CallbackData{
state_id: state_id
})
button := vgram.InlineKeyboardButton{
text: "нажмите на кнопку чтобы продолжить опрос"
callback_data: callback_data_json
}
keyboard << button
reply_markup := vgram.InlineKeyboardMarkup{
inline_keyboard: [keyboard]
}
b.bot.send_message(
chat_id: chat_id_str,
parse_mode: 'Markdown',
reply_markup: json.encode(reply_markup)
)
b.repo.update_state(state_id,question.id)or{
b.bot.send_message(chat_id: chat_id_str, text: 'Ошибка при обновлении состояния респондента')
return
}

@ -3,9 +3,9 @@ module utils
import crypto.md5
import time
fn generate_signature(quizID i64,respondent_id i64) string {
pub fn generate_signature(quizID string,respondent_id string) string {
mut u := time.now().unix().str()
u += quizID.str()+ respondent_id.str()
u += quizID + respondent_id
hash := md5.hexhash(u)
return hash[..20]
}