Cykl chatboty #2: tworzenie podstawowej wersji chatbota EchoBot

Visual Studio bot C# template

Na początku należy zainstalować odpowiednie SDK, więc wystarczy w Visual Studio (na przykładzie Visual Studio 2019) wejść w Extensions -> Manage Extensions i z listy Online wyszukać „Bot Framework v4 SDK Templates” (można też zrobić to osobno, pobierając paczkę pod linkiem).

Następnie możemy utworzyć nowy projekt i przy wyborze wybrać najprostszego Echo bota (będzie odpowiadał to, co się do niego napisze).

I gotowe, cała solucja jest już przygotowana:

BotController

To, na co warto zwrócić na początek uwagę, to jeden controller o nazwie BotController, który obsługuje tylko jedną metodę POST pod url api/messages:

[Route("api/messages")]
[ApiController]
public class BotController : ControllerBase
{
	private readonly IBotFrameworkHttpAdapter Adapter;
	private readonly IBot Bot;

	public BotController(IBotFrameworkHttpAdapter adapter, IBot bot)
	{
		Adapter = adapter;
		Bot = bot;
	}

	[HttpPost]
	public async Task PostAsync()
	{
		// Delegate the processing of the HTTP POST to the adapter.
		// The adapter will invoke the bot.
		await Adapter.ProcessAsync(Request, Response, Bot);
	}
}

Pod ten endpoint będą wysyłane wszystkie zapytania do bota i jak widać na przykładzie odpowiedni adapter IBotFrameworkHttpAdapter będzie je przeprocesowywał dalej.

Bot Startup

Jeśli chcemy zobaczyć, skąd się wziął adapter, możemy zerknąć do pliku Startup. Najważniejsza jest metoda ConfigureServices():

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
	services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

	// Create the Bot Framework Adapter with error handling enabled.
	services.AddSingleton<IBotFrameworkHttpAdapter, AdapterWithErrorHandler>();

	// Create the bot as a transient. In this case the ASP Controller is expecting an IBot.
	services.AddTransient<IBot, EchoBot>();
}

Rejestruje ona IBotFrameworkHttpAdapter oraz IBot. Zaraz przejdziemy do opisu rejestrowanych klas.

EchoBot

W ważną klasą jest klasa EchoBot, która dziedziczy po klasie ActivityHandler. To ona odpowiada za logikę odpowiedzi bota. W naszym przypadku logika jest prosta i składają się na nią 2 metody:

  1. OnMessageActivityAsync() – gdy otrzymasz wiadomość od użytkownika, odpisz mu „Echo:” i wiadomość, którą wysłał.
  2. OnMembersAddedAsync() – gdy jakikolwiek użytkownik dołączy do konwersacji, powitaj go tekstem „Hello and welcome”.
public class EchoBot : ActivityHandler
{
	protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
	{
		await turnContext.SendActivityAsync(MessageFactory.Text($"Echo: {turnContext.Activity.Text}"), cancellationToken);
	}

	protected override async Task OnMembersAddedAsync(IList<ChannelAccount> membersAdded, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
	{
		foreach (var member in membersAdded)
		{
			if (member.Id != turnContext.Activity.Recipient.Id)
			{
				await turnContext.SendActivityAsync(MessageFactory.Text($"Hello and welcome!"), cancellationToken);
			}
		}
	}
}

BotFrameworkHttpAdapter

Happy path dla bota jest prosty – przywitaj się i odpisz echo. Ale co ma się wydarzyć, gdy coś pójdzie źle? Tutaj właśnie przydaje się nasz adapter AdapterWithErrorHandler. Gdy zostanie wywołany event OnTurnError, ma on 2 zadania:

  1. Zalogować wyjątek.
  2. Wysłać wiadomość do użytkownika, że coś poszło nie tak.
public class AdapterWithErrorHandler : BotFrameworkHttpAdapter
{
	public AdapterWithErrorHandler(IConfiguration configuration, ILogger<BotFrameworkHttpAdapter> logger)
		: base(configuration, logger)
	{
		OnTurnError = async (turnContext, exception) =>
		{
			// Log any leaked exception from the application.
			logger.LogError($"Exception caught : {exception.Message}");

			// Send a catch-all apology to the user.
			await turnContext.SendActivityAsync("Sorry, it looks like something went wrong.");
		};
	}
}

Uruchomienie bota

Po uruchomieniu projektu (wystarczy F5) powinniśmy zobaczyć stronę:

To znaczy, że API naszego bota działa i jest dostępne pod localhost:3978/api/messages.

Bot Framework Emulator

Żeby jednak móc porozmawiać z botem, potrzebujemy specjalnego lokalnego czatu. Potrzebujemy więc pobrać odpowiedni program Bot Framework Emulator.

Po zainstalowaniu i otwarciu programu, wybieramy opcję Open bot z głównego ekranu i wpisujemy url:

Po kliknięciu Connect otwiera nam się nowa zakładka:

Jak widać, bot się z nami przywitał. Po prawej stronie widzimy dokładne logi konwersacji (informacje o requestach i rozpoznanych typach eventów).

Spróbujmy coś napisać do bota:

Odpisał! Działa 🙂

W tym odcinku to tyle. W przyszłym odcinku wykorzystując narzędzie azure-cli zreleasujemy naszego bota. Zasoby bota znajdą się w chmurze i każdy bedzie mógł z nim rozmawiać (będzie publiczny).

Jeśli temat Cię zaciekawił, to zerknij jeszcze na pozostałe posty o tematyce botów 🙂


Post powstał pod patronatem firmy, w której aktualnie pracuję: Objectivity.

Grafikę tytułową zaprojektował niezastąpiony zespół designu!

Skomentuj

Wprowadź swoje dane lub kliknij jedną z tych ikon, aby się zalogować:

Logo WordPress.com

Komentujesz korzystając z konta WordPress.com. Wyloguj /  Zmień )

Zdjęcie na Facebooku

Komentujesz korzystając z konta Facebook. Wyloguj /  Zmień )

Połączenie z %s