{"id":373946,"date":"2024-05-21T05:48:22","date_gmt":"2024-05-21T05:48:22","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=373946"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=373946","title":{"rendered":"<span>Java \u0434\u043b\u044f \u0434\u043e\u043c\u043e\u0445\u043e\u0437\u044f\u0435\u043a: \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f \u043f\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0432\u043d\u0443\u0442\u0440\u0438 Telegram \u0431\u043e\u0442\u0430<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e \u0432\u0430\u0448\u0435\u043c\u0443 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044e \u0441\u0432\u043e\u0451 \u0432\u0438\u0434\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430, \u0442.\u043a. \u043d\u0438\u0447\u0435\u0433\u043e \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0433\u043e \u043f\u043e\u043a\u0430 \u043d\u0435 \u043d\u0430\u0445\u043e\u0434\u0438\u043b. \u0414\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0439 \u043d\u0430 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u043a\u043d\u043e\u043f\u043a\u0438 \u0432 \u0431\u043e\u0442\u0435 <a href=\"https:\/\/t.me\/AvandyNewsBot\" rel=\"noopener noreferrer nofollow\"><strong>Avandy News<\/strong><\/a><strong> (<\/strong>\u0431\u043e\u0442 \u043e\u0441\u043d\u043e\u0432\u0430\u043d \u043d\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0435 <a href=\"https:\/\/avandy-news.ru\/\" rel=\"noopener noreferrer nofollow\">Avandy News Analysis<\/a>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0430 \u0432 <a href=\"https:\/\/reestr.digital.gov.ru\/reestr\/1483979\/\" rel=\"noopener noreferrer nofollow\">\u0420\u0435\u0435\u0441\u0442\u0440 \u0440\u043e\u0441\u0441\u0438\u0439\u0441\u043a\u043e\u0433\u043e \u041f\u041e<\/a>).<\/p>\n<p><strong>\u0421\u0442\u0435\u043a: <\/strong>Java 17, Spring Boot 3.15, Postgresql 16.1<\/p>\n<h2>\u041a \u043d\u0430\u043c \u043f\u0440\u0438\u0448\u043b\u0438 \u0433\u043e\u0441\u0442\u0438 \u0438..<\/h2>\n<h2>\u0421\u0438\u0442\u0443\u0430\u0446\u0438\u044f \u2116 1 (\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 Inline \u043a\u043d\u043e\u043f\u043e\u043a)<\/h2>\n<p>\u041e\u043d\u0438 \u0445\u043e\u0442\u044f\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0431\u043e\u0442\u0443 \u043b\u044e\u0431\u043e\u0435 \u0441\u043b\u043e\u0432\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0438\u0441\u043a\u0430\u0442\u044c \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0438, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0435 \u044d\u0442\u043e \u0441\u043b\u043e\u0432\u043e.<\/p>\n<p><strong>\u0412\u043a\u0440\u0430\u0442\u0446\u0435<\/strong><\/p>\n<ol>\n<li>\n<p>\u0421\u043e\u0437\u0434\u0430\u0451\u043c \u043f\u043e\u0442\u043e\u043a\u043e\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u0443\u044e \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044e <strong>ConcurrentHashMap<\/strong>, \u0433\u0434\u0435 \u043a\u043b\u044e\u0447 \u044d\u0442\u043e \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 id \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u0430\u0451\u0442 \u0441\u0430\u043c Telegram (chat_id).<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0442\u0435\u043a\u0441\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u0440\u0438\u0448\u043b\u043e <strong>update.getMessage().getText()<\/strong><\/p>\n<\/li>\n<li>\n<p>\u0414\u0435\u043b\u0430\u0435\u043c \u043a\u0435\u0439\u0441\u044b \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0438\u0441\u0445\u043e\u0434\u044f \u0438\u0437 \u043b\u043e\u0433\u0438\u043a\u0438 \u0432\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f (\u0443 \u043c\u0435\u043d\u044f \u0442\u0430\u043a\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435, \u043d\u0435 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u044e\u0449\u0435\u0435 \u043d\u0438 \u0441 \u043e\u0434\u043d\u0438\u043c \u043a\u0435\u0439\u0441\u043e\u043c, \u043f\u043e\u043f\u0430\u0434\u0430\u0435\u0442 \u0432 \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434. \u0422\u0430\u043c \u0443\u0436\u0435 \u0435\u0441\u0442\u044c \u0441\u0432\u043e\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043f\u043e \u043e\u043f\u044b\u0442\u0443 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043f\u0430\u0440\u044b \u0442\u044b\u0441\u044f\u0447 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439)<\/p>\n<\/li>\n<li>\n<p>\u0421\u043e\u0437\u0434\u0430\u0451\u043c \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u0443 <strong>InlineKeyboardMarkup<\/strong> \u0441 \u043a\u043d\u043e\u043f\u043a\u0430\u043c\u0438<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u044b \u043a\u043b\u0430\u0434\u0451\u043c \u0441\u043b\u043e\u0432\u043e \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u0433\u043e\u0441\u0442\u044f \u0432 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044e <strong>\u043f.1<\/strong><\/p>\n<\/li>\n<li>\n<p>\u0412 \u0441\u0435\u043a\u0446\u0438\u0438 <strong>update.hasCallbackQuery() <\/strong>\u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0438\u043c\u044f \u043d\u0430\u0436\u0430\u0442\u043e\u0439 \u043a\u043d\u043e\u043f\u043a\u0438 \u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043a \u0435\u0451 \u043a\u0435\u0439\u0441\u0443<\/p>\n<\/li>\n<li>\n<p>\u0411\u0435\u0440\u0451\u043c \u0441\u043b\u043e\u0432\u043e \u0438\u0437 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0451\u043c \u0435\u0433\u043e \u0432 \u043d\u0443\u0436\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438. \u0412\u0441\u0451.<\/p>\n<\/li>\n<\/ol>\n<p><strong>\u041d\u0415 \u0432\u043a\u0440\u0430\u0442\u0446\u0435<\/strong><\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/745\/157\/71d\/74515771d2957fcee7941183ff1b3bcb.jpg\" alt=\"\u0420\u0430\u043d\u0435\u0435 \u0431\u044b\u043b\u043e \u0430\u0436 5 \u043a\u043d\u043e\u043f\u043e\u043a (\u0443\u043f\u0440\u043e\u0449\u0430\u0435\u043c, \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u043c..)\" title=\"\u0420\u0430\u043d\u0435\u0435 \u0431\u044b\u043b\u043e \u0430\u0436 5 \u043a\u043d\u043e\u043f\u043e\u043a (\u0443\u043f\u0440\u043e\u0449\u0430\u0435\u043c, \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u043c..)\" width=\"1079\" height=\"1814\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/745\/157\/71d\/74515771d2957fcee7941183ff1b3bcb.jpg\" data-blurred=\"true\"\/><\/p>\n<div><figcaption>\u0420\u0430\u043d\u0435\u0435 \u0431\u044b\u043b\u043e \u0430\u0436 5 \u043a\u043d\u043e\u043f\u043e\u043a (\u0443\u043f\u0440\u043e\u0449\u0430\u0435\u043c, \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u043c..)<\/figcaption><\/div>\n<\/figure>\n<p>\u041a\u0430\u043a \u044d\u0442\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0432 \u043a\u043e\u0434\u0435:<\/p>\n<pre><code class=\"java\">\/* 1 \u0448\u0430\u0433. \u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0441\u043b\u043e\u0432\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0438\u0448\u0443\u0442 \u0431\u043e\u0442\u0443 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e,    \u043d\u0435 \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u043b\u0438\u0441\u044c - \u0434\u0435\u043b\u0430\u0435\u043c \u043f\u043e\u0442\u043e\u043a\u043e\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u0443\u044e \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044e     \u0433\u0434\u0435 \u043a\u043b\u044e\u0447 Long \u044d\u0442\u043e \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 chat_id, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043b\u044e\u0431\u0435\u0437\u043d\u043e \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 Telegram *\/ private final Map&lt;Long, String> oneWordFromChat = new ConcurrentHashMap&lt;>();  @Override public void onUpdateReceived(Update update) {     \/\/ 2 \u0448\u0430\u0433. \u0413\u043e\u0441\u0442\u044c \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u043b \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0438 \u043c\u044b \u0435\u0433\u043e \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u0438\u043b\u0438 \u0437\u0434\u0435\u0441\u044c     if (update.hasMessage() &amp;&amp; update.getMessage().hasText()) {         String messageText = update.getMessage().getText(); \/\/ = \"\u041c\u043e\u0441\u043a\u0432\u0430\"         long chatId = update.getMessage().getChatId(); \/\/ \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 id \u0433\u043e\u0441\u0442\u044f                \/\/ \u041f\u0440\u0438\u043d\u0443\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0432\u044b\u0445\u043e\u0434 \u0434\u043b\u044f \u043f\u0441\u0438\u0445\u043e\u0432 (\u043f\u043e\u0432\u0435\u0440\u044c\u0442\u0435 - \u0447\u0430\u0441\u0442\u043e \u043f\u0440\u0438\u043b\u0435\u0442\u0430\u0435\u0442)         List&lt;String> flugegeheimen = List.of(\"\u0441\u0442\u043e\u043f\", \"\/\u0441\u0442\u043e\u043f\", \"stop\", \"\/stop\");         \/\/ toLowerCase :)         if (flugegeheimen.contains(messageText.toLowerCase())) {           userStates.remove(chatId); \/\/ \u0421\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0431\u043e\u0442\u0430 (\u043e\u0431 \u044d\u0442\u043e\u043c \u043f\u043e\u0437\u0436\u0435)           nextKeyboard(chatId, \"\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u043e\u0442\u043c\u0435\u043d\u0435\u043d\u043e\"); \/\/ \u041e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0433\u043e\u0441\u0442\u044e                        } else if (messageText.startsWith(\"\")) {         } else if (messageText.equals(\"\")) {         } else {             \/* \u041e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b *\/             switch (messageText) {               case \"\/settings\" -> getSettings(chatId);               case \"\/info\" -> infoKeyboard(chatId);               \/\/ 3 \u0448\u0430\u0433. \u041c\u044b \u043f\u043e\u043f\u0430\u043b\u0438 \u0441\u044e\u0434\u0430, \u0442.\u043a. \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \"\u041c\u043e\u0441\u043a\u0432\u0430\"                \/\/ \u043d\u0438 \u0441 \u043e\u0434\u043d\u0438\u043c \u043a\u0435\u0439\u0441\u043e\u043c \u043d\u0435 \u0441\u043e\u0432\u043f\u0430\u043b\u043e               default -> undefinedKeyboard(chatId, messageText);             }         }     } }<\/code><\/pre>\n<ol>\n<li>\n<p>\u0417\u0430\u0434\u0430\u0451\u043c \u0432\u043e\u043f\u0440\u043e\u0441 \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c \u043a\u043b\u0430\u0441\u0441\u0430 <strong>SendMessage<\/strong>, <strong>InlineKeyboardMarkup &#8212;<\/strong> 2 \u0448\u0442., \u043f\u043e\u0442\u043e\u043a\u043e\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0439 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 \u0438 \u043a\u0440\u0430\u0441\u0438\u0432\u043e\u0433\u043e \u0441\u043c\u0430\u0439\u043b\u0430 \u0434\u043b\u044f \u0441\u0433\u043b\u0430\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0438 \u043f\u043e\u0441\u043b\u0435 \u0441\u0442\u043e\u043b\u044c \u043f\u0440\u044f\u043c\u043e\u0433\u043e \u0432\u043e\u043f\u0440\u043e\u0441\u0430.<\/p>\n<\/li>\n<\/ol>\n<pre><code class=\"java\">\/\/ 4 \u0448\u0430\u0433. \u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u0443 InlineKeyboardMarkup \u0441 \u0434\u0432\u0443\u043c\u044f \u043a\u043d\u043e\u043f\u043a\u0430\u043c\u0438 private void undefinedKeyboard(long chatId, String word) {   \/\/ 5 \u0448\u0430\u0433. \u041a\u043b\u0430\u0434\u0451\u043c \u0441\u043b\u043e\u0432\u043e \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u0433\u043e\u0441\u0442\u044f \u0432 \u0440\u0430\u043d\u0435\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u0443\u044e \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044e   oneWordFromChat.put(chatId, word); \/\/ word = \"\u041c\u043e\u0441\u043a\u0432\u0430\"      \/\/ \u0414\u0435\u043b\u0430\u0435\u043c \u0434\u0432\u0443\u0445\u0441\u043b\u043e\u0439\u043d\u044b\u0439 \u0442\u043e\u0440\u0442 \u0438\u0437 \u043a\u043d\u043e\u043f\u043e\u043a   Map&lt;String, String> floor1 = new HashMap&lt;>();   Map&lt;String, String> floor2 = new HashMap&lt;>();    \/\/ \u041f\u043e\u043d\u044f\u0442\u043d\u043e \u043e\u0437\u0432\u0443\u0447\u0438\u0432\u0430\u0435\u043c \u0438\u043d\u0433\u0440\u0438\u0434\u0438\u0435\u043d\u0442\u044b \u0434\u043b\u044f \u0441\u0435\u0431\u044f \u0438 \u0433\u043e\u0441\u0442\u0435\u0439   floor1.put(\"ADD_KEYWORD_FROM_CHAT\", \"\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u043f\u043e\u0438\u0441\u043a\u0430\");   floor2.put(\"SEARCH_BY_WORD\", \"\u0418\u0441\u043a\u0430\u0442\u044c \u043d\u043e\u0432\u043e\u0441\u0442\u0438\");    \/\/ \u043a\u043e\u0434 maker \u043d\u0430 GitHub   sendMessage(chatId, \"\u0427\u0442\u043e \u0441 \u044d\u0442\u0438\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c? \" + \"\\uD83E\\uDDD0\",                InlineKeyboards.maker(floor1, floor2)); }<\/code><\/pre>\n<ol start=\"2\">\n<li>\n<p>\u0413\u043e\u0441\u0442\u0438 \u043d\u0430\u0436\u0438\u043c\u0430\u044e\u0442 \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 &#171;\u0418\u0441\u043a\u0430\u0442\u044c \u043d\u043e\u0432\u043e\u0441\u0442\u0438&#187;, \u043d\u043e \u043d\u0435 \u0444\u0430\u043a\u0442, \u0438<\/p>\n<\/li>\n<\/ol>\n<pre><code class=\"java\">if (update.hasMessage() &amp;&amp; update.getMessage().hasText()) {     \/\/ \u0437\u0434\u0435\u0441\u044c \u0441\u0435\u0439\u0447\u0430\u0441 \u043f\u0443\u0441\u0442\u043e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0438\u0434\u0451\u043c \u0434\u0430\u043b\u044c\u0448\u0435 } else if (update.hasCallbackQuery()) {   \/\/ 6 \u0448\u0430\u0433. \u0410 \u0432\u043e\u0442 \u0437\u0434\u0435\u0441\u044c \u0443\u0436\u0435 \u043b\u043e\u0432\u0438\u043c \u043d\u0430\u0436\u0430\u0442\u0443\u044e \u043a\u043d\u043e\u043f\u043a\u0443   String callbackData = update.getCallbackQuery().getData(); \/\/ = \"SEARCH_BY_WORD\"    switch (callbackData) {       case \"JOHN_COFFEY_MAM\" -> drinkCoffee(chatId, \"See The Green mile\");       \/\/ \u0437\u0430\u0448\u043b\u0438 \u0441\u044e\u0434\u0430       case \"SEARCH_BY_WORD\" ->         \/\/ 7 \u0448\u0430\u0433. \u041f\u0435\u0440\u0435\u0434\u0430\u0451\u043c \u0441\u043b\u043e\u0432\u043e \u0438\u0437 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 \u0432 \u043c\u0435\u0442\u043e\u0434 \u043f\u043e\u0438\u0441\u043a\u0430         wordSearch(chatId, oneWordFromChat.get(chatId));   }  }<\/code><\/pre>\n<ol start=\"3\">\n<li>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043e\u043d\u0438 \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u044e\u0442 \u0442\u0430\u043a\u043e\u0439 \u043e\u0442\u0432\u0435\u0442 (\u0432\u0438\u0434 \u043d\u043e\u0432\u043e\u0441\u0442\u0435\u0439 \u0432\u043e\u0437\u043c\u043e\u0436\u0435\u043d \u0432 5 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430\u0445). \u041a\u0430\u043a \u0432\u0438\u0434\u0438\u0442\u0435 \u043e\u043a\u043e\u043d\u0447\u0430\u043d\u0438\u044f \u0443 \u041c\u043e\u0441\u043a\u0432\u044b \u0440\u0430\u0437\u043d\u044b\u0435, \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u0430\u043a \u043f\u0440\u043e\u0441\u0438\u043b\u0438, \u043d\u043e \u044d\u0442\u043e \u0443\u0436\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u0434\u0440\u0443\u0433\u0430\u044f \u0438\u0441\u0442\u043e\u0440\u0438\u044f.<\/p>\n<figure class=\"bordered full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/481\/ca7\/d6a\/481ca7d6a38f4860fd8ed06560f1095f.png\" alt=\"\u0411\u0435\u0435\u0435\u0435\u0437 \u0442\u0435\u0435\u0435\u0435\u0431\u044f\u044f, \u0431\u0435\u0437 \u0442\u0435\u0431\u044f..\" title=\"\u0411\u0435\u0435\u0435\u0435\u0437 \u0442\u0435\u0435\u0435\u0435\u0431\u044f\u044f, \u0431\u0435\u0437 \u0442\u0435\u0431\u044f..\" width=\"1080\" height=\"1339\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/481\/ca7\/d6a\/481ca7d6a38f4860fd8ed06560f1095f.png\"\/><\/p>\n<div><figcaption>\u0411\u0435\u0435\u0435\u0435\u0437 \u0442\u0435\u0435\u0435\u0435\u0431\u044f\u044f, \u0431\u0435\u0437 \u0442\u0435\u0431\u044f..<\/figcaption><\/div>\n<\/figure>\n<\/li>\n<\/ol>\n<h2>\u0421\u0438\u0442\u0443\u0430\u0446\u0438\u044f \u2116 2 (\u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0435 \u0432\u0432\u043e\u0434\u0430 \u0442\u0435\u043a\u0441\u0442\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c)<\/h2>\n<p>\u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c \u0433\u043e\u0441\u0442\u044c \u0440\u0435\u0448\u0438\u043b \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0441\u043b\u043e\u0432\u043e \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u043f\u043e\u0438\u0441\u043a\u0430.<\/p>\n<p>\u041e\u043d \u043d\u0430\u0436\u0438\u043c\u0430\u0435\u0442 <strong>\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c <\/strong>\u0438 \u0431\u043e\u0442 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442 \u0432 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u0432\u0432\u043e\u0434\u0430 \u0441 \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u044b \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f (\u0437\u0434\u0435\u0441\u044c \u0442\u043e\u0436\u0435 \u043f\u043e\u043b\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a, \u044e\u0437\u0435\u0440 \u0447\u0442\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0435 \u0442\u0432\u043e\u0440\u0438\u0442).<\/p>\n<p><strong>\u0412\u043a\u0440\u0430\u0442\u0446\u0435<\/strong><\/p>\n<ol>\n<li>\n<p>\u041d\u0430\u0436\u0430\u0442\u0438\u0435 \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443<\/p>\n<\/li>\n<li>\n<p>\u041f\u0435\u0440\u0435\u0432\u043e\u0434 \u0431\u043e\u0442\u0430 \u0432 \u043d\u0443\u0436\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435, \u043f\u0443\u0442\u0451\u043c \u0435\u0433\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0432 \u043f\u043e\u0442\u043e\u043a\u043e\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u0443\u044e \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044e \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u0433\u043e\u0441\u0442\u044f<\/p>\n<\/li>\n<li>\n<p>\u041e\u0436\u0438\u0434\u0430\u043d\u0438\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f<\/p>\n<\/li>\n<li>\n<p>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043f\u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c\u0443 \u0433\u043e\u0441\u0442\u044e \u0438 \u043f\u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c\u0443 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044e<\/p>\n<\/li>\n<\/ol>\n<p><strong>\u041d\u0415 \u0441\u043e\u0432\u0441\u0435\u043c \u0432\u043a\u0440\u0430\u0442\u0446\u0435<\/strong><\/p>\n<figure class=\"bordered full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/fc2\/b23\/df4\/fc2b23df47250bbb366e5e94e3cb359b.jpg\" alt=\"\u041d\u0430\u0436\u0430\u0442\u0430 \u043a\u043d\u043e\u043f\u043a\u0430 \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c\" title=\"\u041d\u0430\u0436\u0430\u0442\u0430 \u043a\u043d\u043e\u043f\u043a\u0430 \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c\" width=\"1079\" height=\"1593\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/fc2\/b23\/df4\/fc2b23df47250bbb366e5e94e3cb359b.jpg\" data-blurred=\"true\"\/><\/p>\n<div><figcaption>\u041d\u0430\u0436\u0430\u0442\u0430 \u043a\u043d\u043e\u043f\u043a\u0430 \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c<\/figcaption><\/div>\n<\/figure>\n<p>\u0412 \u0440\u0430\u0437\u0434\u0435\u043b <strong>hasCallbackQuery<\/strong> \u043b\u0435\u0442\u0438\u0442 <strong>callbackData<\/strong> \u0440\u0430\u0432\u043d\u044b\u0439 <strong>ADD_KEYWORD <\/strong>(\u0442\u0430\u043a \u043c\u044b \u043d\u0430\u0437\u0432\u0430\u043b\u0438 \u044d\u0442\u0443 \u043a\u043d\u043e\u043f\u043a\u0443 \u0432\u043d\u0443\u0442\u0440\u0438 \u0431\u043e\u0442\u0430) \u0438 \u043d\u0430\u0448 \u0431\u043e\u0442 \u043e\u0436\u0438\u0434\u0430\u0435\u0442 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u0442.\u0435. \u0435\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u043d\u0430 <strong>ADD_KEYWORDS<\/strong><\/p>\n<pre><code class=\"java\">\/\/ \u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0431\u043e\u0442\u0430 public enum UserState {     SEND_FEEDBACK,     \/\/..     ADD_KEYWORDS }<\/code><\/pre>\n<pre><code class=\"java\">\/* \u041a\u043b\u0430\u0441\u0441 \u0431\u043e\u0442\u0430 *\/ \/\/ 1. \u041a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0433\u0434\u0435 Long = chatId private final Map&lt;Long, UserState> userStates = new ConcurrentHashMap&lt;>();    if (update.hasMessage() &amp;&amp; update.getMessage().hasText()) {       \/\/ \u0437\u0434\u0435\u0441\u044c \u0441\u0435\u0439\u0447\u0430\u0441 \u043f\u0443\u0441\u0442\u043e   } else if (update.hasCallbackQuery()) {          \/\/ 2. \u041d\u0430\u0436\u0430\u0432 \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 \u043c\u044b \u043f\u043e\u043f\u0430\u0434\u0430\u0435\u043c \u0432 \u044d\u0442\u043e\u0442 \u043a\u0435\u0439\u0441, \u0442.\u043a. \"\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c\" = \"ADD_KEYWORD\"     case \"ADD_KEYWORD\" -> setBotState(chatId, UserState.ADD_KEYWORDS, addInListText);          \/\/ \u0421\u0431\u0440\u043e\u0441 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0431\u043e\u0442\u0430 \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0435\u0441\u043b\u0438 \u043e\u043d \u043d\u0430\u0436\u043c\u0451\u0442 \"\u041e\u0442\u043c\u0435\u043d\u0430\"     case \"CANCEL\" -> userStates.remove(chatId);    }    \/\/ 3. \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0431\u043e\u0442\u0430   private void setBotState(Long chatId, UserState state, String text) {       userStates.put(chatId, state);       \/\/ 4. \u0417\u0434\u0435\u0441\u044c \u0431\u043e\u0442 \u0438 \u043e\u0436\u0438\u0434\u0430\u0435\u0442 \u0432\u0432\u043e\u0434\u0430 \u0442\u0435\u043a\u0441\u0442\u0430. \u0422\u0443\u0442 \u0436\u0435 \u043c\u043e\u0436\u0435\u043c \u043e\u0442\u043c\u0435\u043d\u0438\u0442\u044c \u0432\u0432\u043e\u0434.       cancelKeyboard(chatId, text);   }    \/\/ \u041a\u043d\u043e\u043f\u043a\u0430 \u043e\u0442\u043c\u0435\u043d\u044b \u0432\u0432\u043e\u0434\u0430 \u0441\u043b\u043e\u0432   private void cancelKeyboard(long chatId, String text) {       Map&lt;String, String> buttons = new LinkedHashMap&lt;>();       buttons.put(\"CANCEL\", cancelButtonText);       sendMessage(chatId, text, InlineKeyboards.maker(buttons));   }      \/\/ \u041a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u0430 \u0440\u0430\u0437\u0434\u0435\u043b\u0430 \u0441 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438 \u0434\u043b\u044f \u043f\u043e\u0438\u0441\u043a\u0430   private void keywordsListKeyboard(long chatId, String text) {       Map&lt;String, String> buttons1 = new LinkedHashMap&lt;>();       Map&lt;String, String> buttons2 = new LinkedHashMap&lt;>();          buttons1.put(\"DELETE_KEYWORD\", delText);       buttons1.put(\"ADD_KEYWORD\", addText);       buttons2.put(\"SET_PERIOD\", intervalText);       buttons2.put(\"FIND_BY_KEYWORDS\", searchText);            sendMessage(chatId, text, InlineKeyboards.maker(buttons1, buttons2));   }   }<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0432\u0432\u043e\u0434\u0430 \u0442\u0435\u043a\u0441\u0442\u0430, \u043a\u043e\u0433\u0434\u0430 \u0431\u043e\u0442 \u0432 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0438 <strong>ADD_KEYWORDS,<\/strong> \u043c\u044b \u043b\u043e\u0432\u0438\u043c \u0432\u0432\u0435\u0434\u0451\u043d\u043d\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0443\u0436\u0435 \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 <strong>update.hasMessage()<\/strong> \u0433\u0434\u0435 \u0438 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0435\u0433\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430<\/p>\n<pre><code class=\"java\">\/\/ \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f if (update.hasMessage() &amp;&amp; update.getMessage().hasText()) {       String messageText = update.getMessage().getText();       long chatId = update.getMessage().getChatId();              \/\/ 5. \u0411\u0435\u0440\u0451\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0431\u043e\u0442\u0430 \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f       UserState userState = userStates.get(chatId);              \/\/ \u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0431\u043e\u0442\u0430 \u0441\u0435\u0439\u0447\u0430\u0441 - \u044d\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u043b\u043e\u0432 \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u043f\u043e\u0438\u0441\u043a\u0430       if (UserState.ADD_KEYWORDS.equals(userState)) {         \/\/ \u041e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c         String keywords = messageText.trim().toLowerCase();         addKeywords(chatId, keywords);       }      \/\/ \u0421\u0431\u0440\u043e\u0441 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f     userStates.remove(chatId);    } else if (update.hasCallbackQuery()) {   \/\/.. }<\/code><\/pre>\n<h2>\u0421\u0438\u0442\u0443\u0430\u0446\u0438\u044f \u2116 3 (\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0441 \u0444\u043e\u0442\u043e)<\/h2>\n<p>\u0413\u043e\u0441\u0442\u044c \u0437\u0430\u0445\u043e\u0442\u0435\u043b \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043d\u0430\u043c \u0441\u0432\u043e\u0438 \u0432\u043f\u0435\u0447\u0430\u0442\u043b\u0435\u043d\u0438\u044f \u043e\u0442 \u0432\u0435\u0447\u0435\u0440\u0430 \u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0438\u0442\u044c \u0444\u043e\u0442\u043e.<\/p>\n<p><strong>\u0412\u043a\u0440\u0430\u0442\u0446\u0435<\/strong><\/p>\n<ol>\n<li>\n<p>\u041d\u0430\u0436\u0430\u0442\u0438\u0435 \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443<\/p>\n<\/li>\n<li>\n<p>\u041f\u0435\u0440\u0435\u0432\u043e\u0434 \u0431\u043e\u0442\u0430 \u0432 \u043d\u0443\u0436\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435, \u043f\u0443\u0442\u0451\u043c \u0435\u0433\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0432 \u043f\u043e\u0442\u043e\u043a\u043e\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u0443\u044e \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044e \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u0433\u043e\u0441\u0442\u044f<\/p>\n<\/li>\n<li>\n<p>\u041e\u0436\u0438\u0434\u0430\u043d\u0438\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f<\/p>\n<\/li>\n<li>\n<p>\u041e\u0442\u0434\u0435\u043b\u044c\u043d\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0441 \u0444\u043e\u0442\u043e<\/p>\n<\/li>\n<\/ol>\n<p><strong>\u041d\u0435\u0442<\/strong><\/p>\n<figure class=\"bordered full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/1bd\/fc3\/7f4\/1bdfc37f4b0f337bd835fff68ae61e84.png\" width=\"734\" height=\"453\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/1bd\/fc3\/7f4\/1bdfc37f4b0f337bd835fff68ae61e84.png\"\/><\/figure>\n<pre><code class=\"java\">\/\/ \u041f\u043e\u0441\u043b\u0435 \u043d\u0430\u0436\u0430\u0442\u0438\u044f \u043a\u043d\u043e\u043f\u043a\u0438 \"\u041d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043e\u0442\u0437\u044b\u0432\" if (update.hasMessage() &amp;&amp; update.getMessage().hasText()) {} else if (update.hasCallbackQuery()) {       \/\/ \u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0441\u0442\u0430\u0442\u0443\u0441 \u0431\u043e\u0442\u0430 \u0432 \u0440\u0435\u0436\u0438\u043c SEND_FEEDBACK \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u0433\u043e\u0441\u0442\u044f       case \"FEEDBACK\" -> setBotState(chatId, UserState.SEND_FEEDBACK); }<\/code><\/pre>\n<pre><code class=\"java\">\/\/ \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0441 \u0444\u043e\u0442\u043e @Override public void onUpdateReceived(Update update) {     if (update.hasMessage() &amp;&amp; update.getMessage().hasPhoto()) {           long chatId = update.getMessage().getChatId();           \/\/ \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0431\u043e\u0442\u0430           UserState userState = userStates.get(chatId);          \/\/ update \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0441\u043a\u0440\u0438\u043d\u0448\u043e\u0442         if (UserState.SEND_FEEDBACK.equals(userState)) {             \/\/ \u041e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0443 \u0441 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c \u0441\u043a\u0440\u0438\u043d\u0448\u043e\u0442\u0430             sendFeedbackWithPhoto(update);             \/\/ \u0421\u0431\u0440\u043e\u0441 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0431\u043e\u0442\u0430             userStates.remove(chatId);             \/\/ \u0423\u0432\u0435\u0434\u043e\u043c\u043b\u044f\u0435\u043c, \u0447\u0442\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0443\u0441\u043f\u0435\u0448\u043d\u0430             sendMessage(chatId, \"\u0414\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043e \u2714\ufe0f\");         }                 }      else if (update.hasMessage() &amp;&amp; update.getMessage().hasText()) {}      else if (update.hasCallbackQuery()) {} }  \/\/ \u041e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u043e\u0442\u0437\u044b\u0432\u0430 \u043f\u043e\u0432\u0430\u0440\u0443 \u0441 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c \u0441\u043a\u0440\u0438\u043d\u0448\u043e\u0442\u0430 (\u0435\u0441\u043b\u0438 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0449\u0435, \u0442\u043e \u0441\u043a\u0430\u0436\u0438\u0442\u0435 \u043a\u0430\u043a) private void sendFeedbackWithPhoto(Update update) {     long chatIdFrom = update.getMessage().getChatId();     String userName = userRepository.findNameByChatId(chatIdFrom);     String caption = update.getMessage().getCaption();     if (caption == null) caption = \"\u043d\u0435 \u0443\u0434\u043e\u0441\u0443\u0436\u0438\u043b\u0441\u044f..\";     List&lt;PhotoSize> photos = update.getMessage().getPhoto();      SendPhoto sendPhoto = new SendPhoto();     sendPhoto.setChatId(OWNER_ID);     sendPhoto.setCaption(\"Message from \" + userName + \", \" + chatIdFrom + \":\\n\" + caption);      List&lt;PhotoSize> photo = update.getMessage().getPhoto();     if (photo == null) return;     try {         String fileId = Objects.requireNonNull(photos.stream().max(Comparator.comparing(PhotoSize::getFileSize))                 .orElse(null)).getFileId();          URL url = new URL(\"https:\/\/api.telegram.org\/bot\" + TOKEN + \"\/getFile?file_id=\" + fileId);          BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));         String res = in.readLine();         String filePath = new JSONObject(res).getJSONObject(\"result\").getString(\"file_path\");         String urlPhoto = \"https:\/\/api.telegram.org\/file\/bot\" + TOKEN + \"\/\" + filePath;          URL url2 = new URL(urlPhoto);         BufferedImage img = ImageIO.read(url2);          ByteArrayOutputStream os = new ByteArrayOutputStream();         ImageIO.write(img, \"jpg\", os);         InputStream is = new ByteArrayInputStream(os.toByteArray());         sendPhoto.setPhoto(new InputFile(is, caption));          execute(sendPhoto);      } catch (IOException | TelegramApiException e) {         log.error(e.getMessage());     } }<\/code><\/pre>\n<p><strong>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442<\/strong><\/p>\n<figure class=\"bordered\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/ea6\/3fa\/272\/ea63fa272cc70ead7d672bb6d5f5e5a3.png\" alt=\"\u041f\u043e\u043a\u0430 \u0436\u0435\u043d\u0430 \u043d\u0435 \u0432\u0438\u0434\u0438\u0442\" title=\"\u041f\u043e\u043a\u0430 \u0436\u0435\u043d\u0430 \u043d\u0435 \u0432\u0438\u0434\u0438\u0442\" width=\"398\" height=\"581\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/ea6\/3fa\/272\/ea63fa272cc70ead7d672bb6d5f5e5a3.png\"\/><\/p>\n<div><figcaption>\u041f\u043e\u043a\u0430 \u0436\u0435\u043d\u0430 \u043d\u0435 \u0432\u0438\u0434\u0438\u0442<\/figcaption><\/div>\n<\/figure>\n<h2>\u0421\u0438\u0442\u0443\u0430\u0446\u0438\u044f \u2116 4 (\u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c\u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u043e\u0442 \u0432\u043b\u0430\u0434\u0435\u043b\u044c\u0446\u0430 \u0431\u043e\u0442\u0430)<\/h2>\n<p>\u0415\u0441\u043b\u0438 \u043b\u0438\u0447\u043d\u043e \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0445\u043e\u0447\u0435\u0442 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0432 \u0447\u0430\u0442 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c\u0443 \u0433\u043e\u0441\u0442\u044e, \u0442\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u0442\u0443\u043f\u0438\u0442\u044c \u0442\u0430\u043a.<\/p>\n<p>\u041f\u0438\u0448\u0435\u043c \u042d\u043c\u0438\u043b\u0438 \u0432 \u0447\u0430\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0432\u0438\u0434\u0430:<\/p>\n<p><strong>@123457 \u0410 \u0447\u0442\u043e \u043d\u0430\u0434\u043e \u0431\u044b\u043b\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c? Windows \u043f\u0435\u0440\u0435\u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c?<\/strong><\/p>\n<ol>\n<li>\n<p>@ &#8212; \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043b\u044e\u0431\u043e\u0439 \u0441\u0438\u043c\u0432\u043e\u043b \u0438\u043b\u0438 \u0441\u043b\u043e\u0432\u043e, \u044f \u0432\u044b\u0431\u0440\u0430\u043b \u044d\u0442\u043e\u0442<\/p>\n<\/li>\n<li>\n<p>\u0431\u0435\u0437 \u043f\u0440\u043e\u0431\u0435\u043b\u0430 \u043f\u043e\u0441\u043b\u0435 @ \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 chat_it \u0433\u043e\u0441\u0442\u044f (\u043c\u044b \u0435\u0433\u043e \u0437\u043d\u0430\u0435\u043c \u0438\u043b\u0438 \u0432\u0438\u0434\u0438\u043c \u043a\u043e\u0433\u0434\u0430 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 \u043e\u0442\u0437\u044b\u0432)<\/p>\n<\/li>\n<li>\n<p>\u0441\u0442\u0430\u0432\u0438\u043c \u043f\u0440\u043e\u0431\u0435\u043b \u0438 \u043f\u0438\u0448\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0438 \u0443\u0432\u0438\u0434\u0438\u0442 \u0433\u043e\u0441\u0442\u044c \u0441 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u043c chat_it<\/p>\n<\/li>\n<\/ol>\n<pre><code class=\"java\">\/\/ \u041f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0431\u0435\u0437 \u0444\u043e\u0442\u043e, \u0431\u0435\u0437 \u043d\u0430\u0436\u0430\u0442\u0438\u044f Inline \u043a\u043d\u043e\u043f\u043e\u043a if (update.hasMessage() &amp;&amp; update.getMessage().hasText()) {   long chatId = update.getMessage().getChatId();    \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u043c\u0435\u043c, \u0447\u0442\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0438\u043c\u0435\u043d\u043d\u043e \u0432\u043b\u0430\u0434\u0435\u043b\u0435\u0446 \u0431\u043e\u0442\u0430   if (messageText.startsWith(\"@\") &amp;&amp; config.getBotOwner() == chatId) {     \/\/ \u0431\u0435\u0440\u0451\u043c chat_id \u043e\u0442 \u0441\u043e\u0431\u0430\u043a\u0438 \u0434\u043e \u043f\u0440\u043e\u0431\u0435\u043b\u0430 (\"\u0447\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442 \u043e\u0442\u043a\u0440\u043e\u0439 \u0441\u043e\u0431\u0430\u043a\u0443?\")     long chatToSend = Long.parseLong(messageText                                      .substring(1, messageText.indexOf(\" \")));     \/\/ \u0430 \u0437\u0434\u0435\u0441\u044c \u0431\u0435\u0440\u0451\u043c \u0432\u0441\u0451 \u043f\u043e\u0441\u043b\u0435 \u043f\u0440\u043e\u0431\u0435\u043b\u0430     String textToSend = messageText.substring(messageText.indexOf(\" \"));     sendMessage(chatToSend, textToSend);   }    }<\/code><\/pre>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/ff5\/29e\/cf4\/ff529ecf4c40ac8a5f102fd682b8cf02.png\" alt=\"\u0414\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u043f\u0438\u0448\u0443 \u0441\u0430\u043c \u0441\u0435\u0431\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u0441\u0451 \u0432 \u043e\u0434\u043d\u043e\u043c \u0447\u0430\u0442\u0435\" title=\"\u0414\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u043f\u0438\u0448\u0443 \u0441\u0430\u043c \u0441\u0435\u0431\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u0441\u0451 \u0432 \u043e\u0434\u043d\u043e\u043c \u0447\u0430\u0442\u0435\" width=\"741\" height=\"344\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/ff5\/29e\/cf4\/ff529ecf4c40ac8a5f102fd682b8cf02.png\"\/><\/p>\n<div><figcaption>\u0414\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u043f\u0438\u0448\u0443 \u0441\u0430\u043c \u0441\u0435\u0431\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u0441\u0451 \u0432 \u043e\u0434\u043d\u043e\u043c \u0447\u0430\u0442\u0435<\/figcaption><\/div>\n<\/figure>\n<h2>\u0421\u0438\u0442\u0443\u0430\u0446\u0438\u044f \u2116 5 (Menu \u0438 Reply Keyboard)<\/h2>\n<p>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043a\u043e\u043c\u0430\u043d\u0434 \u043c\u0435\u043d\u044e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432 \u0441\u0435\u043a\u0446\u0438\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0431\u0435\u0437 \u0444\u043e\u0442\u043e \u0438 \u0431\u0435\u0437 \u043d\u0430\u0436\u0430\u0442\u044b\u0445 \u043a\u043d\u043e\u043f\u043e\u043a.<\/p>\n<p>\u0416\u043c\u0451\u043c \u043d\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 <strong>\/settings<\/strong>, \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043a \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u043c\u0443 \u043a\u0435\u0439\u0441\u0443<\/p>\n<pre><code class=\"java\">if (update.hasMessage() &amp;&amp; update.getMessage().hasText()) {    switch (messageText) {      case \"\/settings\" -> getSettings(chatId);      case \"\/keywords\", \"\/list_key\" -> showKeywordsList(chatId);      case \"\/info\" -> infoKeyboard(chatId);    } }<\/code><\/pre>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/41d\/c27\/9b7\/41dc279b7c66b67f1a0b7365b6bebc08.png\" width=\"417\" height=\"459\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/41d\/c27\/9b7\/41dc279b7c66b67f1a0b7365b6bebc08.png\"\/><\/figure>\n<p>\u0414\u043b\u044f \u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u0432\u044b\u0437\u043e\u0432\u0430 \u0447\u0430\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u043e\u0433\u043e \u0438\u043b\u0438 \u043f\u0440\u043e\u0441\u0442\u043e-\u043d\u0430\u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430 &#8212; \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <strong>ReplyKeyboardMarkup<\/strong><\/p>\n<figure class=\"bordered full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/47f\/56c\/816\/47f56c816a3252d6c615150ae9842158.png\" width=\"740\" height=\"247\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/47f\/56c\/816\/47f56c816a3252d6c615150ae9842158.png\"\/><\/figure>\n<pre><code class=\"java\">\/\/ \u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u044b getReplyKeyboard(chatId, textToSend);  \/\/ \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u044b private void getReplyKeyboard(long chatId, String textToSend) {   KeyboardRow row = new KeyboardRow();   row.add(\"\u0412\u0441\u0435 \u043d\u043e\u0432\u043e\u0441\u0442\u0438\");   row.add(\"Top 20\");   row.add(\"\u041f\u043e \u0441\u043b\u043e\u0432\u0430\u043c\");      sendMessage(chatId, textToSend, ReplyKeyboards.replyKeyboardMaker(row)); }<\/code><\/pre>\n<pre><code class=\"java\">\/\/ \u041a\u043b\u0430\u0441\u0441 ReplyKeyboards import org.springframework.stereotype.Component; import org.telegram.telegrambots.meta.api.objects.replykeyboard.ReplyKeyboardMarkup; import org.telegram.telegrambots.meta.api.objects.replykeyboard.buttons.KeyboardRow;  import java.util.ArrayList; import java.util.List;  public class ReplyKeyboards {        public static ReplyKeyboardMarkup replyKeyboardMaker(KeyboardRow row) {         ReplyKeyboardMarkup keyboardMarkup = new ReplyKeyboardMarkup();         keyboardMarkup.setResizeKeyboard(true);          List&lt;KeyboardRow> keyboardRows = new ArrayList&lt;>();         keyboardRows.add(row);         keyboardMarkup.setKeyboard(keyboardRows);         return keyboardMarkup;     } }<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043d\u0430\u0436\u0430\u0442\u0438\u044f \u043d\u0430 \u043e\u0434\u043d\u0443 \u0438\u0437 \u0442\u0430\u043a\u0438\u0445 \u043a\u043d\u043e\u043f\u043e\u043a \u0431\u0443\u0434\u0435\u0442 <strong>\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f<\/strong> \u0441 \u0442\u0435\u043a\u0441\u0442\u043e\u043c, \u0430 <strong>\u043d\u0435 \u043a\u0430\u043a \u043f\u043e\u0441\u043b\u0435 \u043d\u0430\u0436\u0430\u0442\u0438\u044f \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0438 Inline Keyboards<\/strong><\/p>\n<pre><code class=\"java\">if (update.hasMessage() &amp;&amp; update.getMessage().hasText()) {     if (messageText.equals(\"\u041f\u043e \u0441\u043b\u043e\u0432\u0430\u043c\")) {     findNewsByKeywordsManual(chatId);   } else if (messageText.equals(\"Top 20\")) {     showTop(chatId);   } else if (messageText.equals(\"\u0412\u0441\u0435 \u043d\u043e\u0432\u043e\u0441\u0442\u0438\")) {     fullSearch(chatId);   } else {     switch (messageText) {      case \"\/settings\" -> getSettings(chatId);      case \"\/keywords\", \"\/list_key\" -> showKeywordsList(chatId);      case \"\/info\" -> infoKeyboard(chatId);     }   } }<\/code><\/pre>\n<h2>\u041f\u043e\u0434\u044b\u0442\u043e\u0436\u0438\u043c<\/h2>\n<p>\u0411\u043e\u0442 \u0443 \u043c\u0435\u043d\u044f \u043f\u0435\u0440\u0432\u044b\u0439, \u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0439, \u0442\u0430\u043a \u0441\u043a\u0430\u0437\u0430\u0442\u044c. \u0414\u0435\u043b\u0430\u044e \u0434\u043e\u043b\u0433\u043e, \u0443\u0447\u0443\u0441\u044c. \u041a\u043e\u0433\u0434\u0430 \u0431\u0443\u0434\u0443 \u0434\u0435\u043b\u0430\u0442\u044c \u043d\u043e\u0432\u043e\u0433\u043e \u0431\u043e\u0442\u0430, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u043b\u0443\u0447\u0448\u0435 \u043f\u043e \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0443, \u0445\u043e\u0442\u044f \u044f \u0438 \u0437\u0434\u0435\u0441\u044c \u043f\u043e\u0441\u0442\u0430\u0440\u0430\u043b\u0441\u044f \u043d\u0430 \u0441\u043b\u0430\u0432\u0443.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u043e \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u044e \u043a\u043e\u0434\u0430 \u0438\u043b\u0438 \u0435\u0449\u0451 \u043a\u0430\u043a\u0438\u0435 \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0435 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0438, \u043f\u0438\u0448\u0438\u0442\u0435 \u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u0445, \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u044e \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c. \u0418\u043b\u0438 \u0447\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u043b\u0443\u0447\u0448\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u044e <strong>webHook<\/strong> \u0432\u043c\u0435\u0441\u0442\u043e <strong>longPolling.<\/strong><\/p>\n<p>\u0421\u043f\u0430\u0441\u0438\u0431\u043e \u041f\u0430\u0432\u043b\u0443 \u0414\u0443\u0440\u043e\u0432\u0443 \u0437\u0430 <strong>BotFather!<\/strong><\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/808535\/\"> https:\/\/habr.com\/ru\/articles\/808535\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e \u0432\u0430\u0448\u0435\u043c\u0443 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044e \u0441\u0432\u043e\u0451 \u0432\u0438\u0434\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430, \u0442.\u043a. \u043d\u0438\u0447\u0435\u0433\u043e \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0433\u043e \u043f\u043e\u043a\u0430 \u043d\u0435 \u043d\u0430\u0445\u043e\u0434\u0438\u043b. \u0414\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0439 \u043d\u0430 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u043a\u043d\u043e\u043f\u043a\u0438 \u0432 \u0431\u043e\u0442\u0435 <a href=\"https:\/\/t.me\/AvandyNewsBot\" rel=\"noopener noreferrer nofollow\"><strong>Avandy News<\/strong><\/a><strong> (<\/strong>\u0431\u043e\u0442 \u043e\u0441\u043d\u043e\u0432\u0430\u043d \u043d\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0435 <a href=\"https:\/\/avandy-news.ru\/\" rel=\"noopener noreferrer nofollow\">Avandy News Analysis<\/a>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0430 \u0432 <a href=\"https:\/\/reestr.digital.gov.ru\/reestr\/1483979\/\" rel=\"noopener noreferrer nofollow\">\u0420\u0435\u0435\u0441\u0442\u0440 \u0440\u043e\u0441\u0441\u0438\u0439\u0441\u043a\u043e\u0433\u043e \u041f\u041e<\/a>).<\/p>\n<p><strong>\u0421\u0442\u0435\u043a: <\/strong>Java 17, Spring Boot 3.15, Postgresql 16.1<\/p>\n<h2>\u041a \u043d\u0430\u043c \u043f\u0440\u0438\u0448\u043b\u0438 \u0433\u043e\u0441\u0442\u0438 \u0438..<\/h2>\n<h2>\u0421\u0438\u0442\u0443\u0430\u0446\u0438\u044f \u2116 1 (\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 Inline \u043a\u043d\u043e\u043f\u043e\u043a)<\/h2>\n<p>\u041e\u043d\u0438 \u0445\u043e\u0442\u044f\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0431\u043e\u0442\u0443 \u043b\u044e\u0431\u043e\u0435 \u0441\u043b\u043e\u0432\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0438\u0441\u043a\u0430\u0442\u044c \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0438, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0435 \u044d\u0442\u043e \u0441\u043b\u043e\u0432\u043e.<\/p>\n<p><strong>\u0412\u043a\u0440\u0430\u0442\u0446\u0435<\/strong><\/p>\n<ol>\n<li>\n<p>\u0421\u043e\u0437\u0434\u0430\u0451\u043c \u043f\u043e\u0442\u043e\u043a\u043e\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u0443\u044e \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044e <strong>ConcurrentHashMap<\/strong>, \u0433\u0434\u0435 \u043a\u043b\u044e\u0447 \u044d\u0442\u043e \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 id \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u0430\u0451\u0442 \u0441\u0430\u043c Telegram (chat_id).<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0442\u0435\u043a\u0441\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u0440\u0438\u0448\u043b\u043e <strong>update.getMessage().getText()<\/strong><\/p>\n<\/li>\n<li>\n<p>\u0414\u0435\u043b\u0430\u0435\u043c \u043a\u0435\u0439\u0441\u044b \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0438\u0441\u0445\u043e\u0434\u044f \u0438\u0437 \u043b\u043e\u0433\u0438\u043a\u0438 \u0432\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f (\u0443 \u043c\u0435\u043d\u044f \u0442\u0430\u043a\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435, \u043d\u0435 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u044e\u0449\u0435\u0435 \u043d\u0438 \u0441 \u043e\u0434\u043d\u0438\u043c \u043a\u0435\u0439\u0441\u043e\u043c, \u043f\u043e\u043f\u0430\u0434\u0430\u0435\u0442 \u0432 \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434. \u0422\u0430\u043c \u0443\u0436\u0435 \u0435\u0441\u0442\u044c \u0441\u0432\u043e\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043f\u043e \u043e\u043f\u044b\u0442\u0443 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043f\u0430\u0440\u044b \u0442\u044b\u0441\u044f\u0447 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439)<\/p>\n<\/li>\n<li>\n<p>\u0421\u043e\u0437\u0434\u0430\u0451\u043c \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u0443 <strong>InlineKeyboardMarkup<\/strong> \u0441 \u043a\u043d\u043e\u043f\u043a\u0430\u043c\u0438<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u044b \u043a\u043b\u0430\u0434\u0451\u043c \u0441\u043b\u043e\u0432\u043e \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u0433\u043e\u0441\u0442\u044f \u0432 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044e <strong>\u043f.1<\/strong><\/p>\n<\/li>\n<li>\n<p>\u0412 \u0441\u0435\u043a\u0446\u0438\u0438 <strong>update.hasCallbackQuery() <\/strong>\u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0438\u043c\u044f \u043d\u0430\u0436\u0430\u0442\u043e\u0439 \u043a\u043d\u043e\u043f\u043a\u0438 \u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043a \u0435\u0451 \u043a\u0435\u0439\u0441\u0443<\/p>\n<\/li>\n<li>\n<p>\u0411\u0435\u0440\u0451\u043c \u0441\u043b\u043e\u0432\u043e \u0438\u0437 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0451\u043c \u0435\u0433\u043e \u0432 \u043d\u0443\u0436\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438. \u0412\u0441\u0451.<\/p>\n<\/li>\n<\/ol>\n<p><strong>\u041d\u0415 \u0432\u043a\u0440\u0430\u0442\u0446\u0435<\/strong><\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u0420\u0430\u043d\u0435\u0435 \u0431\u044b\u043b\u043e \u0430\u0436 5 \u043a\u043d\u043e\u043f\u043e\u043a (\u0443\u043f\u0440\u043e\u0449\u0430\u0435\u043c, \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u043c..)<\/figcaption><\/div>\n<\/figure>\n<p>\u041a\u0430\u043a \u044d\u0442\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0432 \u043a\u043e\u0434\u0435:<\/p>\n<pre><code class=\"java\">\/* 1 \u0448\u0430\u0433. \u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0441\u043b\u043e\u0432\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0438\u0448\u0443\u0442 \u0431\u043e\u0442\u0443 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e,    \u043d\u0435 \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u043b\u0438\u0441\u044c - \u0434\u0435\u043b\u0430\u0435\u043c \u043f\u043e\u0442\u043e\u043a\u043e\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u0443\u044e \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044e     \u0433\u0434\u0435 \u043a\u043b\u044e\u0447 Long \u044d\u0442\u043e \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 chat_id, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043b\u044e\u0431\u0435\u0437\u043d\u043e \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 Telegram *\/ private final Map&lt;Long, String> oneWordFromChat = new ConcurrentHashMap&lt;>();  @Override public void onUpdateReceived(Update update) {     \/\/ 2 \u0448\u0430\u0433. \u0413\u043e\u0441\u0442\u044c \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u043b \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0438 \u043c\u044b \u0435\u0433\u043e \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u0438\u043b\u0438 \u0437\u0434\u0435\u0441\u044c     if (update.hasMessage() &amp;&amp; update.getMessage().hasText()) {         String messageText = update.getMessage().getText(); \/\/ = \"\u041c\u043e\u0441\u043a\u0432\u0430\"         long chatId = update.getMessage().getChatId(); \/\/ \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 id \u0433\u043e\u0441\u0442\u044f                \/\/ \u041f\u0440\u0438\u043d\u0443\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0432\u044b\u0445\u043e\u0434 \u0434\u043b\u044f \u043f\u0441\u0438\u0445\u043e\u0432 (\u043f\u043e\u0432\u0435\u0440\u044c\u0442\u0435 - \u0447\u0430\u0441\u0442\u043e \u043f\u0440\u0438\u043b\u0435\u0442\u0430\u0435\u0442)         List&lt;String> flugegeheimen = List.of(\"\u0441\u0442\u043e\u043f\", \"\/\u0441\u0442\u043e\u043f\", \"stop\", \"\/stop\");         \/\/ toLowerCase :)         if (flugegeheimen.contains(messageText.toLowerCase())) {           userStates.remove(chatId); \/\/ \u0421\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0431\u043e\u0442\u0430 (\u043e\u0431 \u044d\u0442\u043e\u043c \u043f\u043e\u0437\u0436\u0435)           nextKeyboard(chatId, \"\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u043e\u0442\u043c\u0435\u043d\u0435\u043d\u043e\"); \/\/ \u041e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0433\u043e\u0441\u0442\u044e                        } else if (messageText.startsWith(\"\")) {         } else if (messageText.equals(\"\")) {         } else {             \/* \u041e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b *\/             switch (messageText) {               case \"\/settings\" -> getSettings(chatId);               case \"\/info\" -> infoKeyboard(chatId);               \/\/ 3 \u0448\u0430\u0433. \u041c\u044b \u043f\u043e\u043f\u0430\u043b\u0438 \u0441\u044e\u0434\u0430, \u0442.\u043a. \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \"\u041c\u043e\u0441\u043a\u0432\u0430\"                \/\/ \u043d\u0438 \u0441 \u043e\u0434\u043d\u0438\u043c \u043a\u0435\u0439\u0441\u043e\u043c \u043d\u0435 \u0441\u043e\u0432\u043f\u0430\u043b\u043e               default -> undefinedKeyboard(chatId, messageText);             }         }     } }<\/code><\/pre>\n<ol>\n<li>\n<p>\u0417\u0430\u0434\u0430\u0451\u043c \u0432\u043e\u043f\u0440\u043e\u0441 \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c \u043a\u043b\u0430\u0441\u0441\u0430 <strong>SendMessage<\/strong>, <strong>InlineKeyboardMarkup &#8212;<\/strong> 2 \u0448\u0442., \u043f\u043e\u0442\u043e\u043a\u043e\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0439 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 \u0438 \u043a\u0440\u0430\u0441\u0438\u0432\u043e\u0433\u043e \u0441\u043c\u0430\u0439\u043b\u0430 \u0434\u043b\u044f \u0441\u0433\u043b\u0430\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0438 \u043f\u043e\u0441\u043b\u0435 \u0441\u0442\u043e\u043b\u044c \u043f\u0440\u044f\u043c\u043e\u0433\u043e \u0432\u043e\u043f\u0440\u043e\u0441\u0430.<\/p>\n<\/li>\n<\/ol>\n<pre><code class=\"java\">\/\/ 4 \u0448\u0430\u0433. \u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u0443 InlineKeyboardMarkup \u0441 \u0434\u0432\u0443\u043c\u044f \u043a\u043d\u043e\u043f\u043a\u0430\u043c\u0438 private void undefinedKeyboard(long chatId, String word) {   \/\/ 5 \u0448\u0430\u0433. \u041a\u043b\u0430\u0434\u0451\u043c \u0441\u043b\u043e\u0432\u043e \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u0433\u043e\u0441\u0442\u044f \u0432 \u0440\u0430\u043d\u0435\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u0443\u044e \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044e   oneWordFromChat.put(chatId, word); \/\/ word = \"\u041c\u043e\u0441\u043a\u0432\u0430\"      \/\/ \u0414\u0435\u043b\u0430\u0435\u043c \u0434\u0432\u0443\u0445\u0441\u043b\u043e\u0439\u043d\u044b\u0439 \u0442\u043e\u0440\u0442 \u0438\u0437 \u043a\u043d\u043e\u043f\u043e\u043a   Map&lt;String, String> floor1 = new HashMap&lt;>();   Map&lt;String, String> floor2 = new HashMap&lt;>();    \/\/ \u041f\u043e\u043d\u044f\u0442\u043d\u043e \u043e\u0437\u0432\u0443\u0447\u0438\u0432\u0430\u0435\u043c \u0438\u043d\u0433\u0440\u0438\u0434\u0438\u0435\u043d\u0442\u044b \u0434\u043b\u044f \u0441\u0435\u0431\u044f \u0438 \u0433\u043e\u0441\u0442\u0435\u0439   floor1.put(\"ADD_KEYWORD_FROM_CHAT\", \"\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u043f\u043e\u0438\u0441\u043a\u0430\");   floor2.put(\"SEARCH_BY_WORD\", \"\u0418\u0441\u043a\u0430\u0442\u044c \u043d\u043e\u0432\u043e\u0441\u0442\u0438\");    \/\/ \u043a\u043e\u0434 maker \u043d\u0430 GitHub   sendMessage(chatId, \"\u0427\u0442\u043e \u0441 \u044d\u0442\u0438\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c? \" + \"\\uD83E\\uDDD0\",                InlineKeyboards.maker(floor1, floor2)); }<\/code><\/pre>\n<ol start=\"2\">\n<li>\n<p>\u0413\u043e\u0441\u0442\u0438 \u043d\u0430\u0436\u0438\u043c\u0430\u044e\u0442 \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 &#171;\u0418\u0441\u043a\u0430\u0442\u044c \u043d\u043e\u0432\u043e\u0441\u0442\u0438&#187;, \u043d\u043e \u043d\u0435 \u0444\u0430\u043a\u0442, \u0438<\/p>\n<\/li>\n<\/ol>\n<pre><code class=\"java\">if (update.hasMessage() &amp;&amp; update.getMessage().hasText()) {     \/\/ \u0437\u0434\u0435\u0441\u044c \u0441\u0435\u0439\u0447\u0430\u0441 \u043f\u0443\u0441\u0442\u043e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0438\u0434\u0451\u043c \u0434\u0430\u043b\u044c\u0448\u0435 } else if (update.hasCallbackQuery()) {   \/\/ 6 \u0448\u0430\u0433. \u0410 \u0432\u043e\u0442 \u0437\u0434\u0435\u0441\u044c \u0443\u0436\u0435 \u043b\u043e\u0432\u0438\u043c \u043d\u0430\u0436\u0430\u0442\u0443\u044e \u043a\u043d\u043e\u043f\u043a\u0443   String callbackData = update.getCallbackQuery().getData(); \/\/ = \"SEARCH_BY_WORD\"    switch (callbackData) {       case \"JOHN_COFFEY_MAM\" -> drinkCoffee(chatId, \"See The Green mile\");       \/\/ \u0437\u0430\u0448\u043b\u0438 \u0441\u044e\u0434\u0430       case \"SEARCH_BY_WORD\" ->         \/\/ 7 \u0448\u0430\u0433. \u041f\u0435\u0440\u0435\u0434\u0430\u0451\u043c \u0441\u043b\u043e\u0432\u043e \u0438\u0437 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 \u0432 \u043c\u0435\u0442\u043e\u0434 \u043f\u043e\u0438\u0441\u043a\u0430         wordSearch(chatId, oneWordFromChat.get(chatId));   }  }<\/code><\/pre>\n<ol start=\"3\">\n<li>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043e\u043d\u0438 \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u044e\u0442 \u0442\u0430\u043a\u043e\u0439 \u043e\u0442\u0432\u0435\u0442 (\u0432\u0438\u0434 \u043d\u043e\u0432\u043e\u0441\u0442\u0435\u0439 \u0432\u043e\u0437\u043c\u043e\u0436\u0435\u043d \u0432 5 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430\u0445). \u041a\u0430\u043a \u0432\u0438\u0434\u0438\u0442\u0435 \u043e\u043a\u043e\u043d\u0447\u0430\u043d\u0438\u044f \u0443 \u041c\u043e\u0441\u043a\u0432\u044b \u0440\u0430\u0437\u043d\u044b\u0435, \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u0430\u043a \u043f\u0440\u043e\u0441\u0438\u043b\u0438, \u043d\u043e \u044d\u0442\u043e \u0443\u0436\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u0434\u0440\u0443\u0433\u0430\u044f \u0438\u0441\u0442\u043e\u0440\u0438\u044f.<\/p>\n<figure class=\"bordered full-width\">\n<div><figcaption>\u0411\u0435\u0435\u0435\u0435\u0437 \u0442\u0435\u0435\u0435\u0435\u0431\u044f\u044f, \u0431\u0435\u0437 \u0442\u0435\u0431\u044f..<\/figcaption><\/div>\n<\/figure>\n<\/li>\n<\/ol>\n<h2>\u0421\u0438\u0442\u0443\u0430\u0446\u0438\u044f \u2116 2 (\u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0435 \u0432\u0432\u043e\u0434\u0430 \u0442\u0435\u043a\u0441\u0442\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c)<\/h2>\n<p>\u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c \u0433\u043e\u0441\u0442\u044c \u0440\u0435\u0448\u0438\u043b \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0441\u043b\u043e\u0432\u043e \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u043f\u043e\u0438\u0441\u043a\u0430.<\/p>\n<p>\u041e\u043d \u043d\u0430\u0436\u0438\u043c\u0430\u0435\u0442 <strong>\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c <\/strong>\u0438 \u0431\u043e\u0442 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442 \u0432 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u0432\u0432\u043e\u0434\u0430 \u0441 \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u044b \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f (\u0437\u0434\u0435\u0441\u044c \u0442\u043e\u0436\u0435 \u043f\u043e\u043b\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a, \u044e\u0437\u0435\u0440 \u0447\u0442\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0435 \u0442\u0432\u043e\u0440\u0438\u0442).<\/p>\n<p><strong>\u0412\u043a\u0440\u0430\u0442\u0446\u0435<\/strong><\/p>\n<ol>\n<li>\n<p>\u041d\u0430\u0436\u0430\u0442\u0438\u0435 \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443<\/p>\n<\/li>\n<li>\n<p>\u041f\u0435\u0440\u0435\u0432\u043e\u0434 \u0431\u043e\u0442\u0430 \u0432 \u043d\u0443\u0436\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435, \u043f\u0443\u0442\u0451\u043c \u0435\u0433\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0432 \u043f\u043e\u0442\u043e\u043a\u043e\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u0443\u044e \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044e \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u0433\u043e\u0441\u0442\u044f<\/p>\n<\/li>\n<li>\n<p>\u041e\u0436\u0438\u0434\u0430\u043d\u0438\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f<\/p>\n<\/li>\n<li>\n<p>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043f\u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c\u0443 \u0433\u043e\u0441\u0442\u044e \u0438 \u043f\u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c\u0443 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044e<\/p>\n<\/li>\n<\/ol>\n<p><strong>\u041d\u0415 \u0441\u043e\u0432\u0441\u0435\u043c \u0432\u043a\u0440\u0430\u0442\u0446\u0435<\/strong><\/p>\n<figure class=\"bordered full-width\">\n<div><figcaption>\u041d\u0430\u0436\u0430\u0442\u0430 \u043a\u043d\u043e\u043f\u043a\u0430 \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c<\/figcaption><\/div>\n<\/figure>\n<p>\u0412 \u0440\u0430\u0437\u0434\u0435\u043b <strong>hasCallbackQuery<\/strong> \u043b\u0435\u0442\u0438\u0442 <strong>callbackData<\/strong> \u0440\u0430\u0432\u043d\u044b\u0439 <strong>ADD_KEYWORD <\/strong>(\u0442\u0430\u043a \u043c\u044b \u043d\u0430\u0437\u0432\u0430\u043b\u0438 \u044d\u0442\u0443 \u043a\u043d\u043e\u043f\u043a\u0443 \u0432\u043d\u0443\u0442\u0440\u0438 \u0431\u043e\u0442\u0430) \u0438 \u043d\u0430\u0448 \u0431\u043e\u0442 \u043e\u0436\u0438\u0434\u0430\u0435\u0442 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u0442.\u0435. \u0435\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u043d\u0430 <strong>ADD_KEYWORDS<\/strong><\/p>\n<pre><code class=\"java\">\/\/ \u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0431\u043e\u0442\u0430 public enum UserState {     SEND_FEEDBACK,     \/\/..     ADD_KEYWORDS }<\/code><\/pre>\n<pre><code class=\"java\">\/* \u041a\u043b\u0430\u0441\u0441 \u0431\u043e\u0442\u0430 *\/ \/\/ 1. \u041a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0433\u0434\u0435 Long = chatId private final Map&lt;Long, UserState> userStates = new ConcurrentHashMap&lt;>();    if (update.hasMessage() &amp;&amp; update.getMessage().hasText()) {       \/\/ \u0437\u0434\u0435\u0441\u044c \u0441\u0435\u0439\u0447\u0430\u0441 \u043f\u0443\u0441\u0442\u043e   } else if (update.hasCallbackQuery()) {          \/\/ 2. \u041d\u0430\u0436\u0430\u0432 \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 \u043c\u044b \u043f\u043e\u043f\u0430\u0434\u0430\u0435\u043c \u0432 \u044d\u0442\u043e\u0442 \u043a\u0435\u0439\u0441, \u0442.\u043a. \"\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c\" = \"ADD_KEYWORD\"     case \"ADD_KEYWORD\" -> setBotState(chatId, UserState.ADD_KEYWORDS, addInListText);          \/\/ \u0421\u0431\u0440\u043e\u0441 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0431\u043e\u0442\u0430 \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0435\u0441\u043b\u0438 \u043e\u043d \u043d\u0430\u0436\u043c\u0451\u0442 \"\u041e\u0442\u043c\u0435\u043d\u0430\"     case \"CANCEL\" -> userStates.remove(chatId);    }    \/\/ 3. \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0431\u043e\u0442\u0430   private void setBotState(Long chatId, UserState state, String text) {       userStates.put(chatId, state);       \/\/ 4. \u0417\u0434\u0435\u0441\u044c \u0431\u043e\u0442 \u0438 \u043e\u0436\u0438\u0434\u0430\u0435\u0442 \u0432\u0432\u043e\u0434\u0430 \u0442\u0435\u043a\u0441\u0442\u0430. \u0422\u0443\u0442 \u0436\u0435 \u043c\u043e\u0436\u0435\u043c \u043e\u0442\u043c\u0435\u043d\u0438\u0442\u044c \u0432\u0432\u043e\u0434.       cancelKeyboard(chatId, text);   }    \/\/ \u041a\u043d\u043e\u043f\u043a\u0430 \u043e\u0442\u043c\u0435\u043d\u044b \u0432\u0432\u043e\u0434\u0430 \u0441\u043b\u043e\u0432   private void cancelKeyboard(long chatId, String text) {       Map&lt;String, String> buttons = new LinkedHashMap&lt;>();       buttons.put(\"CANCEL\", cancelButtonText);       sendMessage(chatId, text, InlineKeyboards.maker(buttons));   }      \/\/ \u041a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u0430 \u0440\u0430\u0437\u0434\u0435\u043b\u0430 \u0441 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438 \u0434\u043b\u044f \u043f\u043e\u0438\u0441\u043a\u0430   private void keywordsListKeyboard(long chatId, String text) {       Map&lt;String, String> buttons1 = new LinkedHashMap&lt;>();       Map&lt;String, String> buttons2 = new LinkedHashMap&lt;>();          buttons1.put(\"DELETE_KEYWORD\", delText);       buttons1.put(\"ADD_KEYWORD\", addText);       buttons2.put(\"SET_PERIOD\", intervalText);       buttons2.put(\"FIND_BY_KEYWORDS\", searchText);            sendMessage(chatId, text, InlineKeyboards.maker(buttons1, buttons2));   }   }<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0432\u0432\u043e\u0434\u0430 \u0442\u0435\u043a\u0441\u0442\u0430, \u043a\u043e\u0433\u0434\u0430 \u0431\u043e\u0442 \u0432 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0438 <strong>ADD_KEYWORDS,<\/strong> \u043c\u044b \u043b\u043e\u0432\u0438\u043c \u0432\u0432\u0435\u0434\u0451\u043d\u043d\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0443\u0436\u0435 \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 <strong>update.hasMessage()<\/strong> \u0433\u0434\u0435 \u0438 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0435\u0433\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430<\/p>\n<pre><code class=\"java\">\/\/ \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f if (update.hasMessage() &amp;&amp; update.getMessage().hasText()) {       String messageText = update.getMessage().getText();       long chatId = update.getMessage().getChatId();              \/\/ 5. \u0411\u0435\u0440\u0451\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0431\u043e\u0442\u0430 \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f       UserState userState = userStates.get(chatId);              \/\/ \u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0431\u043e\u0442\u0430 \u0441\u0435\u0439\u0447\u0430\u0441 - \u044d\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u043b\u043e\u0432 \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u043f\u043e\u0438\u0441\u043a\u0430       if (UserState.ADD_KEYWORDS.equals(userState)) {         \/\/ \u041e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c         String keywords = messageText.trim().toLowerCase();         addKeywords(chatId, keywords);       }      \/\/ \u0421\u0431\u0440\u043e\u0441 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f     userStates.remove(chatId);    } else if (update.hasCallbackQuery()) {   \/\/.. }<\/code><\/pre>\n<h2>\u0421\u0438\u0442\u0443\u0430\u0446\u0438\u044f \u2116 3 (\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0441 \u0444\u043e\u0442\u043e)<\/h2>\n<p>\u0413\u043e\u0441\u0442\u044c \u0437\u0430\u0445\u043e\u0442\u0435\u043b \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043d\u0430\u043c \u0441\u0432\u043e\u0438 \u0432\u043f\u0435\u0447\u0430\u0442\u043b\u0435\u043d\u0438\u044f \u043e\u0442 \u0432\u0435\u0447\u0435\u0440\u0430 \u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0438\u0442\u044c \u0444\u043e\u0442\u043e.<\/p>\n<p><strong>\u0412\u043a\u0440\u0430\u0442\u0446\u0435<\/strong><\/p>\n<ol>\n<li>\n<p>\u041d\u0430\u0436\u0430\u0442\u0438\u0435 \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443<\/p>\n<\/li>\n<li>\n<p>\u041f\u0435\u0440\u0435\u0432\u043e\u0434 \u0431\u043e\u0442\u0430 \u0432 \u043d\u0443\u0436\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435, \u043f\u0443\u0442\u0451\u043c \u0435\u0433\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0432 \u043f\u043e\u0442\u043e\u043a\u043e\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u0443\u044e \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044e \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u0433\u043e\u0441\u0442\u044f<\/p>\n<\/li>\n<li>\n<p>\u041e\u0436\u0438\u0434\u0430\u043d\u0438\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f<\/p>\n<\/li>\n<li>\n<p>\u041e\u0442\u0434\u0435\u043b\u044c\u043d\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0441 \u0444\u043e\u0442\u043e<\/p>\n<\/li>\n<\/ol>\n<p><strong>\u041d\u0435\u0442<\/strong><\/p>\n<figure class=\"bordered full-width\"><\/figure>\n<pre><code class=\"java\">\/\/ \u041f\u043e\u0441\u043b\u0435 \u043d\u0430\u0436\u0430\u0442\u0438\u044f \u043a\u043d\u043e\u043f\u043a\u0438 \"\u041d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043e\u0442\u0437\u044b\u0432\" if (update.hasMessage() &amp;&amp; update.getMessage().hasText()) {} else if (update.hasCallbackQuery()) {       \/\/ \u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0441\u0442\u0430\u0442\u0443\u0441 \u0431\u043e\u0442\u0430 \u0432 \u0440\u0435\u0436\u0438\u043c SEND_FEEDBACK \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u0433\u043e\u0441\u0442\u044f       case \"FEEDBACK\" -> setBotState(chatId, UserState.SEND_FEEDBACK); }<\/code><\/pre>\n<pre><code class=\"java\">\/\/ \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0441 \u0444\u043e\u0442\u043e @Override public void onUpdateReceived(Update update) {     if (update.hasMessage() &amp;&amp; update.getMessage().hasPhoto()) {           long chatId = update.getMessage().getChatId();           \/\/ \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0431\u043e\u0442\u0430           UserState userState = userStates.get(chatId);          \/\/ update \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0441\u043a\u0440\u0438\u043d\u0448\u043e\u0442         if (UserState.SEND_FEEDBACK.equals(userState)) {             \/\/ \u041e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0443 \u0441 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c \u0441\u043a\u0440\u0438\u043d\u0448\u043e\u0442\u0430             sendFeedbackWithPhoto(update);             \/\/ \u0421\u0431\u0440\u043e\u0441 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0431\u043e\u0442\u0430             userStates.remove(chatId);             \/\/ \u0423\u0432\u0435\u0434\u043e\u043c\u043b\u044f\u0435\u043c, \u0447\u0442\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0443\u0441\u043f\u0435\u0448\u043d\u0430             sendMessage(chatId, \"\u0414\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043e \u2714\ufe0f\");         }                 }      else if (update.hasMessage() &amp;&amp; update.getMessage().hasText()) {}      else if (update.hasCallbackQuery()) {} }  \/\/ \u041e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u043e\u0442\u0437\u044b\u0432\u0430 \u043f\u043e\u0432\u0430\u0440\u0443 \u0441 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c \u0441\u043a\u0440\u0438\u043d\u0448\u043e\u0442\u0430 (\u0435\u0441\u043b\u0438 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0449\u0435, \u0442\u043e \u0441\u043a\u0430\u0436\u0438\u0442\u0435 \u043a\u0430\u043a) private void sendFeedbackWithPhoto(Update update) {     long chatIdFrom = update.getMessage().getChatId();     String userName = userRepository.findNameByChatId(chatIdFrom);     String caption = update.getMessage().getCaption();     if (caption == null) caption = \"\u043d\u0435 \u0443\u0434\u043e\u0441\u0443\u0436\u0438\u043b\u0441\u044f..\";     List&lt;PhotoSize> photos = update.getMessage().getPhoto();      SendPhoto sendPhoto = new SendPhoto();     sendPhoto.setChatId(OWNER_ID);     sendPhoto.setCaption(\"Message from \" + userName + \", \" + chatIdFrom + \":\\n\" + caption);      List&lt;PhotoSize> photo = update.getMessage().getPhoto();     if (photo == null) return;     try {         String<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-373946","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/373946","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=373946"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/373946\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=373946"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=373946"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=373946"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}