From 193dabe805f1cb3466e686063e1f8333aff40fbd Mon Sep 17 00:00:00 2001 From: Kirill Kirilenko Date: Sat, 19 Nov 2022 21:42:18 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9D=D0=B0=D1=80=D0=B0=D0=B1=D0=BE=D1=82?= =?UTF-8?q?=D0=BA=D0=B8=20=D0=BF=D0=BE=20=D0=BC=D0=B0=D1=88=D0=B8=D0=BD?= =?UTF-8?q?=D0=B0=D0=BC=20=D1=81=D0=BE=D1=81=D1=82=D0=BE=D1=8F=D0=BD=D0=B8?= =?UTF-8?q?=D1=8F.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Bot.cpp | 35 ++++++----- Bot.h | 1 + BotSession.cpp | 31 +++++++--- BotSession.h | 11 ++-- CourtApi.cpp | 77 +++++++++++++---------- CourtApi.h | 33 ++++++++-- Dialog.cpp | 13 +--- Dialog.h | 7 +-- DialogHelpers.h | 10 ++- ISRG_X1.pem | 31 ++++++++++ SubscribeCaseDialog.cpp | 132 ++++++++++++++++++++++++++++++++++++---- SubscribeCaseDialog.h | 7 ++- main.cpp | 13 ++-- 13 files changed, 293 insertions(+), 108 deletions(-) create mode 100644 ISRG_X1.pem diff --git a/Bot.cpp b/Bot.cpp index 97758b4..41f0506 100644 --- a/Bot.cpp +++ b/Bot.cpp @@ -94,31 +94,30 @@ void Bot::processUpdate(const banana::api::update_t& update) else LOG(bot, "incoming message: user={} (not text)", userId); - auto sessionIt = sessions_.find(userId); - if (sessionIt == sessions_.end()) - { - bool ok; - std::tie(sessionIt, ok) = - sessions_.emplace(std::piecewise_construct, std::forward_as_tuple(userId), - std::forward_as_tuple(agent_, userId)); - } - sessionIt->second.processMessage(*update.message); + auto& session = getOrCreateSession(userId); + session.processMessage(*update.message); } else if (update.callback_query) { banana::integer_t userId = update.callback_query->from.id; LOG(bot, "incoming callback query: user={} data='{}'", userId, *update.callback_query->data); - auto sessionIt = sessions_.find(userId); - if (sessionIt == sessions_.end()) - { - bool ok; - std::tie(sessionIt, ok) = - sessions_.emplace(std::piecewise_construct, std::forward_as_tuple(userId), - std::forward_as_tuple(agent_, userId)); - } - sessionIt->second.processCallbackQuery(*update.callback_query); + auto& session = getOrCreateSession(userId); + session.processCallbackQuery(*update.callback_query); } else LOG(bot, "skip unknown update type"); } + +BotSession& Bot::getOrCreateSession(banana::integer_t userId) +{ + auto sessionIt = sessions_.find(userId); + if (sessionIt == sessions_.end()) + { + bool ok; + std::tie(sessionIt, ok) = + sessions_.emplace(std::piecewise_construct, std::forward_as_tuple(userId), + std::forward_as_tuple(agent_, userId, storage_)); + } + return sessionIt->second; +} diff --git a/Bot.h b/Bot.h index bd609dd..432eb5d 100644 --- a/Bot.h +++ b/Bot.h @@ -25,6 +25,7 @@ private: void getUpdates(); void processUpdate(const banana::api::update_t& update); + BotSession& getOrCreateSession(banana::integer_t userId); LocalStorage& storage_; bool& terminationFlag_; diff --git a/BotSession.cpp b/BotSession.cpp index 8a2dc11..45453c5 100644 --- a/BotSession.cpp +++ b/BotSession.cpp @@ -1,13 +1,16 @@ #include "BotSession.h" #include "Logger.h" +#include "Storage.h" #include "SubscribeCaseDialog.h" #include #include -BotSession::BotSession(banana::agent::beast_callback& agent, banana::integer_t userId) - : agent_(agent), userId_(userId) +BotSession::BotSession(banana::agent::beast_callback& agent, + banana::integer_t userId, + LocalStorage& storage) + : agent_(agent), userId_(userId), storage_(storage) { LOG(session, "new session created for user {}", userId_); } @@ -20,9 +23,9 @@ void BotSession::processMessage(const banana::api::message_t& message) { auto text = *message.text; if (text == "/start") - processStartCommand(message); + processStartCommand(); else if (text == "/stop") - processStopCommand(message); + processStopCommand(); else if (text == "/subscribe_case") activeDialog_ = makeDialog(); else if (activeDialog_) @@ -30,13 +33,13 @@ void BotSession::processMessage(const banana::api::message_t& message) if (activeDialog_->processMessage(message)) { // TODO - processStartCommand(message); + processStartCommand(); } } else { // TODO - processStartCommand(message); + processStartCommand(); } } else @@ -45,9 +48,21 @@ void BotSession::processMessage(const banana::api::message_t& message) void BotSession::processCallbackQuery(const banana::api::callback_query_t& query) { + if (query.data) + { + if (activeDialog_) + { + if (activeDialog_->processCallbackQuery(query)) + processStartCommand(); + } + else + LOGE(session, "skip callback query, because there is no active dialog"); + } + else + LOGE(session, "skip callback query without data"); } -void BotSession::processStartCommand(const banana::api::message_t& message) +void BotSession::processStartCommand() { activeDialog_.reset(); @@ -59,7 +74,7 @@ void BotSession::processStartCommand(const banana::api::message_t& message) [](const banana::expected& message) {}); } -void BotSession::processStopCommand(const banana::api::message_t& message) +void BotSession::processStopCommand() { activeDialog_.reset(); } diff --git a/BotSession.h b/BotSession.h index 494b15c..a12f9c7 100644 --- a/BotSession.h +++ b/BotSession.h @@ -1,6 +1,8 @@ #ifndef COURT_MONITOR_BOT_SESSION_H #define COURT_MONITOR_BOT_SESSION_H +#include "Storage.h" + #include #include #include @@ -12,7 +14,7 @@ class Dialog; class BotSession final { public: - BotSession(banana::agent::beast_callback& agent, banana::integer_t userId); + BotSession(banana::agent::beast_callback& agent, banana::integer_t userId, LocalStorage& storage); ~BotSession(); void processMessage(const banana::api::message_t& message); @@ -22,14 +24,15 @@ private: template std::unique_ptr makeDialog() { - return std::make_unique(agent_, userId_); + return std::make_unique(agent_, userId_, storage_); } - void processStartCommand(const banana::api::message_t& message); - void processStopCommand(const banana::api::message_t& message); + void processStartCommand(); + void processStopCommand(); banana::agent::beast_callback& agent_; banana::integer_t userId_; + LocalStorage& storage_; std::unique_ptr activeDialog_; }; diff --git a/CourtApi.cpp b/CourtApi.cpp index d1a519d..5a15a3f 100644 --- a/CourtApi.cpp +++ b/CourtApi.cpp @@ -1,5 +1,7 @@ #include "CourtApi.h" +#include "Logger.h" + #include #include @@ -9,7 +11,6 @@ #include #include -#include #include const char* serverDomain = "mirsud.spb.ru"; @@ -24,15 +25,16 @@ ssl_stream connect(boost::asio::io_context& asioContext, const std::string& host sslContext.set_verify_mode(boost::asio::ssl::verify_peer | boost::asio::ssl::verify_fail_if_no_peer_cert); sslContext.set_default_verify_paths(); + sslContext.load_verify_file("ISRG_X1.pem"); boost::certify::enable_native_https_server_verification(sslContext); ssl_stream stream(asioContext, sslContext); static boost::asio::ip::tcp::resolver resolver(asioContext); auto const results = resolver.resolve(hostname, "https"); + boost::beast::get_lowest_layer(stream).connect(results); boost::certify::set_server_hostname(stream, hostname); boost::certify::sni_hostname(stream, hostname); - boost::beast::get_lowest_layer(stream).connect(results); stream.handshake(boost::asio::ssl::stream_base::client); return stream; @@ -56,14 +58,11 @@ std::pair get(ssl_stream& stream, request.body() = std::move(*payload); } - std::cout << "tx: " << request << std::endl; - boost::beast::http::write(stream, request); boost::beast::http::response response; boost::beast::flat_buffer buffer; boost::beast::http::read(stream, buffer, response); - std::cout << "rx: " << response << std::endl; return {response.base().result_int(), response.body()}; } @@ -83,27 +82,58 @@ nlohmann::json getResults(ssl_stream& stream, const std::string_view& uuid) fmt::format("failed to retrieve JSON (server returned code {})", status)); } -nlohmann::json getCaseDetails(boost::asio::io_context& asioContext, - int courtId, - const std::string_view& caseNumber) +CaseDetails getCaseDetails(boost::asio::io_context& asioContext, const std::string_view& caseNumber) { ssl_stream stream = connect(asioContext, serverDomain); int status; std::string result; std::tie(status, result) = - get(stream, serverDomain, - fmt::format("/cases/api/detail/?id={}&court_site_id={}", caseNumber, courtId)); + get(stream, serverDomain, fmt::format("/cases/api/detail/?id={}", caseNumber)); if (status == 200) { auto uuid = nlohmann::json::parse(result).at("id").get(); - for (int i = 0; i < 10; i++) + for (int i = 0; i < 5; i++) { - auto results = getResults(stream, uuid); - bool finished = results.at("finished").get(); - if (finished) - return results.at("result"); + auto response = getResults(stream, uuid); + if (response.at("finished").get()) + { + auto& results = response.at("result"); + LOG(court, results.dump()); + + CaseDetails details; + details.id = results["id"].get(); + details.courtNumber = results["court_number"].get(); + details.name = results["name"].get(); + details.description = results["description"].get(); + details.url = + fmt::format("https://{}{}", serverDomain, results["url"].get()); + + details.districtName = results["district_name"].get(); + details.judgeName = results["judge"].get(); + + for (const auto& participant : results["participants"]) + { + CaseParticipant p; + p.title = participant["title"].get(); + p.name = participant["name"].get(); + details.participants.push_back(std::move(p)); + } + + for (const auto& obj : results["history"]) + { + CaseHistoryItem item; + item.date = obj.at("date").get(); + item.time = obj.at("time").get(); + item.status = obj.at("status").get(); + item.publishDate = obj.at("publish_date").get(); + item.publishTime = obj.at("publish_time").get(); + details.history.push_back(std::move(item)); + } + + return details; + } else std::this_thread::sleep_for(std::chrono::seconds(1)); } @@ -113,20 +143,3 @@ nlohmann::json getCaseDetails(boost::asio::io_context& asioContext, throw std::runtime_error( fmt::format("failed to retrieve JSON (server returned code {})", status)); } - -std::vector parseHistory(const nlohmann::json& details) -{ - std::vector items; - const auto& history = details.at("history"); - for (const auto& obj : history) - { - CaseHistoryItem item; - item.date = obj.at("date").get(); - item.time = obj.at("time").get(); - item.status = obj.at("status").get(); - item.publishDate = obj.at("publish_date").get(); - item.publishTime = obj.at("publish_time").get(); - items.push_back(std::move(item)); - } - return items; -} diff --git a/CourtApi.h b/CourtApi.h index 970e8c0..2152981 100644 --- a/CourtApi.h +++ b/CourtApi.h @@ -9,6 +9,12 @@ #include #include +struct CaseParticipant +{ + std::string title; + std::string name; +}; + struct CaseHistoryItem { std::string date; @@ -18,12 +24,29 @@ struct CaseHistoryItem std::string publishTime; }; -nlohmann::json findCases(boost::asio::io_context& asioContext, const std::string_view& name); +struct CaseDetails +{ + std::string id; + std::string courtNumber; + std::string name; + std::string description; + std::string url; -nlohmann::json getCaseDetails(boost::asio::io_context& asioContext, - int courtId, - const std::string_view& caseNumber); + std::string districtName; + std::string judgeName; + std::vector participants; -std::vector parseHistory(const nlohmann::json& details); + std::string status; + std::vector history; + + std::string createdDate; + std::string acceptedDate; + std::string judicialUid; +}; + +std::vector findCases(boost::asio::io_context& asioContext, + const std::string_view& name); + +CaseDetails getCaseDetails(boost::asio::io_context& asioContext, const std::string_view& caseNumber); #endif // COURT_MONITOR_COURT_API_H diff --git a/Dialog.cpp b/Dialog.cpp index 1db9e6c..7f69b98 100644 --- a/Dialog.cpp +++ b/Dialog.cpp @@ -2,8 +2,7 @@ #include "Logger.h" -Dialog::Dialog(banana::agent::beast_callback& agent, banana::integer_t userId, const char* name) - : agent_(agent), userId_(userId), name_(name) +Dialog::Dialog(banana::integer_t userId, const char* name) : userId_(userId), name_(name) { LOG(dialog, "{} dialog created for user {}", name_, userId_); } @@ -12,13 +11,3 @@ Dialog::~Dialog() { LOG(dialog, "{} dialog for user {} destroyed", name_, userId_); } - -banana::agent::beast_callback& Dialog::getAgent() const -{ - return agent_; -} - -banana::integer_t Dialog::getUserId() const -{ - return userId_; -} diff --git a/Dialog.h b/Dialog.h index bd140a1..393ff24 100644 --- a/Dialog.h +++ b/Dialog.h @@ -1,25 +1,20 @@ #ifndef COURT_MONITOR_DIALOG_H #define COURT_MONITOR_DIALOG_H -#include #include #include class Dialog { public: - Dialog(banana::agent::beast_callback& agent, banana::integer_t userId, const char* name); + Dialog(banana::integer_t userId, const char* name); virtual ~Dialog(); - [[nodiscard]] banana::agent::beast_callback& getAgent() const; - [[nodiscard]] banana::integer_t getUserId() const; - // Возвращают true, если диалог завершен. virtual bool processMessage(const banana::api::message_t& message) = 0; virtual bool processCallbackQuery(const banana::api::callback_query_t& query) = 0; private: - banana::agent::beast_callback& agent_; banana::integer_t userId_; const char* name_; }; diff --git a/DialogHelpers.h b/DialogHelpers.h index ff10612..e557e66 100644 --- a/DialogHelpers.h +++ b/DialogHelpers.h @@ -2,6 +2,7 @@ #define COURT_MONITOR_DIALOG_HELPERS_H #include "Logger.h" +#include "Storage.h" #include @@ -13,8 +14,13 @@ namespace statechart = boost::statechart; template struct StateMachine : public statechart::state_machine { - explicit StateMachine(Dialog& dialog) : dialog(dialog) {} - Dialog& dialog; + explicit StateMachine(banana::agent::beast_callback& agent, banana::integer_t userId) + : agent(agent), userId(userId) + { + } + + banana::agent::beast_callback& agent; + banana::integer_t userId; }; struct BasicState diff --git a/ISRG_X1.pem b/ISRG_X1.pem new file mode 100644 index 0000000..b85c803 --- /dev/null +++ b/ISRG_X1.pem @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw +TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh +cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4 +WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu +ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY +MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc +h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+ +0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U +A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW +T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH +B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC +B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv +KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn +OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn +jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw +qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI +rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq +hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL +ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ +3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK +NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5 +ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur +TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC +jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc +oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq +4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA +mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d +emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc= +-----END CERTIFICATE----- diff --git a/SubscribeCaseDialog.cpp b/SubscribeCaseDialog.cpp index 5c82fe2..2366ca9 100644 --- a/SubscribeCaseDialog.cpp +++ b/SubscribeCaseDialog.cpp @@ -5,10 +5,13 @@ #include "Logger.h" #include +#include #include #include +#include + namespace { // clang-format off @@ -17,6 +20,7 @@ namespace { struct WaitingForInput; struct GettingCaseDetails; struct WaitingForConfirmation; +struct Subscribed; // События struct CaseDetailsFetched : statechart::event { }; @@ -28,7 +32,12 @@ struct SubscriptionConfirmed : statechart::event { }; struct SubscribeCaseStateMachine : StateMachine { - using StateMachine::StateMachine; + SubscribeCaseStateMachine(banana::agent::beast_callback& agent, long userId, LocalStorage& storage) + : StateMachine(agent, userId), storage(storage) + { + } + LocalStorage& storage; + std::string caseNumber; }; namespace { @@ -39,24 +48,122 @@ struct WaitingForInput : State explicit WaitingForInput(const my_context& ctx) : State(ctx, "WaitingForInput") { - auto& dialog = context().dialog; - std::string text = "Введите номер дела"; - banana::api::send_message(dialog.getAgent(), - {.chat_id = dialog.getUserId(), .text = std::move(text)}, - [](auto) {}); + auto& machine = context(); + std::string text = "Введите номер дела..."; + banana::api::send_message(machine.agent, + {.chat_id = machine.userId, .text = std::move(text)}, [](auto) {}); } - statechart::result react(const NewMessageEvent& event) { return transit(); } + statechart::result react(const NewMessageEvent& event) + { + auto& machine = context(); + const std::regex rex(R"(\d-(?:\d+)/(?:\d){4}-(?:\d+))"); + std::smatch captures; + if (std::regex_match(*event.message.text, captures, rex)) + { + machine.caseNumber = *event.message.text; + return transit(); + } + else + { + std::string text = + "Некорректный формат номера дела!\n" + "Попробуйте еще раз."; + banana::api::send_message( + machine.agent, {.chat_id = machine.userId, .text = std::move(text)}, [](auto) {}); + return discard_event(); + } + } }; -struct GettingCaseDetails : State +struct GettingCaseDetails : State { - explicit GettingCaseDetails(const my_context& ctx) : State(ctx, "GettingCaseDetails") {} + using reactions = statechart::custom_reaction; + + explicit GettingCaseDetails(const my_context& ctx) : State(ctx, "GettingCaseDetails") + { + auto& machine = context(); + boost::asio::io_context ioContext; + + try + { + auto details = getCaseDetails(ioContext, machine.caseNumber); + std::string text; + fmt::format_to(std::back_inserter(text), "Проверьте информацию:\n{}\n", details.name); + for (const auto& participant : details.participants) + fmt::format_to(std::back_inserter(text), "{}: {}\n", participant.title, + participant.name); + fmt::format_to(std::back_inserter(text), "Судья: {}", details.judgeName); + + banana::api::inline_keyboard_markup_t keyboard; + keyboard.inline_keyboard.resize(1); + keyboard.inline_keyboard[0].resize(2); + + keyboard.inline_keyboard[0][0].text = "Верно"; + keyboard.inline_keyboard[0][0].callback_data = "yes"; + keyboard.inline_keyboard[0][1].text = "Отмена"; + keyboard.inline_keyboard[0][1].callback_data = "no"; + + banana::api::send_message( + machine.agent, + {.chat_id = machine.userId, .text = std::move(text), .reply_markup = keyboard}, + [](auto) {}); + + post_event(CaseDetailsFetched()); + } + catch (const std::exception& e) + { + LOGE(dialog, e.what()); + // TODO ??? + } + } + + statechart::result react(const CaseDetailsFetched& event) + { + return transit(); + } }; struct WaitingForConfirmation : State { + using reactions = statechart::custom_reaction; + explicit WaitingForConfirmation(const my_context& ctx) : State(ctx, "WaitingForConfirmation") {} + + statechart::result react(const NewCallbackQueryEvent& event) + { + auto& machine = context(); + if (event.query.data) + { + if (event.query.message) + banana::api::edit_message_reply_markup( + machine.agent, + {.chat_id = event.query.message->chat.id, + .message_id = event.query.message->message_id}, + [](banana::expected> result) + { + if (!result) + LOGE(dialog, result.error()); + }); + + if (*event.query.data == "yes") + { + // TODO + + return transit(); + } + else if (*event.query.data == "no") + { + return transit(); + } + } + return discard_event(); + } +}; + +struct Subscribed : State +{ + explicit Subscribed(const my_context& ctx) : State(ctx, "Subscribed") {} }; } // namespace @@ -64,9 +171,10 @@ struct WaitingForConfirmation : State(*this)) + banana::integer_t userId, + LocalStorage& storage) + : Dialog(userId, "SubscribeCase"), + machine_(std::make_unique(agent, userId, storage)) { machine_->initiate(); } diff --git a/SubscribeCaseDialog.h b/SubscribeCaseDialog.h index 80cf4c8..c936f7d 100644 --- a/SubscribeCaseDialog.h +++ b/SubscribeCaseDialog.h @@ -2,13 +2,18 @@ #define COURT_MONITOR_SUBSCRIBE_CASE_DIALOG_H #include "Dialog.h" +#include "Storage.h" + +#include struct SubscribeCaseStateMachine; class SubscribeCaseDialog : public Dialog { public: - SubscribeCaseDialog(banana::agent::beast_callback& agent, banana::integer_t userId); + SubscribeCaseDialog(banana::agent::beast_callback& agent, + banana::integer_t userId, + LocalStorage& storage); ~SubscribeCaseDialog() override; bool processMessage(const banana::api::message_t& message) override; diff --git a/main.cpp b/main.cpp index a69fd2e..4324d0c 100644 --- a/main.cpp +++ b/main.cpp @@ -27,14 +27,11 @@ void processAllSubscriptions(LocalStorage& storage, Bot& bot) for (auto& counter : subscription.counters) { LOG(main, "** Processing case {}", counter.caseNumber); - auto details = getCaseDetails(asioContext, counter.courtId, counter.caseNumber); - LOG(main, details.dump()); - auto url = details["url"].get(); - - auto history = parseHistory(details); - for (std::size_t i = counter.value; i < history.size(); i++) - bot.notifyUser(subscription.userId, counter.caseNumber, url, history[i]); - counter.value = history.size(); + auto details = getCaseDetails(asioContext, counter.caseNumber); + for (std::size_t i = counter.value; i < details.history.size(); i++) + bot.notifyUser(subscription.userId, counter.caseNumber, details.url, + details.history[i]); + counter.value = details.history.size(); } } catch (const std::exception& e)