{"id":350997,"date":"2023-07-30T15:02:19","date_gmt":"2023-07-30T15:02:19","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=350997"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=350997","title":{"rendered":"<span>\u042d\u043a\u0441\u043f\u0440\u0435\u0441\u0441 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 Telegram \u0431\u043e\u0442\u0430 \u043d\u0430 C#<\/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<h2>\u0414\u043e\u0431\u0440\u044b\u0439 \u0434\u0435\u043d\u044c, \u0443\u0432\u0430\u0436\u0430\u0435\u043c\u044b\u0435 \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u0438!<\/h2>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0431\u044b \u0445\u043e\u0442\u0435\u043b \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0431\u043e\u0442\u0430 \u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c \u043d\u0430 C# \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043d\u0430\u0431\u043e\u0440\u0430 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 SKitLs.Bots.Telegram &#8212; \u043c\u043e\u043b\u043e\u0434\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0441 \u0446\u0435\u043b\u044c\u044e \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0431\u043e\u0442\u043e\u0432.<\/p>\n<p>\u0421\u0430\u043c\u043e \u043f\u043e \u0441\u0435\u0431\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u043e \u0441 \u0446\u0435\u043b\u044c\u044e \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0431\u043e\u0442\u043e\u0432 \u0438\u0437 \u0440\u0443\u0442\u0438\u043d\u043d\u043e\u0433\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f if-else \u0432 \u0441\u0432\u043e\u0435\u043e\u0431\u0440\u0430\u0437\u043d\u044b\u0439 \u0434\u0438\u0437\u0430\u0439\u043d-\u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 .NET \u0438 C#.<\/p>\n<h2>\u041e SKitLs.Bots.Telegram<\/h2>\n<p>\u0411\u043e\u043b\u044c\u0448\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u043c\u0435\u0442\u043e\u0434\u0438\u0447\u0435\u043a \u043f\u043e \u0442\u0433-\u0431\u043e\u0442\u0430\u043c \u043d\u0430 C# \u043e\u043f\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 <em>Telegram.Bot \u0438<\/em> <em>Telegram.Bot.Extentions.Polling<\/em>  (\u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e, \u043a \u0441\u043b\u043e\u0432\u0443, \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0445 \u0432\u044b\u043f\u0443\u0441\u043a\u0430\u0445 \u043f\u0435\u0440\u0435\u043a\u043e\u0447\u0435\u0432\u0430\u043b \u0432 \u0441\u0430\u043c <em>Telegram.Bot<\/em>).<\/p>\n<p>\u0422\u0435\u043c \u043d\u0435 \u043c\u0435\u043d\u0435\u0435, <em>Telegram.Bot<\/em> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043b\u0438\u0448\u044c \u043c\u043e\u0441\u0442\u043e\u043c \u043c\u0435\u0436\u0434\u0443 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u043c \u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u043c, \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u044e\u0449\u0438\u043c \u0441\u0432\u044f\u0437\u044c \u0441 API Telegram.<\/p>\n<p>\u0412 \u0442\u043e \u0436\u0435 \u0432\u0440\u0435\u043c\u044f \u0438\u0434\u0435\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f SKitLs \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u0438 \u0442\u0438\u043f\u0438\u0437\u0430\u0446\u0438\u0438 \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0439 \u0438 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0434\u043b\u044f \u0433\u0438\u0431\u043a\u043e\u0433\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043c\u043e\u0434\u0435\u043b\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044f \u0443\u0436\u0435 \u0433\u043e\u0442\u043e\u0432\u0443\u044e, \u0441\u0432\u043e\u044e \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u0443\u044e \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443.<\/p>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u044d\u0442\u0443 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443 \u043d\u0430 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c \u043a\u0435\u0439\u0441\u0435: \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u0431\u043e\u0442\u0430, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0435\u0433\u043e \u043f\u0440\u043e\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u043f\u043e\u0433\u043e\u0434\u0443 \u0432 \u0433\u043e\u0440\u043e\u0434\u0430\u0445 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e API \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u042f\u043d\u0434\u0435\u043a\u0441.\u041f\u043e\u0433\u043e\u0434\u0430 \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0435 \u0433\u043e\u0440\u043e\u0434\u0430 \u0432 \u0441\u043f\u0438\u0441\u043e\u043a \u0438\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0433\u043e.<\/p>\n<p>\u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u044f \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u044e \u043d\u0430 \u0443\u0432\u0435\u0440\u0435\u043d\u043d\u044b\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u044f, \u0430 \u043f\u043e\u0442\u043e\u043c\u0443 \u043f\u043e\u0441\u0442\u0430\u0440\u0430\u044e\u0441\u044c \u043e\u0441\u043e\u0431\u043e \u043d\u0435 \u0432\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u043e\u0431\u044a\u044f\u0441\u043d\u0435\u043d\u0438\u0435 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u0432\u0435\u0449\u0435\u0439 \u0432\u0440\u043e\u0434\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043a\u043e\u043d\u0441\u043e\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430.<\/p>\n<p>\u0418\u0442\u043e\u0433\u043e\u0432\u043e\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 \u0440\u0430\u0437\u043c\u0435\u0449\u0451\u043d \u043d\u0430 <a href=\"https:\/\/github.com\/Sargeras02\/SKitLs-WeatherBot.git\" rel=\"noopener noreferrer nofollow\">GitHub<\/a> \u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0434\u043b\u044f \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u043b\u0435\u043d\u0438\u044f.<\/p>\n<h2>\u041d\u0435 \u0431\u0443\u0434\u0435\u043c \u043c\u0435\u0434\u043b\u0438\u0442\u044c<\/h2>\n<p>\u0421\u043e\u0437\u0434\u0430\u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c\u043d\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 \u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0432 nuget SKitLs.Bots.Telegram.Core &#8212; \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0439 \u043c\u043e\u0434\u0443\u043b\u044c \u0440\u0435\u0448\u0435\u043d\u0438\u044f, &#8212; \u044f \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u043b \u0441\u0435\u0431\u0435 \u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0434 \u0438\u0437 &#171;Quick Start&#187; <a href=\"https:\/\/github.com\/Sargeras02\/SKitLs.Bots.Telegram.git\" rel=\"noopener noreferrer nofollow\">\u0433\u0438\u0442\u0445\u0430\u0431 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b<\/a> \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u0447\u0442\u043e\u0431\u044b \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f \u0432 \u0440\u0435\u043b\u0435\u0432\u0430\u043d\u0442\u043d\u043e\u0441\u0442\u0438 \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f.<\/p>\n<pre><code class=\"cs\">static async Task Main(string[] args) {     var privateMessages = new DefaultSignedMessageUpdateHandler();     var privateTexts = new DefaultSignedMessageTextUpdateHandler     {         CommandsManager = new DefaultActionManager&lt;SignedMessageTextUpdate>()     };     privateTexts.CommandsManager.AddSafely(StartCommand);     privateMessages.TextMessageUpdateHandler = privateTexts;      ChatDesigner privates = ChatDesigner.NewDesigner()        .UseMessageHandler(privateMessages);      await BotBuilder.NewBuilder(\"YOUR_TOKEN\")        .EnablePrivates(privates)        .Build()        .Listen(); }  private static DefaultCommand StartCommand => new(\"start\", Do_StartAsync); private static async Task Do_StartAsync(SignedMessageTextUpdate update) {     await update.Owner.DeliveryService.ReplyToSender(\"Hello, world!\", update); }<\/code><\/pre>\n<p>\u0427\u0442\u043e \u0436\u0435, \u0432\u0441\u0451 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/249\/88e\/e7a\/24988ee7a168d5b49d85dde1c2995e5d.png\" alt=\"\u0420\u0435\u0430\u043a\u0446\u0438\u044f \u043d\u0430 \/start\" title=\"\u0420\u0435\u0430\u043a\u0446\u0438\u044f \u043d\u0430 \/start\" width=\"1248\" height=\"985\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/249\/88e\/e7a\/24988ee7a168d5b49d85dde1c2995e5d.png\"\/><\/p>\n<div><figcaption>\u0420\u0435\u0430\u043a\u0446\u0438\u044f \u043d\u0430 \/start<\/figcaption><\/div>\n<\/figure>\n<p>\u0415\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u0430\u044f \u0432\u043e\u0437\u043d\u0438\u043a\u0448\u0430\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u0441\u043a\u0440\u044b\u0442\u043e\u0439 \u0437\u0430 \u043a\u0443\u043b\u0438\u0441\u0430\u043c\u0438 \u0438 \u043d\u0435 \u0432\u0438\u0434\u0438\u0442\u0441\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e. \u0414\u0435\u043b\u043e \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0432\u044b\u0432\u043e\u0434 \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0430\u0435\u0442 \u043d\u0430\u0441 \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0437\u0440\u0435\u0448\u0438\u0442\u044c \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u0441\u0442\u0440\u043e\u043a\u0438:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/725\/9d2\/755\/7259d2755ef9b02b1b355b87fbbcb355.png\" alt=\"\u0421\u043a\u0440\u044b\u0442\u0430\u044f \u043e\u0448\u0438\u0431\u043a\u0430\" title=\"\u0421\u043a\u0440\u044b\u0442\u0430\u044f \u043e\u0448\u0438\u0431\u043a\u0430\" width=\"1152\" height=\"691\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/725\/9d2\/755\/7259d2755ef9b02b1b355b87fbbcb355.png\"\/><\/p>\n<div><figcaption>\u0421\u043a\u0440\u044b\u0442\u0430\u044f \u043e\u0448\u0438\u0431\u043a\u0430<\/figcaption><\/div>\n<\/figure>\n<p>\u0414\u0435\u043b\u043e \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f SKitLs.Bots.Telegram \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0442 \u043e\u0442\u043b\u0430\u0434\u043a\u0443 \u043d\u0430 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u044f\u0437\u044b\u043a\u0430\u0445. \u0414\u043b\u044f \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0442\u0430\u043a\u0436\u0435 \u0441\u043a\u0430\u0447\u0430\u0442\u044c \u043d\u0443\u0436\u043d\u044b\u0435 \u044f\u0437\u044b\u043a\u043e\u0432\u044b\u0435 \u043f\u0430\u043a\u0435\u0442\u044b, \u043e\u043f\u044f\u0442\u044c \u0436\u0435, \u0441\u043e <a href=\"https:\/\/github.com\/Sargeras02\/SKitLs.Bots.Telegram.git\" rel=\"noopener noreferrer nofollow\">\u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0433\u0438\u0442\u0445\u0430\u0431<\/a> \u0438\u0437 \u043f\u0430\u043f\u043a\u0438 &#171;locals&#187;.<\/p>\n<p>\u041a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u043c\u044b \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u043b\u0438, \u0443\u043a\u0430\u0436\u0435\u043c \u043f\u0443\u0442\u044c \u043a \u043d\u0430\u0448\u0435\u0439 \u043f\u0430\u043f\u043a\u0435 \u0438 \u0437\u0430\u0442\u0435\u043c \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u044f\u0437\u044b\u043a \u043e\u0442\u043b\u0430\u0434\u043a\u0438. \u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e, \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043f\u043e\u0434\u0433\u0440\u0443\u0436\u0430\u0435\u0442 \u044f\u0437\u044b\u043a\u043e\u0432\u044b\u0435 \u043f\u0430\u043a\u0435\u0442\u044b \u0438\u0437 \u043f\u0430\u043f\u043a\u0438 &#171;resources\/locals&#187;, \u043d\u043e \u043c\u044b \u0443\u043a\u0430\u0436\u0435\u043c \u044d\u0442\u043e \u044f\u0432\u043d\u043e, \u0434\u043b\u044f \u043f\u043e\u043b\u043d\u043e\u0442\u044b \u043a\u0430\u0440\u0442\u0438\u043d\u044b.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/48f\/cf3\/1b0\/48fcf31b00e21feb1c6e1b82eb5a8334.png\" alt=\"\u0414\u0435\u0440\u0435\u0432\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f. \u042f\u0437\u044b\u043a\u043e\u0432\u044b\u0435 \u043f\u0430\u043a\u0435\u0442\u044b\" title=\"\u0414\u0435\u0440\u0435\u0432\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f. \u042f\u0437\u044b\u043a\u043e\u0432\u044b\u0435 \u043f\u0430\u043a\u0435\u0442\u044b\" width=\"455\" height=\"198\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/48f\/cf3\/1b0\/48fcf31b00e21feb1c6e1b82eb5a8334.png\"\/><\/p>\n<div><figcaption>\u0414\u0435\u0440\u0435\u0432\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f. \u042f\u0437\u044b\u043a\u043e\u0432\u044b\u0435 \u043f\u0430\u043a\u0435\u0442\u044b<\/figcaption><\/div>\n<\/figure>\n<pre><code class=\"cs\">static async Task Main(string[] args) {     BotBuilder.DebugSettings.DebugLanguage = LangKey.RU;     BotBuilder.DebugSettings.UpdateLocalsPath(\"resources\/locals\");        var privateMessages = new DefaultSignedMessageUpdateHandler();     \/\/ ... }<\/code><\/pre>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/3e3\/8af\/eb8\/3e38afeb862141e3152d838d08880a93.png\" width=\"1152\" height=\"691\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/3e3\/8af\/eb8\/3e38afeb862141e3152d838d08880a93.png\"\/><\/figure>\n<p>\u0427\u0442\u043e \u0436\u0435, \u043d\u0430 \u0434\u0430\u043d\u043d\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u043d\u0430\u0448\u0430 \u0437\u0430\u0442\u0435\u044f \u0441\u043e \u0441\u043c\u0435\u043d\u043d\u043e\u0439 \u044f\u0437\u044b\u043a\u0430 \u043e\u0442\u043b\u0430\u0434\u043a\u0438 \u043f\u0440\u043e\u0432\u0430\u043b\u0438\u043b\u0430\u0441\u044c: \u0432\u044b\u0432\u043e\u0434 \u043e\u0441\u0442\u0430\u043b\u0441\u044f \u043d\u0430 \u0430\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u043e\u043c. \u041e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u043d\u0430\u0434\u0435\u044f\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u0432 \u0431\u0443\u0434\u0443\u0449\u0438\u0445 \u0432\u0435\u0440\u0441\u0438\u044f\u0445 (\u043d\u0430 \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f &#8212; <strong>1.4.3<\/strong>) \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043e.<\/p>\n<p>\u0421\u0435\u0439\u0447\u0430\u0441 \u0436\u0435, \u043a\u043e\u0433\u0434\u0430 \u0432\u0441\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u044b, \u0432\u0435\u0440\u043d\u0451\u043c\u0441\u044f \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043a \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e \u0431\u043e\u0442\u0430.<\/p>\n<h2>\u041f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435<\/h2>\n<p>\u0418\u0442\u0430\u043a, \u043a\u0430\u043a \u044f \u0432\u0438\u0436\u0443 \u0434\u0430\u043d\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435?<\/p>\n<p>\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0434\u043e\u043b\u0436\u0435\u043d \u0438\u043c\u0435\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c: \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043f\u043e\u0433\u043e\u0434\u0443 \u0432 \u0433\u043e\u0440\u043e\u0434\u0435, \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0433\u043e\u0440\u043e\u0434 \u0432 \u0438\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0435, \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0438\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0435, \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0438\u0437 \u0438\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0433\u043e.<\/p>\n<p>\u0412\u0441\u0451, \u0447\u0442\u043e \u043a\u0430\u0441\u0430\u0435\u0442\u0441\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0438 \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0446\u0438\u0438 \u0434\u0430\u043d\u043d\u044b\u0445, \u0432 \u0438\u0434\u0435\u0430\u043b\u0435 \u043c\u043e\u0436\u0435\u0442 \u0440\u0435\u0448\u0430\u0442\u044c\u0441\u044f \u0447\u0435\u0440\u0435\u0437 SKitLs.Bots.Telegram.DataBases. \u041e\u0434\u043d\u0430\u043a\u043e \u043d\u0430 \u043c\u043e\u043c\u0435\u043d\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u044c\u0438 \u0434\u0430\u043d\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435, \u0445\u043e\u0442\u044c \u0438 \u0447\u0438\u0441\u043b\u0438\u0442\u0441\u044f, \u043d\u043e \u0435\u0449\u0451 \u043d\u0435 \u0432\u044b\u043f\u0443\u0449\u0435\u043d\u043e \u0432 \u0432\u0438\u0434\u0435 \u043f\u0430\u043a\u0435\u0442\u0430, \u0430 \u043f\u043e\u0442\u043e\u043c\u0443 \u0431\u0443\u0434\u0435\u043c \u0438\u043c\u043f\u0440\u043e\u0432\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c.<\/p>\n<p>\u0420\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u0431\u043e\u0442\u0430 \u044f \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u044e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043e\u0434\u043d\u043e\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u044b &#8216;\/start&#8217; \u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 SKitLs.Bots.Telegram.PageNavs (1.3.1, \u0442\u0430\u043a\u0436\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d \u0447\u0435\u0440\u0435\u0437 NuGet), \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0435\u0433\u043e \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043c\u0438\u043d\u0438-\u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u044e \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u043e\u0434\u043d\u043e\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f: \u0441 \u0438\u0441\u0442\u043e\u0440\u0438\u0435\u0439 \u043f\u0435\u0440\u0435\u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0439 \u0438 \u043a\u043d\u043e\u043f\u043a\u0430\u043c\u0438. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0447\u0440\u0435\u0437\u043c\u0435\u0440\u043d\u043e\u0433\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u043a\u043e\u043c\u0430\u043d\u0434.<\/p>\n<p>*.PageNavs \u0437\u0430\u0432\u0438\u0441\u0438\u043c \u043e\u0442 *.AdvancedMessages \u0438 *.ArgedInteractions, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c.<\/p>\n<p>\u0412\u0432\u043e\u0434 \u0434\u0430\u043d\u043d\u044b\u0445 \u043e \u0433\u043e\u0440\u043e\u0434\u0435 \u0431\u044b\u043b\u043e \u0431\u044b \u043d\u0435\u043f\u043b\u043e\u0445\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e *.BotProcesses. \u041e\u0434\u043d\u0430\u043a\u043e \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u044d\u0442\u0430 \u0432\u0435\u0442\u0432\u044c, \u0442\u0430\u043a \u0436\u0435 \u043a\u0430\u043a \u0438 *.DataBases, \u0435\u0449\u0451 \u043d\u0435 \u0432\u044b\u043f\u0443\u0449\u0435\u043d\u0430, \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u0438\u043c\u043f\u0440\u043e\u0432\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c: \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043b\u0435\u0433\u043a\u043e\u0432\u0435\u0441\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043d\u044b\u0439 \u0430\u043d\u0430\u043b\u043e\u0433 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0432, \u0434\u043b\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 *.Stateful \u043f\u0430\u043a\u0435\u0442\u0430, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0435\u0433\u043e \u0437\u0430\u0434\u0430\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u043f\u043e\u043c\u0438\u043c\u043e \u043e\u0431\u0449\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0435\u0449\u0451 \u0438 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0435\u0433\u043e \u0442\u0435\u043a\u0443\u0449\u0435\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0438 \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0435\u0441\u0441\u0438\u0438.<\/p>\n<h2>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439<\/h2>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0431\u043b\u043e\u043a\u0435 \u0432\u043a\u0440\u0430\u0442\u0446\u0435 \u043f\u043e\u043a\u0430\u0436\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u0443\u044e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439. \u0427\u0442\u043e\u0431\u044b \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u043b\u0438\u0441\u044c \u043f\u043e\u0441\u043b\u0435 \u043a\u0430\u0436\u0434\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0438 \u043d\u0435 \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u043b\u0438\u0441\u044c &#8212; \u043e\u043d\u0438 \u0434\u043e\u043b\u0436\u043d\u044b \u0445\u0440\u0430\u043d\u0438\u0442\u044c\u0441\u044f \u0432 \u043f\u0430\u043c\u044f\u0442\u0438 \u0431\u043e\u0442\u0430. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u043e\u0433\u043e <code>UserManager : IUserManager<\/code>, \u0434\u043b\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e, \u0432 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0449\u0438\u0439 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f, \u0442\u0438\u043f\u0430 <code>BotUser : IStatefulUser<\/code>. \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0438\u0445.<\/p>\n<pre><code class=\"cs\">internal class BotUser : IStatefulUser {     public IUserState State { get; set; }     public long TelegramId { get; set; }      public BotUser(long telegramId)     {         State = new DefaultUserState();         TelegramId = telegramId;     }      public void ResetState() => State = new DefaultUserState(); }<\/code><\/pre>\n<pre><code class=\"cs\">internal class UserManager : IUsersManager {     public UserDataChanged? SignedEventHandled => null;      public List&lt;BotUser> Users { get; } = new();      public async Task&lt;IBotUser?> GetUserById(long telegramId) => await Task.FromResult(Users.Find(x => x.TelegramId ==  telegramId));      public async Task&lt;bool> IsUserRegistered(long telegramId) => await GetUserById(telegramId) is not null;      public async Task&lt;IBotUser?> RegisterNewUser(ICastedUpdate update)     {         var user = ChatScanner.GetSender(update.OriginalSource, this)!;         var @new = new BotUser(user.Id);         Users.Add(@new);         return await Task.FromResult(@new);     } }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u043c UserManager \u043a \u043d\u0430\u0448\u0435\u043c\u0443 \u0431\u043e\u0442\u0443 \u0432 ChatDesigner \u0438 \u043f\u0435\u0440\u0435\u043f\u0438\u0448\u0435\u043c \u043a\u043e\u0434 &#8216;\/start&#8217;, \u0447\u0442\u043e\u0431\u044b \u0431\u044b\u043b\u043e \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u043e \u0432\u0438\u0434\u043d\u043e, \u043a\u0430\u043a \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442.<\/p>\n<pre><code class=\"cs\">static async Task Main(string[] args) {     \/\/ ...      ChatDesigner privates = ChatDesigner.NewDesigner()         .UseUsersManager(new UserManager())         .UseMessageHandler(privateMessages);          \/\/ ... }  private static async Task Do_StartAsync(SignedMessageTextUpdate update) {     if (update.Sender is IStatefulUser sender)     {         int st = (sender.State.StateId + 1) % 2;         var text = st == 0             ? \"Start command \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u0430 \u0438\u0437 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f 0\"             : \"\u0410\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u043e \u0434\u0440\u0443\u0433\u043e\u0439 \u0442\u0435\u043a\u0441\u0442, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0441\u043a\u0430\u0437\u0430\u043d\u043e, \u0447\u0442\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f - 1\";         await update.Owner.DeliveryService.ReplyToSender(text, update);         sender.State = new DefaultUserState(st);     } }<\/code><\/pre>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/36e\/61b\/282\/36e61b2827ec34a6e6053c9511a4d375.png\" width=\"1248\" height=\"985\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/36e\/61b\/282\/36e61b2827ec34a6e6053c9511a4d375.png\"\/><\/figure>\n<p>\u041a\u0430\u043a \u043c\u044b \u0432\u0438\u0434\u0438\u043c, \u0440\u0435\u0430\u043a\u0446\u0438\u044f \u0431\u043e\u0442\u0430 \u043d\u0430 \u043e\u0434\u043d\u043e \u0438 \u0442\u043e \u0436\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043a\u0430\u0440\u0434\u0438\u043d\u0430\u043b\u044c\u043d\u043e \u0440\u0430\u0437\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f \u0434\u0430\u0436\u0435 \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043d\u043e\u0439 \u043b\u043e\u0433\u0438\u043a\u0438. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u043e\u0442 \u043d\u0430\u0441 \u044d\u0442\u043e \u043d\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043b\u043e \u0440\u0430\u0434\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0445 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u043a\u043e\u0434\u0430.<\/p>\n<p>\u041f\u043e\u0434\u043e\u0431\u043d\u043e\u0435 \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043d\u0430 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043d\u0430\u043c \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430 \u0432\u0432\u043e\u0434\u0430, \u0434\u043e\u0431\u0430\u0432\u0438\u0432 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f &#171;\u0412\u0432\u043e\u0434\u0438\u0442 \u0413\u043e\u0440\u043e\u0434&#187;, \u043f\u0440\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0431\u043e\u0442 \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u043d\u0435\u0442 \u0440\u0435\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430 \u043f\u0440\u043e\u0447\u0438\u0435 \u0440\u0430\u0437\u0434\u0440\u0430\u0436\u0438\u0442\u0435\u043b\u0438 \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442 \u0438\u043b\u0438 \u043d\u0435 \u043e\u0442\u043c\u0435\u043d\u0438\u0442 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0432\u0432\u043e\u0434\u0430.<\/p>\n<h2>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043c\u0435\u043d\u044e<\/h2>\n<p>\u041c\u0435\u043d\u044e (\u0438\u0437 *.PageNavs), \u043f\u0430\u0434\u0430\u044e\u0449\u0435\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u043f\u043e \u043a\u043e\u043c\u0430\u043d\u0434\u0435 &#8216;\/start&#8217; \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u0442\u044c \u0438\u0437 2 \u043a\u043d\u043e\u043f\u043e\u043a: \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u0430\u044f \u043a\u043d\u043e\u043f\u043a\u0430 &#8216;> \u0418\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0435&#8217; \u0438 \u0430\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u043e\u043d\u043d\u0430\u044f &#8216;\u041d\u0430\u0439\u0442\u0438&#8217;.<\/p>\n<p>\u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043c\u0435\u043d\u044e \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 \u0431\u043e\u0442\u0430 \u0441\u0435\u0440\u0432\u0438\u0441 \u0442\u0438\u043f IMenuManager, \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u044f\u0442\u0441\u044f \u0441\u0435\u0440\u0432\u0438\u0441 IArgsSerializer (\u0438\u0437 *.ArgedInteractions) \u0438 \u043f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u0430\u044f \u0441\u043b\u0443\u0436\u0431\u0430 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 (\u0438\u0437 *.AdvancedMessages).<\/p>\n<pre><code class=\"cs\">await BotBuilder.NewBuilder(\"your_token\")     .EnablePrivates(privates)     .AddService&lt;IArgsSerilalizerService>(new DefaultArgsSerilalizerService())     .AddService&lt;IMenuManager>(GetMenuManager())     .CustomDelievery(new AdvancedDeliverySystem())     .Build()     .Listen();<\/code><\/pre>\n<p>\u0420\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u0430 \u0447\u0435\u0440\u0435\u0437 <code>GetMenuManager()<\/code><\/p>\n<pre><code class=\"cs\">\/\/ Program private static IMenuManager GetMenuManager() {     var mm = new DefaultMenuManager();      var mainBody = new OutputMessageText(\"\u0414\u043e\u0431\u0440\u043e \u043f\u043e\u0436\u0430\u043b\u043e\u0432\u0430\u0442\u044c!\\n\\n\u0427\u0435\u0433\u043e \u0436\u0435\u043b\u0430\u0435\u0442\u0435?\");     var mainMenu = new PageNavMenu();     var mainPage = new StaticPage(\"main\", \"\u0413\u043b\u0430\u0432\u043d\u0430\u044f\", mainBody, mainMenu);      var savedBody = new DynamicMessage(u =>     {         return new OutputMessageText(\"_\u0417\u0434\u0435\u0441\u044c \u0431\u0443\u0434\u0443\u0442 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c\u0441\u044f \u0438\u0437\u0431\u0440\u0430\u043d\u043d\u044b\u0435..._\");     });     var savedPage = new WidgetPage(\"saved\", \"\u0418\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0435\", savedBody);      mainMenu.PathTo(savedPage);     mainMenu.AddAction(StartSearching);      mm.Define(mainPage);     mm.Define(savedPage);      return mm; }  \/\/ \u042d\u0442\u043e\u0442 \u043a\u043e\u043b\u043b\u0431\u044d\u043a \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u043f\u043e\u0438\u0441\u043a. \u041f\u043e\u043a\u0430 \u0447\u0442\u043e \u043f\u0440\u043e\u0442\u043e\u0442\u0438\u043f. private static DefaultCallback StartSearching => new(\"startSearch\", \"\u041d\u0430\u0439\u0442\u0438\", Do_SearchAsync); private static async Task Do_SearchAsync(SignedCallbackUpdate update) { }<\/code><\/pre>\n<p>\u041f\u0435\u0440\u0435\u043f\u0438\u0448\u0435\u043c \u043a\u043e\u043c\u0430\u043d\u0434\u0443 &#8216;\/start&#8217;, \u0447\u0442\u043e\u0431\u044b \u043e\u043d\u0430 \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u043b\u0430 \u043c\u0435\u043d\u044e<\/p>\n<pre><code class=\"cs\">\/\/ Program private static async Task Do_StartAsync(SignedMessageTextUpdate update) {     var mm = update.Owner.ResolveService&lt;IMenuManager>();      \/\/ \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043f\u043e id     \/\/ ...StaticPage( { \u044d\u0442\u043e id -> } \"main\", \"\u0413\u043b\u0430\u0432\u043d\u0430\u044f\"...     var page = mm.GetDefined(\"main\");          await mm.PushPageAsync(page, update); }<\/code><\/pre>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c. \u0412\u0441\u0451 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442. \u041f\u0440\u043e\u0431\u0443\u0435\u043c \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0438 \u0441\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u0435\u043c\u0441\u044f \u0441 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u043e\u0439.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/097\/528\/84e\/09752884ee26a084f2b57f7996fd3c72.png\" alt=\"\u041c\u0435\u043d\u044e \u043e\u0442\u043a\u0440\u044b\u043b\u043e\u0441\u044c\" title=\"\u041c\u0435\u043d\u044e \u043e\u0442\u043a\u0440\u044b\u043b\u043e\u0441\u044c\" width=\"1248\" height=\"985\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/097\/528\/84e\/09752884ee26a084f2b57f7996fd3c72.png\"\/><\/p>\n<div><figcaption>\u041c\u0435\u043d\u044e \u043e\u0442\u043a\u0440\u044b\u043b\u043e\u0441\u044c<\/figcaption><\/div>\n<\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/726\/b41\/0f9\/726b410f9ae60d42ccb9314174b44aa7.png\" alt=\"\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u043f\u043e\u043f\u044b\u0442\u043a\u0435 \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435.\" title=\"\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u043f\u043e\u043f\u044b\u0442\u043a\u0435 \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435.\" width=\"1146\" height=\"687\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/726\/b41\/0f9\/726b410f9ae60d42ccb9314174b44aa7.png\"\/><\/p>\n<div><figcaption>\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u043f\u043e\u043f\u044b\u0442\u043a\u0435 \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435.<\/figcaption><\/div>\n<\/figure>\n<p>\u0414\u0435\u043b\u043e \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043d\u0430\u0448 \u0431\u043e\u0442 \u043d\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u043d\u0438\u043a\u0430\u043a\u043e\u0433\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0434\u043b\u044f Callback-\u043e\u0432. \u0418 \u0445\u043e\u0442\u044f \u043c\u044b \u043d\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u043b\u0438 \u043d\u0430\u0448 \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 <code>DefaultCallback StartSearching<\/code>, \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e MenuManager \u0442\u0430\u043a\u0436\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d \u043d\u0430 Callback.<\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u044d\u0442\u043e \u043e\u0448\u0438\u0431\u043a\u0443, \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0432\u043e\u0440\u043e\u043d\u043a\u0443 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f\u043c\u0438 \u0442\u0438\u043f\u0430 Callback \u0438\u0437 \u043f\u0440\u0438\u0432\u0430\u0442\u043d\u044b\u0445 \u0447\u0430\u0442\u043e\u0432. \u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0432 \u043d\u0435\u0451 \u043d\u0430\u0448 \u043a\u043e\u043b\u043b\u0431\u044d\u043a \u0438 \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u043c MenuManager \u043a \u043d\u0430\u0448\u0435\u043c\u0443 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0443.<\/p>\n<pre><code class=\"cs\">static async Task Main(string[] args) {     \/\/ ...     \/\/ \u0421\u043e\u0437\u0434\u0430\u0451\u043c \u0432\u043e\u0440\u043e\u043d\u043a\u0443 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0434\u043b\u044f CallbackUpdate     var mm = GetMenuManager();     var privateCallbacks = new DefaultCallbackHandler()     {         CallbackManager = new DefaultActionManager&lt;SignedCallbackUpdate>(),     };      \/\/ \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043d\u0430\u0448 \u043a\u043e\u043b\u043b\u0431\u044d\u043a     privateCallbacks.CallbackManager.AddSafely(StartSearching);      \/\/ \u041f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u043c \u043c\u0435\u043d\u044e \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u043a \u043a\u043e\u043b\u043b\u0431\u044d\u043a \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u0443 (\u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u043e \u043a\u043e\u043b\u043b\u0431\u044d\u043a\u0430\u0445 mm \u0432 \u043d\u0430\u0448 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440)     mm.ApplyFor(privateCallbacks.CallbackManager);      \/\/ ...     ChatDesigner privates = ChatDesigner.NewDesigner()         .UseUsersManager(new UserManager())         .UseMessageHandler(privateMessages)         .UseCallbackHandler(privateCallbacks);  \/\/ &lt;- \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c     \/\/ ...     await BotBuilder.NewBuilder(\"your_token\")         .EnablePrivates(privates)         .AddService&lt;IArgsSerilalizerService>(new DefaultArgsSerilalizerService())         .AddService&lt;IMenuManager>(mm)  \/\/ &lt;- \u041e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c         .CustomDelievery(new AdvancedDeliverySystem())         .Build()         .Listen(); }<\/code><\/pre>\n<p>\u041a\u0430\u043a \u043c\u044b \u0432\u0438\u0434\u0438\u043c, \u043e\u043f\u044f\u0442\u044c \u043d\u0435 \u0445\u0432\u0430\u0442\u0430\u0435\u0442 \u044f\u0437\u044b\u043a\u043e\u0432\u044b\u0445 \u043f\u0430\u043a\u0435\u0442\u043e\u0432. \u0421\u043a\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u0438\u0445 \u043e\u0442\u0442\u0443\u0434\u0430 \u0436\u0435 \u0438 \u0440\u0430\u0437\u043c\u0435\u0449\u0430\u0435\u043c \u0432 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0439 \u043f\u0430\u043f\u043a\u0435.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/e7b\/d56\/d6c\/e7bd56d6c7c2d26bee40af7491147f99.png\" alt=\"\u041d\u0435\u0434\u043e\u0441\u0442\u0430\u044e\u0449\u0438\u0435 \u044f\u0437\u044b\u043a\u043e\u0432\u044b\u0435 \u043f\u0430\u043a\u0435\u0442\u044b\" title=\"\u041d\u0435\u0434\u043e\u0441\u0442\u0430\u044e\u0449\u0438\u0435 \u044f\u0437\u044b\u043a\u043e\u0432\u044b\u0435 \u043f\u0430\u043a\u0435\u0442\u044b\" width=\"1229\" height=\"386\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/e7b\/d56\/d6c\/e7bd56d6c7c2d26bee40af7491147f99.png\"\/><\/p>\n<div><figcaption>\u041d\u0435\u0434\u043e\u0441\u0442\u0430\u044e\u0449\u0438\u0435 \u044f\u0437\u044b\u043a\u043e\u0432\u044b\u0435 \u043f\u0430\u043a\u0435\u0442\u044b<\/figcaption><\/div>\n<\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/767\/ab1\/604\/767ab160490e18022bdf0f9f3baa420c.png\" alt=\"\u0413\u043b\u0430\u0432\u043d\u0430\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\" title=\"\u0413\u043b\u0430\u0432\u043d\u0430\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\" width=\"671\" height=\"296\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/767\/ab1\/604\/767ab160490e18022bdf0f9f3baa420c.png\"\/><\/p>\n<div><figcaption>\u0413\u043b\u0430\u0432\u043d\u0430\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430<\/figcaption><\/div>\n<\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/a19\/657\/5e0\/a196575e0228400a8f419aa169acaed8.png\" alt=\"\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\" title=\"\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\" width=\"671\" height=\"185\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/a19\/657\/5e0\/a196575e0228400a8f419aa169acaed8.png\"\/><\/p>\n<div><figcaption>\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430<\/figcaption><\/div>\n<\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/894\/788\/4d7\/8947884d7545fc1de4a0b25e64938db0.png\" alt=\"\u0421\u043d\u043e\u0432\u0430 \u0433\u043b\u0430\u0432\u043d\u0430\u044f \u043f\u043e\u0441\u043b\u0435 &quot;&lt;&lt; \u041d\u0430\u0437\u0430\u0434&quot;\" title=\"\u0421\u043d\u043e\u0432\u0430 \u0433\u043b\u0430\u0432\u043d\u0430\u044f \u043f\u043e\u0441\u043b\u0435 &quot;&lt;&lt; \u041d\u0430\u0437\u0430\u0434&quot;\" width=\"668\" height=\"296\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/894\/788\/4d7\/8947884d7545fc1de4a0b25e64938db0.png\"\/><\/p>\n<div><figcaption>\u0421\u043d\u043e\u0432\u0430 \u0433\u043b\u0430\u0432\u043d\u0430\u044f \u043f\u043e\u0441\u043b\u0435 &#171;&lt;&lt; \u041d\u0430\u0437\u0430\u0434&#187;<\/figcaption><\/div>\n<\/figure>\n<h2>\u0412 \u043f\u043e\u0438\u0441\u043a\u0430\u0445 \u0441\u043e\u043b\u043d\u0446\u0430<\/h2>\n<p>\u041f\u0435\u0440\u0435\u0439\u0434\u0451\u043c \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043a \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u043e\u0438\u0441\u043a\u043e\u0432\u0438\u043a\u0430 \u043f\u043e\u0433\u043e\u0434\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<p>\u0414\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u0430\u043d\u043d\u043e\u0439 \u0444\u0438\u0447\u0438 \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <a href=\"https:\/\/yandex.ru\/dev\/maps\/geocoder\/\" rel=\"noopener noreferrer nofollow\">\u042f\u043d\u0434\u0435\u043a\u0441.\u0413\u0435\u043e\u043a\u043e\u0434\u0435\u0440<\/a> \u0438 <a href=\"https:\/\/yandex.ru\/dev\/weather\/\" rel=\"noopener noreferrer nofollow\">\u042f\u043d\u0434\u0435\u043a\u0441.\u041f\u043e\u0433\u043e\u0434\u0430<\/a>.<\/p>\n<p>\u041e\u0431\u043e \u0432\u0441\u0451\u043c \u043f\u043e \u043f\u043e\u0440\u044f\u0434\u043a\u0443.<\/p>\n<p>\u041f\u0435\u0440\u0432\u044b\u043c \u0434\u0435\u043b\u043e\u043c \u0432\u044b\u043d\u0435\u0441\u0435\u043c \u043a\u043e\u0435-\u043a\u0430\u043a\u0438\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0432 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f:<\/p>\n<pre><code class=\"cs\">internal class Program {     private static readonly bool RequestApi = true;     private static readonly string GeocoderApiKey = ...;     private static readonly string WeatherApiKey = ...;      private static readonly string BotApiKey = ...;      public static DefaultUserState DefaultState = new(0, \"default\");     public static DefaultUserState InputCityState = new(10, \"typing\");      static async Task Main(string[] args)     {         \/\/ ...     }      \/\/ ... }<\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0434\u0432\u0430 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u0432\u0432\u043e\u0434\u0430:<\/p>\n<ol>\n<li>\n<p>\u0422\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0432\u0432\u043e\u0434 \u0433\u043e\u0440\u043e\u0434\u0430<\/p>\n<\/li>\n<li>\n<p>\u0422\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0432\u0432\u043e\u0434 &#171;\u041e\u0442\u043c\u0435\u043d\u0430&#187;<\/p>\n<\/li>\n<\/ol>\n<p>\u0415\u0441\u043b\u0438 \u041e\u0442\u043c\u0435\u043d\u0443 \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0432\u0448\u0438\u0441\u044c \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u043c <code>DefaultTextInput<\/code>, \u0443\u043a\u0430\u0437\u0430\u0432, &#171;\u041e\u0442\u043c\u0435\u043d\u0430&#187; \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043a\u043b\u044e\u0447\u0430 \u0440\u0435\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u0442\u043e \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0432\u0432\u043e\u0434 \u0433\u043e\u0440\u043e\u0434\u0430 \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043e\u043d \u0434\u043e\u043b\u0436\u0435\u043d \u0440\u0435\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430 \u043b\u044e\u0431\u043e\u0435 \u0432\u0432\u0435\u0434\u0451\u043d\u043d\u043e\u0435 \u0441\u043b\u043e\u0432\u043e.<\/p>\n<pre><code class=\"cs\">\/\/ Program private static DefaultTextInput ExitInput => new(\"\u0412\u044b\u0439\u0442\u0438\", Do_ExitInputCityAsync); private static async Task Do_ExitInputCityAsync(SignedMessageTextUpdate update) {     \/\/ \u041f\u0440\u043e\u0441\u0442\u043e \u043c\u0435\u043d\u044f\u0435\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043d\u0430 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0435     if (update.Sender is IStatefulUser stateful)     {         stateful.State = DefaultState;          var message = new OutputMessageText($\"\u0412\u044b \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0432\u0432\u043e\u0434\u0438\u0442\u0435.\")         {             Menu = new ReplyCleaner(),         };         await update.Owner.DeliveryService.ReplyToSender(message, update);     } }<\/code><\/pre>\n<pre><code class=\"cs\">internal class AnyInput : DefaultBotAction&lt;SignedMessageTextUpdate> {     public AnyInput(string anyId, BotInteraction&lt;SignedMessageTextUpdate> action) : base(\"systemAny.\" + anyId, action)     { }      \/\/ \u0414\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u0440\u0435\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430 \u043b\u044e\u0431\u043e\u0439 \u0432\u0432\u043e\u0434, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c true \u0431\u0435\u0437 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a.     public override bool ShouldBeExecutedOn(SignedMessageTextUpdate update) => true; }<\/code><\/pre>\n<pre><code class=\"cs\">\/\/ Program private static AnyInput InputCity => new(\"city\", Do_InputCityAsync); private static async Task Do_InputCityAsync(SignedMessageTextUpdate update) {     \/\/ ... }<\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u0432\u0432\u043e\u0434\u0430. \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u043c\u044b \u0445\u043e\u0442\u0438\u043c, \u0447\u0442\u043e\u0431\u044b \u0431\u043e\u0442 \u0440\u0435\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u043b \u043d\u0430 \u0442\u0435\u043a\u0441\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0441\u043b\u0443\u0447\u0430\u0435, \u043a\u043e\u0433\u0434\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0438 \u0432\u0432\u043e\u0434\u0430 \u0442\u0435\u043a\u0441\u0442\u0430. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u043c\u0435\u0441\u0442\u043e \u043e\u0431\u044b\u0447\u043d\u043e\u0433\u043e ActionManager \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c StatefulManager (\u0438\u0437 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f SKitLs.Bots.Telegram.Stateful), \u0443\u043a\u0430\u0437\u0430\u0432 \u0434\u043b\u044f StateSection \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435 \u0440\u0430\u0431\u043e\u0447\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 &#8212; <code>InputCityState<\/code>.<\/p>\n<pre><code class=\"cs\">\/\/ async Task Main() var privateMessages = new DefaultSignedMessageUpdateHandler(); var statefulInputs = new DefaultStatefulManager&lt;SignedMessageTextUpdate>(); var privateTexts = new DefaultSignedMessageTextUpdateHandler {     CommandsManager = new DefaultActionManager&lt;SignedMessageTextUpdate>(),     TextInputManager = statefulInputs, }; privateTexts.CommandsManager.AddSafely(StartCommand);  \/\/ \u041d\u043e\u0432\u0430\u044f \u0441\u0435\u043a\u0446\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439 var inputStateSection = new DefaultStateSection&lt;SignedMessageTextUpdate>(); \/\/ \u0420\u0430\u0437\u0440\u0435\u0448\u0430\u0435\u043c \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 inputStateSection.EnableState(InputCityState); \/\/ \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0438\u0434\u0451\u0442 Exit, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0438\u043d\u0447\u0435 Input, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0435\u0430\u0433\u0438\u0440\u0443\u0435\u0442 \u043d\u0430 \u043b\u044e\u0431\u043e\u0439 \u0432\u0432\u043e\u0434, \/\/ \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0432\u0432\u0435\u0434\u0451\u043d\u043d\u043e\u0435 \u0441\u043b\u043e\u0432\u043e, \u043d\u0435 \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u044f \u0435\u0433\u043e \u0434\u043e Exit-\u0430 inputStateSection.AddSafely(ExitInput); inputStateSection.AddSafely(InputCity); \/\/ \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u0435\u043a\u0446\u0438\u044e \u0432 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 statefulInputs.AddSectionSafely(inputStateSection);  privateMessages.TextMessageUpdateHandler = privateTexts;<\/code><\/pre>\n<p>\u0412 \u0438\u0434\u0435\u0430\u043b\u0435, \u0431\u044b\u043b\u043e \u0431\u044b \u043d\u0435\u043f\u043b\u043e\u0445\u043e \u0437\u0430\u043a\u0440\u044b\u0442\u044c \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u044b, \u0442\u043e \u0435\u0441\u0442\u044c, \u0442\u0430\u043a\u0436\u0435 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0438\u0445 Stateful \u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 &#8212; <code>DefaultState<\/code>. \u041d\u043e \u044d\u0442\u043e \u043c\u043e\u0433\u043b\u043e \u0431\u044b \u0441\u0442\u0430\u0442\u044c \u043d\u0435\u043f\u043b\u043e\u0445\u0438\u043c \u0434\u043e\u043c\u0430\u0448\u043d\u0438\u043c \u0437\u0430\u0434\u0430\u043d\u0438\u0435\u043c \u0434\u043b\u044f \u0442\u0435\u0445, \u043a\u0442\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0447\u0435\u0442 \u043f\u043e\u0433\u0440\u0443\u0437\u0438\u0442\u044c\u0441\u044f \u0432 \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438.<\/p>\n<p>\u041c\u044b \u0436\u0435 \u0438\u0434\u0451\u043c \u0434\u0430\u043b\u044c\u0448\u0435.<\/p>\n<p>\u0417\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0432 \u043d\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0430 \u042f\u043d\u0434\u0435\u043a\u0441, \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0434\u0432\u0430 API \u043a\u043b\u044e\u0447\u0430:<\/p>\n<ol>\n<li>\n<p>\u0414\u043b\u044f .\u0413\u0435\u043e\u043a\u043e\u0434\u0435\u0440\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u0442\u044c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043d\u0430\u0441\u0435\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u043f\u0443\u043d\u043a\u0442\u0430 \u0432 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b<\/p>\n<\/li>\n<li>\n<p>\u0418 \u0434\u043b\u044f .\u041f\u043e\u0433\u043e\u0434\u044b, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0434\u0430\u0451\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\/\u043f\u0440\u043e\u0433\u043d\u043e\u0437 \u043f\u043e\u0433\u043e\u0434\u044b \u043f\u043e \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430\u043c \u043c\u0435\u0441\u0442\u0430<\/p>\n<\/li>\n<\/ol>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u043c\u0441\u044f \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c \u0438\u0445 \u0432 <code>Do_InputCityAsync<\/code> &#8212; \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f &#171;\u0413\u043e\u0440\u043e\u0434 \u0431\u044b\u043b \u0432\u0432\u0435\u0434\u0451\u043d&#187;. \u0412\u0432\u0438\u0434\u0443 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e API \u042f\u043d\u0434\u0435\u043a\u0441\u0430 \u043d\u0435 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0442\u0435\u043c\u043e\u0439 \u043d\u0430\u0448\u0435\u0433\u043e \u0440\u0430\u0437\u0431\u043e\u0440\u0430 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0440\u0438\u0432\u0435\u0434\u0443 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 ChatGPT \u043a\u043e\u0434 \u0441 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u043c\u0438.<\/p>\n<pre><code class=\"cs\">\/\/ Program private static AnyInput InputCity => new(\"city\", Do_InputCityAsync); private static async Task Do_InputCityAsync(SignedMessageTextUpdate update) {     string cityName = update.Text;     var geocoderApiUrl = $\"https:\/\/geocode-maps.yandex.ru\/1.x\/?apikey={GeocoderApiKey}&amp;geocode={cityName}&amp;format=json\";     double longitude = double.MaxValue;     double latitude = double.MaxValue;     if (RequestApi)     {         using (var httpClient = new HttpClient())         {             string responseString = await httpClient.GetStringAsync(geocoderApiUrl);             Console.WriteLine(responseString);             \/\/ \u0414\u043b\u044f GeoCodeWrap \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 GitHub \u044d\u0442\u043e\u0433\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f             var response = JsonConvert.DeserializeObject&lt;GeoCodeWrap>(responseString);             cityName = response?.Response?.GeoObjectCollection?.FeatureMember?[0]?.GeoObject?.Name ?? update.Text;             string? pos = response?.Response?.GeoObjectCollection?.FeatureMember?[0]?.GeoObject?.Point?.pos;             string[] coordinates = pos?.Split(' ') ?? Array.Empty&lt;string>();              if (coordinates.Length != 2                 || !double.TryParse(coordinates[0], NumberStyles.Float, CultureInfo.InvariantCulture, out longitude)                 || !double.TryParse(coordinates[1], NumberStyles.Float, CultureInfo.InvariantCulture, out latitude))             {                 await update.Owner.DeliveryService.ReplyToSender(\"\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043d\u0430\u0439\u0442\u0438 \u0438\u0441\u043a\u043e\u043c\u044b\u0439 \u0433\u043e\u0440\u043e\u0434...\", update);                 return;             }         }     }      var resultMessage = $\"\u041f\u043e\u0433\u043e\u0434\u0430 \u0432 \u0437\u0430\u043f\u0440\u043e\u0448\u0435\u043d\u043d\u043e\u043c \u043c\u0435\u0441\u0442\u0435: {cityName} ({latitude.ToString().Replace(',', '.')}, {longitude.ToString().Replace(',', '.')})\\n\\n\";      if (RequestApi)     {         var weatherApiUrl = $\"https:\/\/api.weather.yandex.ru\/v2\/informers?\" +             $\"lat={latitude.ToString().Replace(',', '.')}&amp;lon={longitude.ToString().Replace(',', '.')}\";         using (HttpClient client = new HttpClient())         {             client.DefaultRequestHeaders.Add(\"X-Yandex-API-Key\", WeatherApiKey);              HttpResponseMessage response = await client.GetAsync(weatherApiUrl);             string content = await response.Content.ReadAsStringAsync();              JObject jsonObject = JObject.Parse(content);             JObject factObject = jsonObject[\"fact\"] as JObject;              \/\/ \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u043f\u043e\u043b\u0435\u0439             double temp = (double)factObject[\"temp\"];             resultMessage += $\"\u0422\u0435\u043c\u043f\u0435\u0440\u0430\u0442\u0443\u0440\u0430: {temp} \u00b0C\\n\";             double feelsLike = (double)factObject[\"feels_like\"];             resultMessage += $\"\u041e\u0449\u0443\u0449\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u043a: {feelsLike} \u00b0C\\n\";             \/\/string icon = (string)factObject[\"icon\"];             double windSpeed = (double)factObject[\"wind_speed\"];             resultMessage += $\"\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0432\u0435\u0442\u0440\u0430: {windSpeed} \u043c\/\u0441\\n\";             int pressureMm = (int)factObject[\"pressure_mm\"];             resultMessage += $\"\u0414\u0430\u0432\u043b\u0435\u043d\u0438\u0435: {pressureMm} \u043c\u043c \u0440\u0442.\u0441\u0442.\\n\";             int humidity = (int)factObject[\"humidity\"];             resultMessage += $\"\u0412\u043b\u0430\u0436\u043d\u043e\u0441\u0442\u044c: {humidity}%\\n\";              string daytime = (string)factObject[\"daytime\"];             bool polar = (bool)factObject[\"polar\"];             string season = (string)factObject[\"season\"];             long obsTime = (long)factObject[\"obs_time\"];         }     }      await update.Owner.DeliveryService.ReplyToSender(resultMessage, update); }<\/code><\/pre>\n<p>\u041f\u043e \u0441\u0443\u0442\u0438, \u043f\u0440\u0438\u043d\u0446\u0438\u043f \u0440\u0430\u0431\u043e\u0442\u044b \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u043f\u0440\u043e\u0441\u0442 \u043a\u0430\u043a \u043b\u043e\u043f\u0430\u0442\u0430: \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0432\u0432\u043e\u0434\u0438\u0442 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043d\u0430\u0441\u0435\u043b\u0451\u043d\u043d\u043e\u0433\u043e \u043f\u0443\u043d\u043a\u0442\u0430. \u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f Geocoder-\u0443, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u0449\u0435\u0442 \u043d\u0435\u0447\u0442\u043e \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0435 \u0443 \u0441\u0435\u0431\u044f. \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u0443\u0441\u043f\u0435\u0445\u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b. \u0418\u043d\u0430\u0447\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u0442\u0430\u0432\u0438\u043c \u043a\u043e\u0441\u0442\u044b\u043b\u044c-\u0437\u0430\u0433\u043b\u0443\u0448\u043a\u0443 \u0430-\u043b\u044f &#171;\u0433\u043e\u0440\u043e\u0434 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d&#187;. \u041f\u043e\u0432\u0442\u043e\u0440\u044e\u0441\u044c, API &#8212; \u043d\u0435 \u043d\u0430\u0448\u0430 \u043a\u043b\u044e\u0447\u0435\u0432\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430.<\/p>\n<p>\u0418\u0437 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0445 \u043e\u0442 Geocoder-\u0430 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0437\u0430\u043f\u0440\u043e\u0441 \u043a \u041f\u043e\u0433\u043e\u0434\u0435, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043a\u0438\u0434\u0430\u0435\u0442 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e.<\/p>\n<p>\u0418\u0442\u0430\u043a,  \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043c, \u0447\u0442\u043e \u0443 \u043d\u0430\u0441 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/651\/18a\/1fe\/65118a1fe9032b4f0049953d8741be53.png\" width=\"1223\" height=\"688\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/651\/18a\/1fe\/65118a1fe9032b4f0049953d8741be53.png\"\/><\/figure>\n<p>\u0412\u0441\u0451 \u043f\u0440\u0435\u043a\u0440\u0430\u0441\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442. \u0411\u043e\u043b\u0435\u0435 \u0442\u043e\u0433\u043e, API \u042f\u043d\u0434\u0435\u043a\u0441\u0430 \u0434\u0430\u0436\u0435 \u0432 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0438 \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u0435 \u043e\u043f\u0435\u0447\u0430\u0442\u043a\u0438.<\/p>\n<h2>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0438\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0433\u043e<\/h2>\n<p>\u0414\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0438\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0433\u043e \u0432\u043e-\u043f\u0435\u0440\u0432\u044b\u0445 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043a\u043b\u0430\u0441\u0441 \u0441 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0435\u0439 \u043e\u0431 \u043e\u0431\u044a\u0435\u043a\u0442\u0435: \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0438 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435. \u0418 \u043e\u0431\u043d\u043e\u0432\u0438\u043c \u043a\u043b\u0430\u0441\u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u0432 \u043d\u0451\u043c \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0441\u044c \u0438\u0437\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u0433\u043e\u0440\u043e\u0434\u0430.<\/p>\n<p>\u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, <code>GeoCoderInfo<\/code> \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430 \u0434\u043b\u044f \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u043c\u0435\u0442\u0438\u043c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u043a\u043b\u0430\u0441\u0441\u0430 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c\u0438 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430\u043c\u0438.<\/p>\n<pre><code class=\"cs\">internal class GeoCoderInfo {     [BotActionArgument(0)]     public string Name { get; set; } = null!;     [BotActionArgument(1)]     public long Longitude { get; set; }     [BotActionArgument(2)]     public long Latitude { get; set; }      public GeoCoderInfo() { }     public GeoCoderInfo(string name, long longitude, long latitude)     {         Name = name;         Longitude = longitude;         Latitude = latitude;     }        public string GetDisplay() => $\"\u0413\u043e\u0440\u043e\u0434: {Name} ({Latitude.ToString().Replace(',', '.')}, {Longitude.ToString().Replace(',', '.')})\"; }<\/code><\/pre>\n<pre><code class=\"cs\">internal class BotUser : IStatefulUser {     public List&lt;GeoCoderInfo> Favs { get; } = new();     \/\/ ... }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0434\u0432\u0430 \u043a\u043e\u043b\u043b\u0431\u044d\u043a\u0430. \u041e\u0434\u0438\u043d \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0433\u043e\u0440\u043e\u0434 \u0432 \u0438\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0435, \u0432\u0442\u043e\u0440\u043e\u0439 \u0431\u0443\u0434\u0435\u0442 \u0435\u0433\u043e \u0443\u0434\u0430\u043b\u044f\u0442\u044c.<\/p>\n<pre><code class=\"cs\">\/\/ Program private static BotArgedCallback&lt;GeoCoderInfo> FollowGeocode => new(new LabeledData(\"\u0412 \u0438\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0435\", \"FollowGeocode\"), Do_FollowGeocodeAsync); private static async Task Do_FollowGeocodeAsync(GeoCoderInfo args, SignedCallbackUpdate update) {     if (update.Sender is BotUser user)     {         user.Favs.Add(args);          \/\/ \u0417\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u0442\u0435\u043a\u0441\u0442 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043a \u043d\u0435\u043c\u0443 \u043f\u0440\u0438\u043f\u0438\u0441\u043a\u0443, \u0447\u0442\u043e \u0433\u043e\u0440\u043e\u0434 \u0441\u043e\u0445\u0440\u0430\u043d\u0451\u043d.         var message = new OutputMessageText(update.Message.Text + $\"\\n\\n\u0413\u043e\u0440\u043e\u0434 \u0441\u043e\u0445\u0440\u0430\u043d\u0451\u043d \u0432 \u0438\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0435!\")         {             \/\/ \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e \u0443\u0434\u0430\u043b\u044f\u0435\u043c \u043a\u043d\u043e\u043f\u043a\u0443, \u0447\u0442\u043e\u0431\u044b \u043d\u0435\u043b\u044c\u0437\u044f \u0431\u044b\u043b\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0434\u0432\u0430\u0436\u0434\u044b             Menu = null,         };         await update.Owner.DeliveryService.ReplyToSender(new EditWrapper(message, update.TriggerMessageId), update);     } }<\/code><\/pre>\n<pre><code class=\"cs\">\/\/ Program private static BotArgedCallback&lt;IntWrapper> UnfollowGeocode => new(new LabeledData(\"\u0423\u0434\u0430\u043b\u0438\u0442\u044c\", \"UnfollowGeocode\"), Do_UnfollowGeocodeAsync); private static async Task Do_UnfollowGeocodeAsync(IntWrapper args, SignedCallbackUpdate update) {     if (update.Sender is BotUser user)     {         user.Favs.RemoveAt(args.Value);          \/\/ \u0421\u043e\u0437\u0434\u0430\u0451\u043c \u043d\u043e\u0432\u043e\u0435 \u043c\u0435\u043d\u044e \u0441 \u043a\u043d\u043e\u043f\u043a\u043e\u0439 \u0432\u044b\u0445\u043e\u0434\u0430         var menu = new PairedInlineMenu();         menu.Add(\"\u0412\u044b\u0439\u0442\u0438\", update.Owner.ResolveService&lt;IMenuManager>().BackCallback);         \/\/ \u0421\u043e\u0437\u0434\u0430\u0451\u043c \u043d\u043e\u0432\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0441\u043e \u0441\u0442\u0430\u0440\u044b\u043c \u0442\u0435\u043a\u0441\u0442\u043e\u043c \u0438 \u043f\u0440\u0438\u043f\u0438\u0441\u043a\u043e\u0439         var message = new OutputMessageText(update.Message.Text + $\"\\n\\n\u0413\u043e\u0440\u043e\u0434 \u0431\u044b\u043b \u0443\u0434\u0430\u043b\u0451\u043d!\")         {             \/\/ \u0423\u0434\u0430\u043b\u044f\u0435\u043c \u043c\u0435\u043d\u044e \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043d\u043e\u0432\u043e\u0435 \u0441 \u043a\u043d\u043e\u043f\u043a\u043e\u0439 \u0432\u044b\u0445\u043e\u0434\u0430             Menu = menu,         };         await update.Owner.DeliveryService.ReplyToSender(new EditWrapper(message, update.TriggerMessageId), update);     } }<\/code><\/pre>\n<pre><code class=\"cs\">\/\/ \u0413\u0434\u0435 IntWrapper - \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u0430\u044f class \u043e\u0431\u0451\u0440\u0442\u043a\u0430 \u0434\u043b\u044f struct int internal class IntWrapper {     [BotActionArgument(0)]     public int Value { get; set; }        public IntWrapper() { }     public IntWrapper(int value) => Value = value; }<\/code><\/pre>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0435 \u043a\u043b\u0430\u0441\u0441\u044b <code>ArgedActions&lt;><\/code>(\u0438\u0437 SKitLs.Bots.Telegram.ArgedInteractions), \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0438\u0435 \u043d\u0430\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043a\u043b\u0430\u0441\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440 \u0438 \u0437\u0430\u0442\u0435\u043c \u0434\u0435\u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d \u043f\u043e\u0441\u043b\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u0430.<\/p>\n<p>\u041d\u0435 \u0437\u0430\u0431\u044b\u0432\u0430\u0435\u043c \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u043a\u043e\u043b\u043b\u0431\u044d\u043a\u0438 \u0432 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u0432 \u043d\u0430\u0448\u0435\u043c <code>Main()<\/code><\/p>\n<pre><code class=\"cs\">\/\/ async Task Main() privateCallbacks.CallbackManager.AddSafely(StartSearching);  privateCallbacks.CallbackManager.AddSafely(FollowGeocode); privateCallbacks.CallbackManager.AddSafely(UnfollowGeocode);  mm.ApplyFor(privateCallbacks.CallbackManager);<\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 &#171;\u043f\u0440\u0438\u043a\u0440\u0443\u0442\u0438\u043c&#187; \u043d\u0430\u0448 \u043a\u043e\u043b\u043b\u0431\u044d\u043a &#171;Follow&#187; \u043a \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044e \u0441 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0435\u0439 \u043e \u043f\u043e\u0433\u043e\u0434\u0435<\/p>\n<pre><code class=\"cs\">\/\/ Program private static async Task Do_InputCityAsync(SignedMessageTextUpdate update) {     \/\/ ...     var menu = new PairedInlineMenu()     {         Serializer = update.Owner.ResolveService&lt;IArgsSerilalizerService>()     };     menu.Add(FollowGeocode, new GeoCodeInfo(cityName, longitude, latitude));     var message = new OutputMessageText(resultMessage)     {         Menu = menu,     };     await update.Owner.DeliveryService.ReplyToSender(message, update); }<\/code><\/pre>\n<p>\u0418\u0442\u0430\u043a, \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043c, \u043a\u0430\u043a \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/f00\/c63\/ffe\/f00c63ffee9bd4ba5abb1be21123d25f.png\" alt=\"\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u043f\u043e\u0433\u043e\u0434\u044b \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0433\u043e\u0440\u043e\u0434 \u0432 \u0438\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0435.\" title=\"\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u043f\u043e\u0433\u043e\u0434\u044b \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0433\u043e\u0440\u043e\u0434 \u0432 \u0438\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0435.\" width=\"1212\" height=\"395\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f00\/c63\/ffe\/f00c63ffee9bd4ba5abb1be21123d25f.png\"\/><\/p>\n<div><figcaption>\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u043f\u043e\u0433\u043e\u0434\u044b \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0433\u043e\u0440\u043e\u0434 \u0432 \u0438\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0435.<\/figcaption><\/div>\n<\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/85c\/f96\/65f\/85cf9665f879e0adc9361da707bcd18f.png\" alt=\"\u041f\u043e\u0441\u043b\u0435 \u043d\u0430\u0436\u0430\u0442\u0438\u044f \u0432\u044b\u0445\u043e\u0434\u0438\u0442 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435, \u0447\u0442\u043e \u0433\u043e\u0440\u043e\u0434 \u0431\u044b\u043b \u0441\u043e\u0445\u0440\u0430\u043d\u0451\u043d \u0432 \u0438\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0435.\" title=\"\u041f\u043e\u0441\u043b\u0435 \u043d\u0430\u0436\u0430\u0442\u0438\u044f \u0432\u044b\u0445\u043e\u0434\u0438\u0442 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435, \u0447\u0442\u043e \u0433\u043e\u0440\u043e\u0434 \u0431\u044b\u043b \u0441\u043e\u0445\u0440\u0430\u043d\u0451\u043d \u0432 \u0438\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0435.\" width=\"1213\" height=\"394\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/85c\/f96\/65f\/85cf9665f879e0adc9361da707bcd18f.png\"\/><\/p>\n<div><figcaption>\u041f\u043e\u0441\u043b\u0435 \u043d\u0430\u0436\u0430\u0442\u0438\u044f \u0432\u044b\u0445\u043e\u0434\u0438\u0442 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435, \u0447\u0442\u043e \u0433\u043e\u0440\u043e\u0434 \u0431\u044b\u043b \u0441\u043e\u0445\u0440\u0430\u043d\u0451\u043d \u0432 \u0438\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0435.<\/figcaption><\/div>\n<\/figure>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0435\u0440\u0435\u043f\u0438\u0448\u0435\u043c \u043d\u0430\u0448 MenuManager, \u0434\u043e\u0431\u0430\u0432\u0438\u0432 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0438\u0437 \u0441\u043e\u0445\u0440\u0430\u043d\u0451\u043d\u043d\u044b\u0445 \u0433\u043e\u0440\u043e\u0434\u043e\u0432.<\/p>\n<pre><code class=\"cs\">private static IMenuManager GetMenuManager() {     \/\/ ...     var savedBody = new DynamicMessage(GetSavedList);     var savedPage = new WidgetPage(\"saved\", \"\u0418\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0435\", savedBody);     \/\/ ... }  private static IOutputMessage GetSavedList(ISignedUpdate? update) {     var message = \"\u0418\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0435:\\n\\n\";     if (update is not null &amp;&amp; update.Sender is BotUser user)     {         if (user.Favs.Count == 0) message += \"\u041d\u0438\u0447\u0435\u0433\u043e \u043d\u0435\u0442\";         foreach (var favorite in user.Favs)         {             message += $\"- {favorite.Name}\\n\";         }     }     return new OutputMessageText(message); }<\/code><\/pre>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/21b\/ec5\/acb\/21bec5acb97ce163e6b722da01d02aba.png\" width=\"1214\" height=\"231\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/21b\/ec5\/acb\/21bec5acb97ce163e6b722da01d02aba.png\"\/><\/figure>\n<p>\u041a\u0430\u043a \u0432\u0438\u0434\u043d\u043e, \u0433\u043e\u0440\u043e\u0434 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0431\u044b\u043b \u0441\u043e\u0445\u0440\u0430\u043d\u0451\u043d \u0432 \u0438\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0435 \u0438, \u0432 \u0446\u0435\u043b\u043e\u043c, \u0437\u0434\u0435\u0441\u044c \u0432\u0441\u0451 \u044f\u0441\u043d\u043e: \u043f\u0440\u0438 \u0432\u0445\u043e\u0434\u044f\u0449\u0435\u043c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 (\u0441 \u043f\u0440\u043e\u0441\u044c\u0431\u043e\u0439 \u043e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u0442\u044c \u0438\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0435) \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438 \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u0432\u044b\u0432\u043e\u0434\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0451\u043d\u043d\u044b\u0435 \u0433\u043e\u0440\u043e\u0434\u0430. \u041e\u0434\u043d\u0430\u043a\u043e \u043a\u0430\u043a \u0431\u044b\u0442\u044c \u0441 \u043c\u0435\u043d\u044e \u0438 \u043f\u043e\u043f\u044b\u0442\u043a\u0430\u043c\u0438 \u043e\u0442\u043a\u0440\u044b\u0442\u044c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0439 \u0433\u043e\u0440\u043e\u0434 \u043a \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0443?<\/p>\n<p>\u041a\u0430\u043a \u0443\u0436\u0435 \u0431\u044b\u043b\u043e \u0441\u043a\u0430\u0437\u0430\u043d\u043e, \u0437\u0430 \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u043f\u043e\u043a\u0430 \u0435\u0449\u0451 \u043d\u0435 \u0432\u044b\u043f\u0443\u0449\u0435\u043d\u043d\u044b\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 SKitLs.Bots.Telegram.DataBases. \u0421 \u044d\u0442\u0438\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u043c \u043d\u0430\u0448\u0430 \u0437\u0430\u0434\u0430\u0447\u0430 \u0431\u044b\u043b\u0430 \u0431\u044b \u043f\u0440\u043e\u0449\u0435, \u043d\u043e \u0441\u0435\u0439\u0447\u0430\u0441, \u0442\u0430\u043a \u043a\u0430\u043a \u043d\u0438 \u043e\u0434\u043d\u0430 \u0438\u0437 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0439 IPageMenu \u043d\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438 \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u0441\u0432\u043e\u0451 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435 \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e, \u043d\u0430\u043c \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043a\u043e\u0441\u0442\u044b\u043b\u044c \u0432 \u0432\u0438\u0434\u0435 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u043c\u0435\u043d\u044e.<\/p>\n<pre><code class=\"cs\">internal class SavedFavoriteMenu : IPageMenu {     public BotArgedCallback&lt;GeoCoderInfo> OpenCallback { get; private set; }      public SavedFavoriteMenu(BotArgedCallback&lt;GeoCoderInfo> openCallback)     {         OpenCallback = openCallback;     }      public IMesMenu Build(IBotPage? previous, IBotPage owner, ISignedUpdate update)     {         IMenuManager mm = update.Owner.ResolveService&lt;IMenuManager>();          var res = new PairedInlineMenu()         {             Serializer = update.Owner.ResolveService&lt;IArgsSerilalizerService>(),         };          if (update.Sender is BotUser user)         {             foreach (var favorite in user.Favs)             {                 res.Add(favorite.Name, OpenCallback, favorite);             }         }          if (previous != null)         {             res.Add(\"\u041d\u0430\u0437\u0430\u0434\", mm.BackCallback, singleLine: true);         }          return res;     } }<\/code><\/pre>\n<p>\u0413\u0434\u0435 <code>OpenCallback<\/code> &#8212; \u043a\u043e\u043b\u043b\u0431\u044d\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u043e\u043b\u0436\u0435\u043d \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u043d\u0430\u0448\u0435\u043c \u0441 \u0432\u0430\u043c\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u0435.<\/p>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u0435 \u043c\u0435\u043d\u044e \u043a \u043d\u0430\u0448\u0435\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u0432 <code>IMenuManager GetMenuManager()<\/code> \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c<\/p>\n<pre><code class=\"cs\">\/\/ GetMenuManager() var savedPage = new WidgetPage(\"saved\", \"\u0418\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0435\", savedBody, new SavedFavoriteMenu(OpenFollow));<\/code><\/pre>\n<p>\u041f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0432 \u044d\u0442\u043e\u0442 \u0441\u0430\u043c\u044b\u0439 <code>OpenFollow<\/code> \u043a\u043e\u043b\u043b\u0431\u044d\u043a \u0432 \u043a\u043b\u0430\u0441\u0441\u0435 <code>Program<\/code><\/p>\n<pre><code class=\"cs\">\/\/ Program private static BotArgedCallback&lt;GeoCoderInfo> OpenFollow => new(new LabeledData(\"{ \u041e\u0442\u043a\u0440\u044b\u0442\u044c }\", \"OpenFollow\"), Do_OpenFollowAsync); private static async Task Do_OpenFollowAsync(GeoCoderInfo args, SignedCallbackUpdate update) {     if (update.Sender is BotUser user)     {         var menu = new PairedInlineMenu();         \/\/ menu.Add(\u043a\u043e\u043b\u043b\u0431\u044d\u043a: \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u043f\u043e\u0433\u043e\u0434\u0435 \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u0430);         \/\/ menu.Add(\u043a\u043e\u043b\u043b\u0431\u044d\u043a: \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442 \u0438\u0437 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0435\u043c\u044b\u0445);         menu.Add(\"\u041d\u0430\u0437\u0430\u0434\", update.Owner.ResolveService&lt;IMenuManager>().BackCallback);         var message = new OutputMessageText(args.GetDisplay())         {             Menu = menu,         };         await update.Owner.DeliveryService.ReplyToSender(new EditWrapper(message, update.TriggerMessageId), update);     } }<\/code><\/pre>\n<p>\u0412 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442, \u0441 \u0446\u0435\u043b\u044c\u044e \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438, \u043f\u0440\u0438 \u043e\u0442\u043a\u0440\u044b\u0442\u0438\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u043f\u043e\u0433\u043e\u0434\u0435 \u043d\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442\u0441\u044f. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u0440\u043e\u043f\u0438\u0448\u0435\u043c \u043b\u043e\u0433\u0438\u043a\u0443 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e \u043f\u043e\u0433\u043e\u0434\u0435 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u043b\u043b\u0431\u044d\u043a, \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u044b\u043d\u0435\u0441\u044f \u043b\u043e\u0433\u0438\u043a\u0443 \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043a API \u042f\u043d\u0434\u0435\u043a\u0441 \u041f\u043e\u0433\u043e\u0434\u044b \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u043a\u043b\u0430\u0441\u0441\u0430 <code>Program<\/code><\/p>\n<pre><code class=\"cs\">\/\/ \u041e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043f\u043e\u0433\u043e\u0434\u044b \u043f\u043e \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430\u043c private static async Task&lt;string> GetWeatherInfo(double latitude, double longitude) {     var resultMessage = string.Empty;      var weatherApiUrl = $\"https:\/\/api.weather.yandex.ru\/v2\/informers?\" +             $\"lat={latitude.ToString().Replace(',', '.')}&amp;lon={longitude.ToString().Replace(',', '.')}\";     using (HttpClient client = new HttpClient())     {         client.DefaultRequestHeaders.Add(\"X-Yandex-API-Key\", WeatherApiKey);          HttpResponseMessage response = await client.GetAsync(weatherApiUrl);         string content = await response.Content.ReadAsStringAsync();          JObject jsonObject = JObject.Parse(content);         JObject factObject = jsonObject[\"fact\"] as JObject;          \/\/ \u0416\u0451\u0441\u0442\u043a\u0438\u0439 \u043f\u0430\u0440\u0441\u0438\u043d\u0433         double temp = (double)factObject[\"temp\"];         resultMessage += $\"\u0422\u0435\u043c\u043f\u0435\u0440\u0430\u0442\u0443\u0440\u0430: {temp} \u00b0C\\n\";         double feelsLike = (double)factObject[\"feels_like\"];         resultMessage += $\"\u041e\u0449\u0443\u0449\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u043a: {feelsLike} \u00b0C\\n\";         \/\/string icon = (string)factObject[\"icon\"];         double windSpeed = (double)factObject[\"wind_speed\"];         resultMessage += $\"\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0432\u0435\u0442\u0440\u0430: {windSpeed} \u043c\/\u0441\\n\";         int pressureMm = (int)factObject[\"pressure_mm\"];         resultMessage += $\"\u0414\u0430\u0432\u043b\u0435\u043d\u0438\u0435: {pressureMm} \u043c\u043c \u0440\u0442.\u0441\u0442.\\n\";         int humidity = (int)factObject[\"humidity\"];         resultMessage += $\"\u0412\u043b\u0430\u0436\u043d\u043e\u0441\u0442\u044c: {humidity}%\\n\";          string daytime = (string)factObject[\"daytime\"];         bool polar = (bool)factObject[\"polar\"];         string season = (string)factObject[\"season\"];         long obsTime = (long)factObject[\"obs_time\"];     }      return resultMessage; }  \/\/ \u0410 \u0442\u0430\u043a\u0436\u0435 \u043e\u0431\u043d\u043e\u0432\u0438\u043c \u043c\u0435\u0442\u043e\u0434 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f private static async Task Do_InputCityAsync(SignedMessageTextUpdate update) {     \/\/ ...     if (RequestApi)     {         resultMessage += await GetWeatherInfo(latitude, longitude);     }     \/\/ ... }<\/code><\/pre>\n<pre><code class=\"cs\">\/\/ Program private static BotArgedCallback&lt;GeoCoderInfo> LoadWeather => new(new LabeledData(\"\u0423\u0437\u043d\u0430\u0442\u044c \u043f\u043e\u0433\u043e\u0434\u0443\", \"LoadWeather\"), Do_LoadWeatherAsync); private static async Task Do_LoadWeatherAsync(GeoCoderInfo args, SignedCallbackUpdate update) {     if (update.Sender is BotUser user)     {         var menu = new PairedInlineMenu()         {             Serializer = update.Owner.ResolveService&lt;IArgsSerilalizerService>()         };         menu.Add(UnfollowGeocode, new IntWrapper(user.Favs.FindIndex(x => x.Name == args.Name)));         menu.Add(\"\u041d\u0430\u0437\u0430\u0434\", update.Owner.ResolveService&lt;IMenuManager>().BackCallback);         var message = new OutputMessageText(update.Message.Text + \"\\n\\n\" + await GetWeatherInfo(args.Latitude, args.Longitude))         {             Menu = menu,         };         await update.Owner.DeliveryService.ReplyToSender(new EditWrapper(message, update.TriggerMessageId), update);     } }<\/code><\/pre>\n<p>\u0418 \u043f\u0430\u0440\u0430 \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0445 \u0448\u0442\u0440\u0438\u0445\u043e\u0432: \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043e\u0431\u043d\u043e\u0432\u0438\u043c \u043c\u0435\u043d\u044e \u0432 <code>Do_OpenFollowAsync<\/code><\/p>\n<pre><code class=\"cs\">var menu = new PairedInlineMenu() {     Serializer = update.Owner.ResolveService&lt;IArgsSerilalizerService>() }; menu.Add(UnfollowGeocode, new IntWrapper(user.Favs.FindIndex(x => x.Name == args.Name))); menu.Add(LoadWeather, args); menu.Add(\"\u041d\u0430\u0437\u0430\u0434\", update.Owner.ResolveService&lt;IMenuManager>().BackCallback);<\/code><\/pre>\n<p>\u0418 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u0430\u0448\u0438 \u043a\u043e\u043b\u043b\u0431\u044d\u043a\u0438 \u0432 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440<\/p>\n<pre><code class=\"cs\">\/\/ async Task Main() privateCallbacks.CallbackManager.AddSafely(OpenFollow); privateCallbacks.CallbackManager.AddSafely(LoadWeather);<\/code><\/pre>\n<h2>\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b<\/h2>\n<p>\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u043c \u0431\u043e\u0442\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439 &#8216;\/start&#8217; (<code>Do_StartAsync<\/code>). \u041f\u0440\u043e\u0432\u0435\u0440\u0438\u043c \u0432\u043a\u043b\u0430\u0434\u043a\u0443 &#171;\u0418\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0435&#187; (<code>GetSavedList()<\/code>). \u041a\u0430\u043a \u0432\u0438\u0434\u043d\u043e, \u0432 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0443 \u043d\u0430\u0441 \u043d\u0435\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u0451\u043d\u043d\u044b\u0445 \u0433\u043e\u0440\u043e\u0434\u043e\u0432.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/923\/368\/254\/92336825414bf87195b6b98e534aac65.png\" alt=\"\u0418\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0435 \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438\" title=\"\u0418\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0435 \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438\" width=\"1212\" height=\"240\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/923\/368\/254\/92336825414bf87195b6b98e534aac65.png\"\/><\/p>\n<div><figcaption>\u0418\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0435 \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438<\/figcaption><\/div>\n<\/figure>\n<p>\u0412\u0435\u0440\u043d\u0451\u043c\u0441\u044f &#171;\u041d\u0430\u0437\u0430\u0434&#187; (<code>IMenuManager.BackCallback<\/code>) \u0438 \u043f\u0435\u0440\u0435\u0439\u0434\u0451\u043c \u0432 &#171;\u041d\u0430\u0439\u0442\u0438&#187; (<code>Do_SearchAsync<\/code>). \u0412\u0432\u0435\u0434\u0451\u043c \u043f\u0430\u0440\u043e\u0447\u043a\u0443 \u0433\u043e\u0440\u043e\u0434\u043e\u0432 \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u043f\u043e\u0433\u043e\u0434\u043d\u044b\u0445 \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u0445 \u0432 \u043d\u0438\u0445 (<code>Do_InputCityAsync<\/code>).<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/6f7\/9e5\/55d\/6f79e555d12f20c884e3763942a8d91f.png\" alt=\"\u0417\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u0430\u044f \u043f\u043e\u0433\u043e\u0434\u0430 \u043f\u043e \u0433\u043e\u0440\u043e\u0434\u0430\u043c\" title=\"\u0417\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u0430\u044f \u043f\u043e\u0433\u043e\u0434\u0430 \u043f\u043e \u0433\u043e\u0440\u043e\u0434\u0430\u043c\" width=\"1217\" height=\"763\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/6f7\/9e5\/55d\/6f79e555d12f20c884e3763942a8d91f.png\"\/><\/p>\n<div><figcaption>\u0417\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u0430\u044f \u043f\u043e\u0433\u043e\u0434\u0430 \u043f\u043e \u0433\u043e\u0440\u043e\u0434\u0430\u043c<\/figcaption><\/div>\n<\/figure>\n<p>\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u043c \u0433\u043e\u0440\u043e\u0434\u0430 \u0432 \u0438\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0435 (<code>Do_FollowGeocodeAsync<\/code>) \u0438 \u0432\u044b\u0439\u0434\u0435\u043c \u0438\u0437 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430 \u0432\u0432\u043e\u0434\u0430 \u0433\u043e\u0440\u043e\u0434\u043e\u0432 (<code>Do_ExitInputCityAsync<\/code>).<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/103\/cbe\/fc9\/103cbefc98604acaf7d2a8bb39fdd34e.png\" alt=\"\u0413\u043e\u0440\u043e\u0434\u0430 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u044b \u0432 \u0438\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0435\" title=\"\u0413\u043e\u0440\u043e\u0434\u0430 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u044b \u0432 \u0438\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0435\" width=\"1211\" height=\"821\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/103\/cbe\/fc9\/103cbefc98604acaf7d2a8bb39fdd34e.png\"\/><\/p>\n<div><figcaption>\u0413\u043e\u0440\u043e\u0434\u0430 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u044b \u0432 \u0438\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0435<\/figcaption><\/div>\n<\/figure>\n<p>\u0417\u0430\u043d\u043e\u0432\u043e \u0432\u044b\u0437\u043e\u0432\u0435\u043c &#8216;\/start&#8217; \u0438 \u043f\u0435\u0440\u0435\u0439\u0434\u0451\u043c \u0432 &#171;\u0418\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0435&#187;. \u041a\u0430\u043a \u0432\u0438\u0434\u043d\u043e, \u0441\u043e\u0445\u0440\u0430\u043d\u0451\u043d\u043d\u044b\u0435 \u0433\u043e\u0440\u043e\u0434\u0430 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u044b \u0432 \u043d\u0430\u0448 \u0441\u043f\u0438\u0441\u043e\u043a.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/b91\/cf5\/527\/b91cf5527fa1fdb52cf20fee22c447f3.png\" alt=\"\u041e\u0431\u043d\u043e\u0432\u043b\u0451\u043d\u043d\u043e\u0435 \u0418\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0435\" title=\"\u041e\u0431\u043d\u043e\u0432\u043b\u0451\u043d\u043d\u043e\u0435 \u0418\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0435\" width=\"1211\" height=\"399\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/b91\/cf5\/527\/b91cf5527fa1fdb52cf20fee22c447f3.png\"\/><\/p>\n<div><figcaption>\u041e\u0431\u043d\u043e\u0432\u043b\u0451\u043d\u043d\u043e\u0435 \u0418\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0435<\/figcaption><\/div>\n<\/figure>\n<p>\u041e\u0442\u043a\u0440\u043e\u0435\u043c \u043f\u0435\u0440\u0432\u044b\u0439 \u0433\u043e\u0440\u043e\u0434 (<code>Do_OpenFollowAsync<\/code>) \u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u043c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u043f\u043e\u0433\u043e\u0434\u0435 \u0432 \u043d\u0451\u043c (<code>Do_LoadWeatherAsync<\/code>).<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/2b7\/1d4\/0d2\/2b71d40d21ea60c33ac87c9f8e4b70f5.png\" alt=\"\u041e\u0442\u043a\u0440\u044b\u0442\u0438\u0435 \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0438 \u0433\u043e\u0440\u043e\u0434\u0430\" title=\"\u041e\u0442\u043a\u0440\u044b\u0442\u0438\u0435 \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0438 \u0433\u043e\u0440\u043e\u0434\u0430\" width=\"1214\" height=\"313\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/2b7\/1d4\/0d2\/2b71d40d21ea60c33ac87c9f8e4b70f5.png\"\/><\/p>\n<div><figcaption>\u041e\u0442\u043a\u0440\u044b\u0442\u0438\u0435 \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0438 \u0433\u043e\u0440\u043e\u0434\u0430<\/figcaption><\/div>\n<\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/ccd\/32b\/043\/ccd32b043d62e2f7b6d14b74059b4f22.png\" alt=\"\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043f\u043e\u0433\u043e\u0434\u044b \u0434\u043b\u044f \u0433\u043e\u0440\u043e\u0434\u0430\" title=\"\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043f\u043e\u0433\u043e\u0434\u044b \u0434\u043b\u044f \u0433\u043e\u0440\u043e\u0434\u0430\" width=\"1214\" height=\"408\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/ccd\/32b\/043\/ccd32b043d62e2f7b6d14b74059b4f22.png\"\/><\/p>\n<div><figcaption>\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043f\u043e\u0433\u043e\u0434\u044b \u0434\u043b\u044f \u0433\u043e\u0440\u043e\u0434\u0430<\/figcaption><\/div>\n<\/figure>\n<p>\u0412\u0438\u0434\u043d\u043e, \u0447\u0442\u043e \u0441 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e \u043f\u043e\u0433\u043e\u0434\u0435 \u0432 \u0433\u043e\u0440\u043e\u0434\u0435 \u043a\u043d\u043e\u043f\u043a\u0430 &#171;\u0423\u0437\u043d\u0430\u0442\u044c \u043f\u043e\u0433\u043e\u0434\u0443&#187; \u0443\u0434\u0430\u043b\u044f\u0435\u0442\u0441\u044f.<\/p>\n<p>\u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c &#171;\u0423\u0434\u0430\u043b\u0438\u0442\u044c&#187; \u0433\u043e\u0440\u043e\u0434 \u0438\u0437 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0435\u043c\u044b\u0445 (<code>Do_UnfollowGeocodeAsync<\/code>) \u0438 \u0432\u0435\u0440\u043d\u0451\u043c\u0441\u044f \u043d\u0430\u0437\u0430\u0434. \u0412\u0438\u0434\u043d\u043e, \u0447\u0442\u043e \u0433\u043e\u0440\u043e\u0434 \u043f\u0440\u043e\u043f\u0430\u043b \u0438\u0437 \u0418\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0433\u043e.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/0af\/937\/52a\/0af93752a4155cd792370a405add927c.png\" alt=\"\u041e\u0431\u043d\u043e\u0432\u043b\u0451\u043d\u043d\u043e\u0435 \u0438\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0435\" title=\"\u041e\u0431\u043d\u043e\u0432\u043b\u0451\u043d\u043d\u043e\u0435 \u0438\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0435\" width=\"1212\" height=\"299\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/0af\/937\/52a\/0af93752a4155cd792370a405add927c.png\"\/><\/p>\n<div><figcaption>\u041e\u0431\u043d\u043e\u0432\u043b\u0451\u043d\u043d\u043e\u0435 \u0438\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0435<\/figcaption><\/div>\n<\/figure>\n<p>\u0422\u0430\u043a\u0436\u0435 \u043f\u0440\u0438\u0432\u0435\u0434\u0443 \u043b\u043e\u0433\u0438 \u043a\u043e\u043d\u0441\u043e\u043b\u0438<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/e8e\/add\/2e4\/e8eadd2e4d2d190bf03bc76b16f6a791.png\" width=\"1364\" height=\"694\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/e8e\/add\/2e4\/e8eadd2e4d2d190bf03bc76b16f6a791.png\"\/><\/figure>\n<p>\u0418 \u043e\u0431\u0449\u0443\u044e \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443 \u0431\u043e\u0442\u0430<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/80d\/6bd\/f55\/80d6bdf5595c7da77a2f145a4cf2d89e.png\" width=\"652\" height=\"736\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/80d\/6bd\/f55\/80d6bdf5595c7da77a2f145a4cf2d89e.png\"\/><\/figure>\n<h2>\u041f\u043e\u0434\u0432\u0435\u0434\u0451\u043c \u0438\u0442\u043e\u0433\u0438<\/h2>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0438 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e \u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c-\u0431\u043e\u0442\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0430 \u0440\u0435\u0448\u0435\u043d\u0438\u0439 SKitLs.Bots.Telegram, \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0443\u043f\u0440\u043e\u0449\u0430\u044e\u0449\u0438\u0445 \u0438 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0432\u044b\u0432\u043e\u0434\u044f\u0449\u0438\u0445 \u043d\u0430 \u043d\u043e\u0432\u044b\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c \u0431\u043e\u0442\u043e\u0432 \u043d\u0430 C#.<\/p>\n<p>\u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u0431\u043e\u0442\u043e\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u043e\u043a\u0430\u0436\u0435\u0442\u0441\u044f \u0438\u0441\u0447\u0435\u0440\u043f\u044b\u0432\u0430\u044e\u0449\u0438\u043c, \u043e\u0434\u043d\u0430\u043a\u043e \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u043a\u043e\u043c\u043f\u043b\u0435\u043a\u0441\u043d\u044b\u0445, \u043f\u043e\u043b\u043d\u043e\u0432\u0435\u0441\u043d\u044b\u0445 \u0440\u0435\u0448\u0435\u043d\u0438\u0439, \u043e\u043d \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043e\u0431\u043b\u0435\u0433\u0447\u0438\u0442 \u0437\u0430\u0434\u0430\u0447\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u0443.<\/p>\n<p>\u041d\u0430\u0434\u0435\u044e\u0441\u044c, \u0432\u044b, \u043a\u0430\u043a \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u044c, \u0441 \u0443\u0432\u0430\u0436\u0435\u043d\u0438\u0435\u043c \u043e\u0442\u043d\u0435\u0441\u0451\u0442\u0435\u0441\u044c \u043a \u043f\u043e\u0442\u0440\u0430\u0447\u0435\u043d\u043d\u043e\u043c\u0443 \u0430\u0432\u0442\u043e\u0440\u043e\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043d\u0430 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0438 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438 \u0438 \u043e\u0441\u0442\u0430\u0432\u0438\u0442\u0435 \u043f\u043e\u0441\u043b\u0435 \u0441\u0435\u0431\u044f \u043b\u0438\u0448\u044c \u043e\u0431\u043e\u0441\u043d\u043e\u0432\u0430\u043d\u043d\u0443\u044e, \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u0438\u0432\u043d\u0443\u044e \u043a\u0440\u0438\u0442\u0438\u043a\u0443.<\/p>\n<p>\u0420\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0441 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u043c, \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u043e\u043c \u0432 \u0445\u043e\u0434\u0435 \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f, \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d <a href=\"https:\/\/github.com\/Sargeras02\/SKitLs-WeatherBot.git\" rel=\"noopener noreferrer nofollow\">\u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435<\/a>.<\/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\/751302\/\"> https:\/\/habr.com\/ru\/articles\/751302\/<\/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<h2>\u0414\u043e\u0431\u0440\u044b\u0439 \u0434\u0435\u043d\u044c, \u0443\u0432\u0430\u0436\u0430\u0435\u043c\u044b\u0435 \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u0438!<\/h2>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0431\u044b \u0445\u043e\u0442\u0435\u043b \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0431\u043e\u0442\u0430 \u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c \u043d\u0430 C# \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043d\u0430\u0431\u043e\u0440\u0430 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 SKitLs.Bots.Telegram &#8212; \u043c\u043e\u043b\u043e\u0434\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0441 \u0446\u0435\u043b\u044c\u044e \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0431\u043e\u0442\u043e\u0432.<\/p>\n<p>\u0421\u0430\u043c\u043e \u043f\u043e \u0441\u0435\u0431\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u043e \u0441 \u0446\u0435\u043b\u044c\u044e \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0431\u043e\u0442\u043e\u0432 \u0438\u0437 \u0440\u0443\u0442\u0438\u043d\u043d\u043e\u0433\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f if-else \u0432 \u0441\u0432\u043e\u0435\u043e\u0431\u0440\u0430\u0437\u043d\u044b\u0439 \u0434\u0438\u0437\u0430\u0439\u043d-\u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 .NET \u0438 C#.<\/p>\n<h2>\u041e SKitLs.Bots.Telegram<\/h2>\n<p>\u0411\u043e\u043b\u044c\u0448\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u043c\u0435\u0442\u043e\u0434\u0438\u0447\u0435\u043a \u043f\u043e \u0442\u0433-\u0431\u043e\u0442\u0430\u043c \u043d\u0430 C# \u043e\u043f\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 <em>Telegram.Bot \u0438<\/em> <em>Telegram.Bot.Extentions.Polling<\/em>  (\u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e, \u043a \u0441\u043b\u043e\u0432\u0443, \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0445 \u0432\u044b\u043f\u0443\u0441\u043a\u0430\u0445 \u043f\u0435\u0440\u0435\u043a\u043e\u0447\u0435\u0432\u0430\u043b \u0432 \u0441\u0430\u043c <em>Telegram.Bot<\/em>).<\/p>\n<p>\u0422\u0435\u043c \u043d\u0435 \u043c\u0435\u043d\u0435\u0435, <em>Telegram.Bot<\/em> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043b\u0438\u0448\u044c \u043c\u043e\u0441\u0442\u043e\u043c \u043c\u0435\u0436\u0434\u0443 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u043c \u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u043c, \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u044e\u0449\u0438\u043c \u0441\u0432\u044f\u0437\u044c \u0441 API Telegram.<\/p>\n<p>\u0412 \u0442\u043e \u0436\u0435 \u0432\u0440\u0435\u043c\u044f \u0438\u0434\u0435\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f SKitLs \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u0438 \u0442\u0438\u043f\u0438\u0437\u0430\u0446\u0438\u0438 \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0439 \u0438 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0434\u043b\u044f \u0433\u0438\u0431\u043a\u043e\u0433\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043c\u043e\u0434\u0435\u043b\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044f \u0443\u0436\u0435 \u0433\u043e\u0442\u043e\u0432\u0443\u044e, \u0441\u0432\u043e\u044e \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u0443\u044e \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443.<\/p>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u044d\u0442\u0443 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443 \u043d\u0430 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c \u043a\u0435\u0439\u0441\u0435: \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u0431\u043e\u0442\u0430, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0435\u0433\u043e \u043f\u0440\u043e\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u043f\u043e\u0433\u043e\u0434\u0443 \u0432 \u0433\u043e\u0440\u043e\u0434\u0430\u0445 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e API \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u042f\u043d\u0434\u0435\u043a\u0441.\u041f\u043e\u0433\u043e\u0434\u0430 \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0435 \u0433\u043e\u0440\u043e\u0434\u0430 \u0432 \u0441\u043f\u0438\u0441\u043e\u043a \u0438\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0433\u043e.<\/p>\n<p>\u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u044f \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u044e \u043d\u0430 \u0443\u0432\u0435\u0440\u0435\u043d\u043d\u044b\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u044f, \u0430 \u043f\u043e\u0442\u043e\u043c\u0443 \u043f\u043e\u0441\u0442\u0430\u0440\u0430\u044e\u0441\u044c \u043e\u0441\u043e\u0431\u043e \u043d\u0435 \u0432\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u043e\u0431\u044a\u044f\u0441\u043d\u0435\u043d\u0438\u0435 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u0432\u0435\u0449\u0435\u0439 \u0432\u0440\u043e\u0434\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043a\u043e\u043d\u0441\u043e\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430.<\/p>\n<p>\u0418\u0442\u043e\u0433\u043e\u0432\u043e\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 \u0440\u0430\u0437\u043c\u0435\u0449\u0451\u043d \u043d\u0430 <a href=\"https:\/\/github.com\/Sargeras02\/SKitLs-WeatherBot.git\" rel=\"noopener noreferrer nofollow\">GitHub<\/a> \u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0434\u043b\u044f \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u043b\u0435\u043d\u0438\u044f.<\/p>\n<h2>\u041d\u0435 \u0431\u0443\u0434\u0435\u043c \u043c\u0435\u0434\u043b\u0438\u0442\u044c<\/h2>\n<p>\u0421\u043e\u0437\u0434\u0430\u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c\u043d\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 \u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0432 nuget SKitLs.Bots.Telegram.Core &#8212; \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0439 \u043c\u043e\u0434\u0443\u043b\u044c \u0440\u0435\u0448\u0435\u043d\u0438\u044f, &#8212; \u044f \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u043b \u0441\u0435\u0431\u0435 \u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0434 \u0438\u0437 &#171;Quick Start&#187; <a href=\"https:\/\/github.com\/Sargeras02\/SKitLs.Bots.Telegram.git\" rel=\"noopener noreferrer nofollow\">\u0433\u0438\u0442\u0445\u0430\u0431 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b<\/a> \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u0447\u0442\u043e\u0431\u044b \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f \u0432 \u0440\u0435\u043b\u0435\u0432\u0430\u043d\u0442\u043d\u043e\u0441\u0442\u0438 \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f.<\/p>\n<pre><code class=\"cs\">static async Task Main(string[] args) {     var privateMessages = new DefaultSignedMessageUpdateHandler();     var privateTexts = new DefaultSignedMessageTextUpdateHandler     {         CommandsManager = new DefaultActionManager&lt;SignedMessageTextUpdate>()     };     privateTexts.CommandsManager.AddSafely(StartCommand);     privateMessages.TextMessageUpdateHandler = privateTexts;      ChatDesigner privates = ChatDesigner.NewDesigner()        .UseMessageHandler(privateMessages);      await BotBuilder.NewBuilder(\"YOUR_TOKEN\")        .EnablePrivates(privates)        .Build()        .Listen(); }  private static DefaultCommand StartCommand => new(\"start\", Do_StartAsync); private static async Task Do_StartAsync(SignedMessageTextUpdate update) {     await update.Owner.DeliveryService.ReplyToSender(\"Hello, world!\", update); }<\/code><\/pre>\n<p>\u0427\u0442\u043e \u0436\u0435, \u0432\u0441\u0451 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442.<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u0420\u0435\u0430\u043a\u0446\u0438\u044f \u043d\u0430 \/start<\/figcaption><\/div>\n<\/figure>\n<p>\u0415\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u0430\u044f \u0432\u043e\u0437\u043d\u0438\u043a\u0448\u0430\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u0441\u043a\u0440\u044b\u0442\u043e\u0439 \u0437\u0430 \u043a\u0443\u043b\u0438\u0441\u0430\u043c\u0438 \u0438 \u043d\u0435 \u0432\u0438\u0434\u0438\u0442\u0441\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e. \u0414\u0435\u043b\u043e \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0432\u044b\u0432\u043e\u0434 \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0430\u0435\u0442 \u043d\u0430\u0441 \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0437\u0440\u0435\u0448\u0438\u0442\u044c \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u0441\u0442\u0440\u043e\u043a\u0438:<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u0421\u043a\u0440\u044b\u0442\u0430\u044f \u043e\u0448\u0438\u0431\u043a\u0430<\/figcaption><\/div>\n<\/figure>\n<p>\u0414\u0435\u043b\u043e \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f SKitLs.Bots.Telegram \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0442 \u043e\u0442\u043b\u0430\u0434\u043a\u0443 \u043d\u0430 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u044f\u0437\u044b\u043a\u0430\u0445. \u0414\u043b\u044f \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0442\u0430\u043a\u0436\u0435 \u0441\u043a\u0430\u0447\u0430\u0442\u044c \u043d\u0443\u0436\u043d\u044b\u0435 \u044f\u0437\u044b\u043a\u043e\u0432\u044b\u0435 \u043f\u0430\u043a\u0435\u0442\u044b, \u043e\u043f\u044f\u0442\u044c \u0436\u0435, \u0441\u043e <a href=\"https:\/\/github.com\/Sargeras02\/SKitLs.Bots.Telegram.git\" rel=\"noopener noreferrer nofollow\">\u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0433\u0438\u0442\u0445\u0430\u0431<\/a> \u0438\u0437 \u043f\u0430\u043f\u043a\u0438 &#171;locals&#187;.<\/p>\n<p>\u041a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u043c\u044b \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u043b\u0438, \u0443\u043a\u0430\u0436\u0435\u043c \u043f\u0443\u0442\u044c \u043a \u043d\u0430\u0448\u0435\u0439 \u043f\u0430\u043f\u043a\u0435 \u0438 \u0437\u0430\u0442\u0435\u043c \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u044f\u0437\u044b\u043a \u043e\u0442\u043b\u0430\u0434\u043a\u0438. \u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e, \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043f\u043e\u0434\u0433\u0440\u0443\u0436\u0430\u0435\u0442 \u044f\u0437\u044b\u043a\u043e\u0432\u044b\u0435 \u043f\u0430\u043a\u0435\u0442\u044b \u0438\u0437 \u043f\u0430\u043f\u043a\u0438 &#171;resources\/locals&#187;, \u043d\u043e \u043c\u044b \u0443\u043a\u0430\u0436\u0435\u043c \u044d\u0442\u043e \u044f\u0432\u043d\u043e, \u0434\u043b\u044f \u043f\u043e\u043b\u043d\u043e\u0442\u044b \u043a\u0430\u0440\u0442\u0438\u043d\u044b.<\/p>\n<figure class=\"\">\n<div><figcaption>\u0414\u0435\u0440\u0435\u0432\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f. \u042f\u0437\u044b\u043a\u043e\u0432\u044b\u0435 \u043f\u0430\u043a\u0435\u0442\u044b<\/figcaption><\/div>\n<\/figure>\n<pre><code class=\"cs\">static async Task Main(string[] args) {     BotBuilder.DebugSettings.DebugLanguage = LangKey.RU;     BotBuilder.DebugSettings.UpdateLocalsPath(\"resources\/locals\");        var privateMessages = new DefaultSignedMessageUpdateHandler();     \/\/ ... }<\/code><\/pre>\n<figure class=\"full-width\"><\/figure>\n<p>\u0427\u0442\u043e \u0436\u0435, \u043d\u0430 \u0434\u0430\u043d\u043d\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u043d\u0430\u0448\u0430 \u0437\u0430\u0442\u0435\u044f \u0441\u043e \u0441\u043c\u0435\u043d\u043d\u043e\u0439 \u044f\u0437\u044b\u043a\u0430 \u043e\u0442\u043b\u0430\u0434\u043a\u0438 \u043f\u0440\u043e\u0432\u0430\u043b\u0438\u043b\u0430\u0441\u044c: \u0432\u044b\u0432\u043e\u0434 \u043e\u0441\u0442\u0430\u043b\u0441\u044f \u043d\u0430 \u0430\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u043e\u043c. \u041e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u043d\u0430\u0434\u0435\u044f\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u0432 \u0431\u0443\u0434\u0443\u0449\u0438\u0445 \u0432\u0435\u0440\u0441\u0438\u044f\u0445 (\u043d\u0430 \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f &#8212; <strong>1.4.3<\/strong>) \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043e.<\/p>\n<p>\u0421\u0435\u0439\u0447\u0430\u0441 \u0436\u0435, \u043a\u043e\u0433\u0434\u0430 \u0432\u0441\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u044b, \u0432\u0435\u0440\u043d\u0451\u043c\u0441\u044f \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043a \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e \u0431\u043e\u0442\u0430.<\/p>\n<h2>\u041f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435<\/h2>\n<p>\u0418\u0442\u0430\u043a, \u043a\u0430\u043a \u044f \u0432\u0438\u0436\u0443 \u0434\u0430\u043d\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435?<\/p>\n<p>\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0434\u043e\u043b\u0436\u0435\u043d \u0438\u043c\u0435\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c: \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043f\u043e\u0433\u043e\u0434\u0443 \u0432 \u0433\u043e\u0440\u043e\u0434\u0435, \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0433\u043e\u0440\u043e\u0434 \u0432 \u0438\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0435, \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0438\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0435, \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0438\u0437 \u0438\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0433\u043e.<\/p>\n<p>\u0412\u0441\u0451, \u0447\u0442\u043e \u043a\u0430\u0441\u0430\u0435\u0442\u0441\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0438 \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0446\u0438\u0438 \u0434\u0430\u043d\u043d\u044b\u0445, \u0432 \u0438\u0434\u0435\u0430\u043b\u0435 \u043c\u043e\u0436\u0435\u0442 \u0440\u0435\u0448\u0430\u0442\u044c\u0441\u044f \u0447\u0435\u0440\u0435\u0437 SKitLs.Bots.Telegram.DataBases. \u041e\u0434\u043d\u0430\u043a\u043e \u043d\u0430 \u043c\u043e\u043c\u0435\u043d\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u044c\u0438 \u0434\u0430\u043d\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435, \u0445\u043e\u0442\u044c \u0438 \u0447\u0438\u0441\u043b\u0438\u0442\u0441\u044f, \u043d\u043e \u0435\u0449\u0451 \u043d\u0435 \u0432\u044b\u043f\u0443\u0449\u0435\u043d\u043e \u0432 \u0432\u0438\u0434\u0435 \u043f\u0430\u043a\u0435\u0442\u0430, \u0430 \u043f\u043e\u0442\u043e\u043c\u0443 \u0431\u0443\u0434\u0435\u043c \u0438\u043c\u043f\u0440\u043e\u0432\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c.<\/p>\n<p>\u0420\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u0431\u043e\u0442\u0430 \u044f \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u044e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043e\u0434\u043d\u043e\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u044b &#8216;\/start&#8217; \u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 SKitLs.Bots.Telegram.PageNavs (1.3.1, \u0442\u0430\u043a\u0436\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d \u0447\u0435\u0440\u0435\u0437 NuGet), \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0435\u0433\u043e \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043c\u0438\u043d\u0438-\u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u044e \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u043e\u0434\u043d\u043e\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f: \u0441 \u0438\u0441\u0442\u043e\u0440\u0438\u0435\u0439 \u043f\u0435\u0440\u0435\u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0439 \u0438 \u043a\u043d\u043e\u043f\u043a\u0430\u043c\u0438. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0447\u0440\u0435\u0437\u043c\u0435\u0440\u043d\u043e\u0433\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u043a\u043e\u043c\u0430\u043d\u0434.<\/p>\n<p>*.PageNavs \u0437\u0430\u0432\u0438\u0441\u0438\u043c \u043e\u0442 *.AdvancedMessages \u0438 *.ArgedInteractions, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c.<\/p>\n<p>\u0412\u0432\u043e\u0434 \u0434\u0430\u043d\u043d\u044b\u0445 \u043e \u0433\u043e\u0440\u043e\u0434\u0435 \u0431\u044b\u043b\u043e \u0431\u044b \u043d\u0435\u043f\u043b\u043e\u0445\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e *.BotProcesses. \u041e\u0434\u043d\u0430\u043a\u043e \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u044d\u0442\u0430 \u0432\u0435\u0442\u0432\u044c, \u0442\u0430\u043a \u0436\u0435 \u043a\u0430\u043a \u0438 *.DataBases, \u0435\u0449\u0451 \u043d\u0435 \u0432\u044b\u043f\u0443\u0449\u0435\u043d\u0430, \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u0438\u043c\u043f\u0440\u043e\u0432\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c: \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043b\u0435\u0433\u043a\u043e\u0432\u0435\u0441\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043d\u044b\u0439 \u0430\u043d\u0430\u043b\u043e\u0433 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0432, \u0434\u043b\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 *.Stateful \u043f\u0430\u043a\u0435\u0442\u0430, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0435\u0433\u043e \u0437\u0430\u0434\u0430\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u043f\u043e\u043c\u0438\u043c\u043e \u043e\u0431\u0449\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0435\u0449\u0451 \u0438 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0435\u0433\u043e \u0442\u0435\u043a\u0443\u0449\u0435\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0438 \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0435\u0441\u0441\u0438\u0438.<\/p>\n<h2>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439<\/h2>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0431\u043b\u043e\u043a\u0435 \u0432\u043a\u0440\u0430\u0442\u0446\u0435 \u043f\u043e\u043a\u0430\u0436\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u0443\u044e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439. \u0427\u0442\u043e\u0431\u044b \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u043b\u0438\u0441\u044c \u043f\u043e\u0441\u043b\u0435 \u043a\u0430\u0436\u0434\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0438 \u043d\u0435 \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u043b\u0438\u0441\u044c &#8212; \u043e\u043d\u0438 \u0434\u043e\u043b\u0436\u043d\u044b \u0445\u0440\u0430\u043d\u0438\u0442\u044c\u0441\u044f \u0432 \u043f\u0430\u043c\u044f\u0442\u0438 \u0431\u043e\u0442\u0430. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u043e\u0433\u043e <code>UserManager : IUserManager<\/code>, \u0434\u043b\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e, \u0432 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0449\u0438\u0439 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f, \u0442\u0438\u043f\u0430 <code>BotUser : IStatefulUser<\/code>. \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0438\u0445.<\/p>\n<pre><code class=\"cs\">internal class BotUser : IStatefulUser {     public IUserState State { get; set; }     public long TelegramId { get; set; }      public BotUser(long telegramId)     {         State = new DefaultUserState();         TelegramId = telegramId;     }      public void ResetState() => State = new DefaultUserState(); }<\/code><\/pre>\n<pre><code class=\"cs\">internal class UserManager : IUsersManager {     public UserDataChanged? SignedEventHandled => null;      public List&lt;BotUser> Users { get; } = new();      public async Task&lt;IBotUser?> GetUserById(long telegramId) => await Task.FromResult(Users.Find(x => x.TelegramId ==  telegramId));      public async Task&lt;bool> IsUserRegistered(long telegramId) => await GetUserById(telegramId) is not null;      public async Task&lt;IBotUser?> RegisterNewUser(ICastedUpdate update)     {         var user = ChatScanner.GetSender(update.OriginalSource, this)!;         var @new = new BotUser(user.Id);         Users.Add(@new);         return await Task.FromResult(@new);     } }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u043c UserManager \u043a \u043d\u0430\u0448\u0435\u043c\u0443 \u0431\u043e\u0442\u0443 \u0432 ChatDesigner \u0438 \u043f\u0435\u0440\u0435\u043f\u0438\u0448\u0435\u043c \u043a\u043e\u0434 &#8216;\/start&#8217;, \u0447\u0442\u043e\u0431\u044b \u0431\u044b\u043b\u043e \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u043e \u0432\u0438\u0434\u043d\u043e, \u043a\u0430\u043a \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442.<\/p>\n<pre><code class=\"cs\">static async Task Main(string[] args) {     \/\/ ...      ChatDesigner privates = ChatDesigner.NewDesigner()         .UseUsersManager(new UserManager())         .UseMessageHandler(privateMessages);          \/\/ ... }  private static async Task Do_StartAsync(SignedMessageTextUpdate update) {     if (update.Sender is IStatefulUser sender)     {         int st = (sender.State.StateId + 1) % 2;         var text = st == 0             ? \"Start command \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u0430 \u0438\u0437 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f 0\"             : \"\u0410\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u043e \u0434\u0440\u0443\u0433\u043e\u0439 \u0442\u0435\u043a\u0441\u0442, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0441\u043a\u0430\u0437\u0430\u043d\u043e, \u0447\u0442\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f - 1\";         await update.Owner.DeliveryService.ReplyToSender(text, update);         sender.State = new DefaultUserState(st);     } }<\/code><\/pre>\n<figure class=\"full-width\"><\/figure>\n<p>\u041a\u0430\u043a \u043c\u044b \u0432\u0438\u0434\u0438\u043c, \u0440\u0435\u0430\u043a\u0446\u0438\u044f \u0431\u043e\u0442\u0430 \u043d\u0430 \u043e\u0434\u043d\u043e \u0438 \u0442\u043e \u0436\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043a\u0430\u0440\u0434\u0438\u043d\u0430\u043b\u044c\u043d\u043e \u0440\u0430\u0437\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f \u0434\u0430\u0436\u0435 \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043d\u043e\u0439 \u043b\u043e\u0433\u0438\u043a\u0438. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u043e\u0442 \u043d\u0430\u0441 \u044d\u0442\u043e \u043d\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043b\u043e \u0440\u0430\u0434\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0445 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u043a\u043e\u0434\u0430.<\/p>\n<p>\u041f\u043e\u0434\u043e\u0431\u043d\u043e\u0435 \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043d\u0430 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043d\u0430\u043c \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430 \u0432\u0432\u043e\u0434\u0430, \u0434\u043e\u0431\u0430\u0432\u0438\u0432 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f &#171;\u0412\u0432\u043e\u0434\u0438\u0442 \u0413\u043e\u0440\u043e\u0434&#187;, \u043f\u0440\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0431\u043e\u0442 \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u043d\u0435\u0442 \u0440\u0435\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430 \u043f\u0440\u043e\u0447\u0438\u0435 \u0440\u0430\u0437\u0434\u0440\u0430\u0436\u0438\u0442\u0435\u043b\u0438 \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442 \u0438\u043b\u0438 \u043d\u0435 \u043e\u0442\u043c\u0435\u043d\u0438\u0442 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0432\u0432\u043e\u0434\u0430.<\/p>\n<h2>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043c\u0435\u043d\u044e<\/h2>\n<p>\u041c\u0435\u043d\u044e (\u0438\u0437 *.PageNavs), \u043f\u0430\u0434\u0430\u044e\u0449\u0435\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u043f\u043e \u043a\u043e\u043c\u0430\u043d\u0434\u0435 &#8216;\/start&#8217; \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u0442\u044c \u0438\u0437 2 \u043a\u043d\u043e\u043f\u043e\u043a: \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u0430\u044f \u043a\u043d\u043e\u043f\u043a\u0430 &#8216;> \u0418\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0435&#8217; \u0438 \u0430\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u043e\u043d\u043d\u0430\u044f &#8216;\u041d\u0430\u0439\u0442\u0438&#8217;.<\/p>\n<p>\u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043c\u0435\u043d\u044e \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 \u0431\u043e\u0442\u0430 \u0441\u0435\u0440\u0432\u0438\u0441 \u0442\u0438\u043f IMenuManager, \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u044f\u0442\u0441\u044f \u0441\u0435\u0440\u0432\u0438\u0441 IArgsSerializer (\u0438\u0437 *.ArgedInteractions) \u0438 \u043f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u0430\u044f \u0441\u043b\u0443\u0436\u0431\u0430 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 (\u0438\u0437 *.AdvancedMessages).<\/p>\n<pre><code class=\"cs\">await BotBuilder.NewBuilder(\"your_token\")     .EnablePrivates(privates)     .AddService&lt;IArgsSerilalizerService>(new DefaultArgsSerilalizerService())     .AddService&lt;IMenuManager>(GetMenuManager())     .CustomDelievery(new AdvancedDeliverySystem())     .Build()     .Listen();<\/code><\/pre>\n<p>\u0420\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u0430 \u0447\u0435\u0440\u0435\u0437 <code>GetMenuManager()<\/code><\/p>\n<pre><code class=\"cs\">\/\/ Program private static IMenuManager GetMenuManager() {     var mm = new DefaultMenuManager();      var mainBody = new OutputMessageText(\"\u0414\u043e\u0431\u0440\u043e \u043f\u043e\u0436\u0430\u043b\u043e\u0432\u0430\u0442\u044c!\\n\\n\u0427\u0435\u0433\u043e \u0436\u0435\u043b\u0430\u0435\u0442\u0435?\");     var mainMenu = new PageNavMenu();     var mainPage = new StaticPage(\"main\", \"\u0413\u043b\u0430\u0432\u043d\u0430\u044f\", mainBody, mainMenu);      var savedBody = new DynamicMessage(u =>     {         return new OutputMessageText(\"_\u0417\u0434\u0435\u0441\u044c \u0431\u0443\u0434\u0443\u0442 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c\u0441\u044f \u0438\u0437\u0431\u0440\u0430\u043d\u043d\u044b\u0435..._\");     });     var savedPage = new WidgetPage(\"saved\", \"\u0418\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0435\", savedBody);      mainMenu.PathTo(savedPage);     mainMenu.AddAction(StartSearching);      mm.Define(mainPage);     mm.Define(savedPage);      return mm; }  \/\/ \u042d\u0442\u043e\u0442 \u043a\u043e\u043b\u043b\u0431\u044d\u043a \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u043f\u043e\u0438\u0441\u043a. \u041f\u043e\u043a\u0430 \u0447\u0442\u043e \u043f\u0440\u043e\u0442\u043e\u0442\u0438\u043f. private static DefaultCallback StartSearching => new(\"startSearch\", \"\u041d\u0430\u0439\u0442\u0438\", Do_SearchAsync); private static async Task Do_SearchAsync(SignedCallbackUpdate update) { }<\/code><\/pre>\n<p>\u041f\u0435\u0440\u0435\u043f\u0438\u0448\u0435\u043c \u043a\u043e\u043c\u0430\u043d\u0434\u0443 &#8216;\/start&#8217;, \u0447\u0442\u043e\u0431\u044b \u043e\u043d\u0430 \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u043b\u0430 \u043c\u0435\u043d\u044e<\/p>\n<pre><code class=\"cs\">\/\/ Program private static async Task Do_StartAsync(SignedMessageTextUpdate update) {     var mm = update.Owner.ResolveService&lt;IMenuManager>();      \/\/ \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043f\u043e id     \/\/ ...StaticPage( { \u044d\u0442\u043e id -> } \"main\", \"\u0413\u043b\u0430\u0432\u043d\u0430\u044f\"...     var page = mm.GetDefined(\"main\");          await mm.PushPageAsync(page, update); }<\/code><\/pre>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c. \u0412\u0441\u0451 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442. \u041f\u0440\u043e\u0431\u0443\u0435\u043c \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0438 \u0441\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u0435\u043c\u0441\u044f \u0441 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u043e\u0439.<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u041c\u0435\u043d\u044e \u043e\u0442\u043a\u0440\u044b\u043b\u043e\u0441\u044c<\/figcaption><\/div>\n<\/figure>\n<figure class=\"full-width\">\n<div><figcaption>\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u043f\u043e\u043f\u044b\u0442\u043a\u0435 \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435.<\/figcaption><\/div>\n<\/figure>\n<p>\u0414\u0435\u043b\u043e \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043d\u0430\u0448 \u0431\u043e\u0442 \u043d\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u043d\u0438\u043a\u0430\u043a\u043e\u0433\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0434\u043b\u044f Callback-\u043e\u0432. \u0418 \u0445\u043e\u0442\u044f \u043c\u044b \u043d\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u043b\u0438 \u043d\u0430\u0448 \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 <code>DefaultCallback StartSearching<\/code>, \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e MenuManager \u0442\u0430\u043a\u0436\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d \u043d\u0430 Callback.<\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u044d\u0442\u043e<\/p>\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-350997","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/350997","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=350997"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/350997\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=350997"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=350997"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=350997"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}