https://github.com/seralexeev/alice-dotnet
Пример простого скилла для платформы Яндекс.Диалоги на c#
https://github.com/seralexeev/alice-dotnet
alice csharp dotnet
Last synced: 4 months ago
JSON representation
Пример простого скилла для платформы Яндекс.Диалоги на c#
- Host: GitHub
- URL: https://github.com/seralexeev/alice-dotnet
- Owner: seralexeev
- Created: 2018-06-05T21:48:08.000Z (about 8 years ago)
- Default Branch: master
- Last Pushed: 2018-06-05T21:56:37.000Z (about 8 years ago)
- Last Synced: 2024-07-30T19:27:20.462Z (almost 2 years ago)
- Topics: alice, csharp, dotnet
- Language: C#
- Homepage: https://dialogs.yandex.ru/
- Size: 12.7 KB
- Stars: 20
- Watchers: 4
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
- awesome-alice - seralexeev/alice-dotnet - Пример на С# и .NET Core (Примеры и навыки / Примеры)
README
# alice dotnet
Данный репозиторий содержит пример создания скилла для Алисы на языке c# под платформу .net core 2.1
## Подготовка
- Для начала необходимо установить `dotnet sdk`
- (с официального сайта) идем на https://www.microsoft.com/net/download и скачиваем `2.1 SDK (v2.1.300)` и устанавливаем
- brew
- apt-get
- Создаем новый проект
```bash
$ dotnet new console -o alice
```
- добавляем нужные зависимости:
```bash
$ dotnet add package Microsoft.AspNetCore
$ dotnet add package Microsoft.AspNetCore.Mvc
```
## Создание сервера
1. Удаляем файл Program.cs, он нам не нужен и создаем файл `Alice.cs`, в этом файле будет наш контроллер вебхука
2. Добавляем импорты:
```csharp
// Alice.cs
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
```
3. Создаем класс `Alice` унаследованный от класса `Controller` это файл будет содержать бутстрапинг сервера и простой ответ
```csharp
// Alice.cs
public class Alice : Controller {
}
```
4. Добавляем метод `CreateWebHostBuilder` - этот метод создаст объект `IWebHostBuilder`, добавит сервисы необходимые для `mvc` и настроит дефолтный роутинг
```csharp
// Alice.cs
public class Alice : Controller {
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureServices(srv => srv.AddMvc())
.Configure(app => app.UseMvc());
}
```
5. Далее создадим точку входа в наше приложение которое получит объект из пунка 4 и запустит хост
```csharp
static void Main(string[] args) => CreateWebHostBuilder(args).Build().Run();
```
6. Наш веб сервер готов, запустить можно его просто командой
```bash
$ dotnet run
```
сервер запустится и выведет на экран примерно следующее:
```bash
info: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[0]
User profile is available. Using '/Users/seralexeev/.aspnet/DataProtection-Keys' as key repository; keys will not be encrypted at rest.
Hosting environment: Production
Content root path: /Users/seralexeev/projects/alice-dotnet
Now listening on: http://localhost:5000
Now listening on: https://localhost:5001
Application started. Press Ctrl+C to shut down.
```
Наш сервер будет доступен на 5000 и 5001 портах, изменить это поведение можно добавив параметр `--urls`
```bash
$ dotnet run --urls "http://localhost:3000"
Hosting environment: Production
Content root path: /Users/seralexeev/projects/alice-dotnet
Now listening on: http://localhost:3000
Application started. Press Ctrl+C to shut down.
```
## Описание протокола
Для взаимодействия с api опишем классы в соответсвии с https://tech.yandex.ru/dialogs/alice/doc/protocol-docpage
```csharp
// Models.cs
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
public class SessionModel {
[JsonProperty("new")]
public bool New { get; set; }
[JsonProperty("session_id")]
public string SessionId { get; set; }
[JsonProperty("message_id")]
public int MessageId { get; set; }
[JsonProperty("skill_id")]
public string SkillId { get; set; }
[JsonProperty("user_id")]
public string UserId { get; set; }
}
public class ResponseModel {
[JsonProperty("text")]
public string Text { get; set; }
[JsonProperty("tts")]
public string Tts { get; set; }
[JsonProperty("end_session")]
public bool EndSession { get; set; }
[JsonProperty("buttons")]
public ButtonModel[] Buttons { get; set; }
}
public class ButtonModel {
[JsonProperty("title")]
public string Title { get; set; }
[JsonProperty("payload")]
public object Payload { get; set; }
[JsonProperty("url")]
public string Url { get; set; }
[JsonProperty("hide")]
public bool Hide { get; set; }
}
public class MetaModel {
[JsonProperty("locale")]
public string Locale { get; set; }
[JsonProperty("timezone")]
public string Timezone { get; set; }
[JsonProperty("client_id")]
public string ClientId { get; set; }
}
public class AliceRequest {
[JsonProperty("meta")]
public MetaModel Meta { get; set; }
[JsonProperty("request")]
public RequestModel Request { get; set; }
[JsonProperty("session")]
public SessionModel Session { get; set; }
[JsonProperty("version")]
public string Version { get; set; }
}
public enum RequestType {
SimpleUtterance,
ButtonPressed
}
public class RequestModel {
[JsonProperty("command")]
public string Command { get; set; }
[JsonProperty("type")]
public RequestType Type { get; set; }
[JsonProperty("original_utterance")]
public string OriginalUtterance { get; set; }
[JsonProperty("payload")]
public JObject Payload { get; set; }
}
public class AliceResponse {
[JsonProperty("response")]
public ResponseModel Response { get; set; }
[JsonProperty("session")]
public SessionModel Session { get; set; }
[JsonProperty("version")]
public string Version { get; set; } = "1.0";
}
```
и добавим метод расширения для `AliceRequest` для простого создания ответа
```csharp
// Extensions.cs
public static class Extensions {
public static AliceResponse Reply(
this AliceRequest req,
string text,
bool endSession = false,
ButtonModel[] buttons = null) => new AliceResponse {
Response = new ResponseModel {
Text = text,
Tts = text,
EndSession = endSession
},
Session = req.Session
};
}
```
## Ответ webhook
На последнем шаге необходимо добавить эндпоинт который и зарегистрируем в платформе диалогов
```csharp
// Alice.cs
public class Alice : Controller {
...
[HttpPost("/alice")]
public AliceResponse WebHook([FromBody] AliceRequest req) => req.Reply("Привет");
...
}
```
В итоге наш котнтроллер будет выглядить примерно так:
```csharp
// Alice.cs
public class Alice : Controller {
static void Main(string[] args) => CreateWebHostBuilder(args).Build().Run();
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureServices(srv => srv.AddMvc())
.Configure(app => app.UseMvc());
[HttpPost("/alice")]
public AliceResponse WebHook([FromBody] AliceRequest req) => req.Reply("Привет");
}
```
# Сборка в контейнере и запуск
```bash
$ docker build -t alice .
$ docker run --rm -it -p 5000:80 alice
```
# Консоль разработчика
Для проверки нашего еще неопубликованного скила необходимо зарегистрироваться и создать "Навык в Алисе" на https://dialogs.yandex.ru/developer/
# Тестирование
- Для тестирования оффлайн можно использовать юнит тесты или интеграционные тесты, описанные в классе `AliceTests`
- Для тестирования через консоль разработчика можно использовать `ngrok`
- Запускаем проект в режиме `watch`, dotnet будет следить за изменениями в файлах и перезапускать сервер: `dotnet watch -p src run`
- Запускаем `ngrok`: `ngrok http 5000`
- Прописываем сгенерированный адрес в консоль разработчика, в итоге получаем возможность писать код и сразу проверять его во вкладке тестирования в консоле разработчика