feat(tgbot): add title menu

This commit is contained in:
Kirill 2025-12-20 01:19:56 +03:00
parent f045eb22b2
commit da40d7df49
7 changed files with 244 additions and 11 deletions

View file

@ -25,6 +25,7 @@ public:
// Асинхронный метод: получить список тайтлов пользователя
pplx::task<std::vector<BotStructs::Title>> fetchUserTitlesAsync(const std::string& userId);
pplx::task<BotStructs::Title> fetchTitleAsync(const std::string& userId, int64_t titleId);
private:
std::shared_ptr<org::openapitools::client::api::ApiConfiguration> apiconfiguration;
@ -32,4 +33,7 @@ private:
std::shared_ptr<org::openapitools::client::api::DefaultApi> api;
nyanimed::AuthImpersonationClient authClient;
static BotStructs::Title mapTitleToBotTitle(
const std::shared_ptr<org::openapitools::client::model::Title>& titleModel);
};

View file

@ -114,4 +114,103 @@ pplx::task<std::vector<BotStructs::Title>> BotToServer::fetchUserTitlesAsync(con
throw;
}
});
}
pplx::task<BotStructs::Title> BotToServer::fetchTitleAsync(const std::string& userId, int64_t titleId) {
auto impersonationTask = authClient.getImpersonationToken(std::stoi(userId));
// Шаг 2: После получения токена — делаем запрос getTitle с этим токеном
return impersonationTask.then([=](pplx::task<std::shared_ptr<nyanimed::meow::auth::model::GetImpersonationToken_200_response>> tokenTask) {
try {
auto tokenResponse = tokenTask.get();
if (!tokenResponse) {
throw std::runtime_error("Null response from getImpersonationToken");
}
utility::string_t accessToken = utility::conversions::to_string_t(tokenResponse->getAccessToken());
// Формируем заголовки с токеном
std::map<utility::string_t, utility::string_t> customHeaders;
customHeaders[U("Cookie")] = U("access_token=") + accessToken;
// Шаг 3: Выполняем запрос getTitle
return api->getTitle(
titleId,
boost::none, // fields — оставляем по умолчанию (все поля)
customHeaders
);
} catch (const std::exception& e) {
std::cerr << "Error obtaining impersonation token in fetchTitleAsync: " << e.what() << std::endl;
throw;
}
}).then([](pplx::task<std::shared_ptr<org::openapitools::client::model::Title>> responseTask) {
try {
auto response = responseTask.get();
if (!response) {
throw std::runtime_error("Null response from getTitle");
}
// Преобразуем модель OpenAPI в внутреннюю структуру бота
BotStructs::Title botTitle = mapTitleToBotTitle(response);
return botTitle;
} catch (const web::http::http_exception& e) {
std::cerr << "HTTP error in fetchTitleAsync: " << e.what() << std::endl;
throw;
} catch (const std::exception& e) {
std::cerr << "Error in fetchTitleAsync: " << e.what() << std::endl;
throw;
}
});
}
BotStructs::Title BotToServer::mapTitleToBotTitle(
const std::shared_ptr<org::openapitools::client::model::Title>& titleModel)
{
if (!titleModel) {
throw std::invalid_argument("titleModel is null");
}
BotStructs::Title botTitle;
botTitle.id = titleModel->getId();
botTitle.num = 0;
botTitle.description = ""; // Описание недоступно в текущей модели
// Извлекаем название
std::string titleName;
const auto& titleNames = titleModel->getTitleNames();
// Попробуем ru → en → первый попавшийся
std::vector<utility::string_t> preferredLangs = { U("ru"), U("en") };
bool found = false;
for (const auto& lang : preferredLangs) {
auto it = titleNames.find(lang);
if (it != titleNames.end() && !it->second.empty()) {
titleName = utility::conversions::to_utf8string(it->second[0]);
found = true;
break;
}
}
if (!found && !titleNames.empty()) {
// Берём первый язык и первое название
const auto& firstLang = *titleNames.begin();
if (!firstLang.second.empty()) {
titleName = utility::conversions::to_utf8string(firstLang.second[0]);
}
}
botTitle.name = titleName;
// --- Изображение ---
botTitle.imageUrl = "";
if (titleModel->posterIsSet()) {
auto poster = titleModel->getPoster();
if (poster && poster->imagePathIsSet()) {
botTitle.imageUrl = utility::conversions::to_utf8string(poster->getImagePath());
}
}
return botTitle;
}