{"id":13400901,"url":"https://github.com/seralexeev/alice-dotnet","last_synced_at":"2026-03-06T00:31:10.992Z","repository":{"id":162046344,"uuid":"136238555","full_name":"seralexeev/alice-dotnet","owner":"seralexeev","description":"Пример простого скилла для платформы Яндекс.Диалоги на c#","archived":false,"fork":false,"pushed_at":"2018-06-05T21:56:37.000Z","size":13,"stargazers_count":20,"open_issues_count":0,"forks_count":2,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-07-30T19:27:20.462Z","etag":null,"topics":["alice","csharp","dotnet"],"latest_commit_sha":null,"homepage":"https://dialogs.yandex.ru/","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/seralexeev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2018-06-05T21:48:08.000Z","updated_at":"2023-09-05T12:46:11.000Z","dependencies_parsed_at":null,"dependency_job_id":"285c7ab0-ed30-445c-86be-78483e91f57a","html_url":"https://github.com/seralexeev/alice-dotnet","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/seralexeev/alice-dotnet","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seralexeev%2Falice-dotnet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seralexeev%2Falice-dotnet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seralexeev%2Falice-dotnet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seralexeev%2Falice-dotnet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/seralexeev","download_url":"https://codeload.github.com/seralexeev/alice-dotnet/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seralexeev%2Falice-dotnet/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30156285,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-05T22:39:40.138Z","status":"ssl_error","status_checked_at":"2026-03-05T22:39:24.771Z","response_time":93,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["alice","csharp","dotnet"],"created_at":"2024-07-30T19:00:56.768Z","updated_at":"2026-03-06T00:31:10.951Z","avatar_url":"https://github.com/seralexeev.png","language":"C#","funding_links":[],"categories":["Примеры и навыки"],"sub_categories":["Примеры"],"readme":"# alice dotnet\n\nДанный репозиторий содержит пример создания скилла для Алисы на языке c# под платформу .net core 2.1\n\n## Подготовка\n\n- Для начала необходимо установить `dotnet sdk`\n  - (с официального сайта) идем на https://www.microsoft.com/net/download и скачиваем `2.1 SDK (v2.1.300)` и устанавливаем\n  - brew\n  - apt-get\n- Создаем новый проект\n\n```bash\n$ dotnet new console -o alice\n```\n\n- добавляем нужные зависимости:\n\n```bash\n$ dotnet add package Microsoft.AspNetCore\n$ dotnet add package Microsoft.AspNetCore.Mvc\n```\n\n## Создание сервера\n\n1.  Удаляем файл Program.cs, он нам не нужен и создаем файл `Alice.cs`, в этом файле будет наш контроллер вебхука\n2.  Добавляем импорты:\n\n```csharp\n// Alice.cs\nusing System;\nusing System.Threading.Tasks;\nusing Microsoft.AspNetCore;\nusing Microsoft.AspNetCore.Hosting;\nusing Microsoft.AspNetCore.Builder;\nusing Microsoft.AspNetCore.Mvc;\nusing Microsoft.Extensions.DependencyInjection;\n```\n\n3.  Создаем класс `Alice` унаследованный от класса `Controller` это файл будет содержать бутстрапинг сервера и простой ответ\n\n```csharp\n// Alice.cs\npublic class Alice : Controller {\n\n}\n```\n\n4.  Добавляем метод `CreateWebHostBuilder` - этот метод создаст объект `IWebHostBuilder`, добавит сервисы необходимые для `mvc` и настроит дефолтный роутинг\n\n```csharp\n// Alice.cs\npublic class Alice : Controller {\n  public static IWebHostBuilder CreateWebHostBuilder(string[] args) =\u003e\n    WebHost.CreateDefaultBuilder(args)\n      .ConfigureServices(srv =\u003e srv.AddMvc())\n      .Configure(app =\u003e app.UseMvc());\n}\n```\n\n5.  Далее создадим точку входа в наше приложение которое получит объект из пунка 4 и запустит хост\n\n```csharp\nstatic void Main(string[] args) =\u003e CreateWebHostBuilder(args).Build().Run();\n```\n\n6.  Наш веб сервер готов, запустить можно его просто командой\n\n```bash\n$ dotnet run\n```\n\nсервер запустится и выведет на экран примерно следующее:\n\n```bash\ninfo: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[0]\n      User profile is available. Using '/Users/seralexeev/.aspnet/DataProtection-Keys' as key repository; keys will not be encrypted at rest.\nHosting environment: Production\nContent root path: /Users/seralexeev/projects/alice-dotnet\nNow listening on: http://localhost:5000\nNow listening on: https://localhost:5001\nApplication started. Press Ctrl+C to shut down.\n```\n\nНаш сервер будет доступен на 5000 и 5001 портах, изменить это поведение можно добавив параметр `--urls`\n\n```bash\n$ dotnet run --urls \"http://localhost:3000\"\n\nHosting environment: Production\nContent root path: /Users/seralexeev/projects/alice-dotnet\nNow listening on: http://localhost:3000\nApplication started. Press Ctrl+C to shut down.\n```\n\n## Описание протокола\n\nДля взаимодействия с api опишем классы в соответсвии с https://tech.yandex.ru/dialogs/alice/doc/protocol-docpage\n\n```csharp\n// Models.cs\nusing Newtonsoft.Json;\nusing Newtonsoft.Json.Linq;\n\npublic class SessionModel {\n  [JsonProperty(\"new\")]\n  public bool New { get; set; }\n\n  [JsonProperty(\"session_id\")]\n  public string SessionId { get; set; }\n\n  [JsonProperty(\"message_id\")]\n  public int MessageId { get; set; }\n\n  [JsonProperty(\"skill_id\")]\n  public string SkillId { get; set; }\n\n  [JsonProperty(\"user_id\")]\n  public string UserId { get; set; }\n}\n\npublic class ResponseModel {\n  [JsonProperty(\"text\")]\n  public string Text { get; set; }\n\n  [JsonProperty(\"tts\")]\n  public string Tts { get; set; }\n\n  [JsonProperty(\"end_session\")]\n  public bool EndSession { get; set; }\n\n  [JsonProperty(\"buttons\")]\n  public ButtonModel[] Buttons { get; set; }\n}\n\npublic class ButtonModel {\n  [JsonProperty(\"title\")]\n  public string Title { get; set; }\n\n  [JsonProperty(\"payload\")]\n  public object Payload { get; set; }\n\n  [JsonProperty(\"url\")]\n  public string Url { get; set; }\n\n  [JsonProperty(\"hide\")]\n  public bool Hide { get; set; }\n}\n\npublic class MetaModel {\n  [JsonProperty(\"locale\")]\n  public string Locale { get; set; }\n\n  [JsonProperty(\"timezone\")]\n  public string Timezone { get; set; }\n\n  [JsonProperty(\"client_id\")]\n  public string ClientId { get; set; }\n}\n\npublic class AliceRequest {\n  [JsonProperty(\"meta\")]\n  public MetaModel Meta { get; set; }\n\n  [JsonProperty(\"request\")]\n  public RequestModel Request { get; set; }\n\n  [JsonProperty(\"session\")]\n  public SessionModel Session { get; set; }\n\n  [JsonProperty(\"version\")]\n  public string Version { get; set; }\n}\n\npublic enum RequestType {\n  SimpleUtterance,\n  ButtonPressed\n}\n\npublic class RequestModel {\n  [JsonProperty(\"command\")]\n  public string Command { get; set; }\n\n  [JsonProperty(\"type\")]\n  public RequestType Type { get; set; }\n\n  [JsonProperty(\"original_utterance\")]\n  public string OriginalUtterance { get; set; }\n\n  [JsonProperty(\"payload\")]\n  public JObject Payload { get; set; }\n}\n\npublic class AliceResponse {\n  [JsonProperty(\"response\")]\n  public ResponseModel Response { get; set; }\n\n  [JsonProperty(\"session\")]\n  public SessionModel Session { get; set; }\n\n  [JsonProperty(\"version\")]\n  public string Version { get; set; } = \"1.0\";\n}\n```\n\nи добавим метод расширения для `AliceRequest` для простого создания ответа\n\n```csharp\n// Extensions.cs\npublic static class Extensions {\n  public static AliceResponse Reply(\n    this AliceRequest req,\n    string text,\n    bool endSession = false,\n    ButtonModel[] buttons = null) =\u003e new AliceResponse {\n      Response = new ResponseModel {\n        Text = text,\n        Tts = text,\n        EndSession = endSession\n      },\n      Session = req.Session\n    };\n}\n```\n\n## Ответ webhook\n\nНа последнем шаге необходимо добавить эндпоинт который и зарегистрируем в платформе диалогов\n\n```csharp\n// Alice.cs\npublic class Alice : Controller {\n  ...\n\n  [HttpPost(\"/alice\")]\n  public AliceResponse WebHook([FromBody] AliceRequest req) =\u003e req.Reply(\"Привет\");\n\n  ...\n}\n```\n\nВ итоге наш котнтроллер будет выглядить примерно так:\n\n```csharp\n// Alice.cs\npublic class Alice : Controller {\n  static void Main(string[] args) =\u003e CreateWebHostBuilder(args).Build().Run();\n\n  public static IWebHostBuilder CreateWebHostBuilder(string[] args) =\u003e\n    WebHost.CreateDefaultBuilder(args)\n      .ConfigureServices(srv =\u003e srv.AddMvc())\n      .Configure(app =\u003e app.UseMvc());\n\n  [HttpPost(\"/alice\")]\n  public AliceResponse WebHook([FromBody] AliceRequest req) =\u003e req.Reply(\"Привет\");\n}\n```\n\n# Сборка в контейнере и запуск\n\n```bash\n$ docker build -t alice .\n$ docker run --rm -it -p 5000:80 alice\n```\n\n# Консоль разработчика\n\nДля проверки нашего еще неопубликованного скила необходимо зарегистрироваться и создать \"Навык в Алисе\" на https://dialogs.yandex.ru/developer/\n\n# Тестирование\n\n- Для тестирования оффлайн можно использовать юнит тесты или интеграционные тесты, описанные в классе `AliceTests`\n- Для тестирования через консоль разработчика можно использовать `ngrok`\n  - Запускаем проект в режиме `watch`, dotnet будет следить за изменениями в файлах и перезапускать сервер: `dotnet watch -p src run`\n  - Запускаем `ngrok`: `ngrok http 5000`\n  - Прописываем сгенерированный адрес в консоль разработчика, в итоге получаем возможность писать код и сразу проверять его во вкладке тестирования в консоле разработчика\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseralexeev%2Falice-dotnet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fseralexeev%2Falice-dotnet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseralexeev%2Falice-dotnet/lists"}