좋은 기회를 얻어 Azure 그룹의 강창훈 선생님의 강의를 들을 수 있었다.
같이 챗봇을 만들어보면서 정리를 해보았다.
마이크로소프트의 Azure 서비스를 이용하여 손쉽게 챗봇을 만들 수 있다. 언어는 C#을 이용한다.
그러면 PaaS Platform as a Service를 이용하게 되는 것이다. LaaS는 aws같이 인프라를 구축해주는 서비스이고 PaaS는 웹 호스팅 처럼 소스만 업로드하면 곧 바로 서비스를 할 수 있는 간편한 방법이다. 더 나아가 FaaS 는 azure function이나 aws lambda 같은 서비스를 의미하고 SaaS는 아이디만 있으면 이용할 수 있는 이메일과 같은 서비스를 말한다.
비주얼 스튜디오 2017에서 새 프로젝트를 만들어 하단의 Visual Studio 솔루션에서 빈 프로젝트를 생성한다.
그리고 우측 솔루션 탐색기에서 솔루션을 우 클릭 하여 새 프로젝트를 추가를 한다. 봇 어플리케이션이란 것을 추가한다.
이전에 https://marketplace.visualstudio.com/items?itemName=BotBuilder.BotBuilderV3 여기에서 툴 박스를 최신화할 수 있다.
그러면 기본 프로젝트가 생성이 된다.
컨트롤러 폴더에서 MessageController.cs 라는 파일이 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | namespace BotApplication1 { [BotAuthentication] public class MessagesController : ApiController { /// <summary> /// POST: api/Messages /// Receive a message from a user and reply to it /// </summary> public async Task<HttpResponseMessage> Post([FromBody]Activity activity) { if (activity.GetActivityType() == ActivityTypes.Message) { await Conversation.SendAsync(activity, () => new Dialogs.RootDialog()); } else { HandleSystemMessage(activity); } var response = Request.CreateResponse(HttpStatusCode.OK); return response; } private Activity HandleSystemMessage(Activity message) { string messageType = message.GetActivityType(); if (messageType == ActivityTypes.DeleteUserData) { // Implement user deletion here // If we handle user deletion, return a real message } else if (messageType == ActivityTypes.ConversationUpdate) { // Handle conversation state changes, like members being added and removed // Use Activity.MembersAdded and Activity.MembersRemoved and Activity.Action for info // Not available in all channels } else if (messageType == ActivityTypes.ContactRelationUpdate) { // Handle add/remove from contact lists // Activity.From + Activity.Action represent what happened } else if (messageType == ActivityTypes.Typing) { // Handle knowing that the user is typing } else if (messageType == ActivityTypes.Ping) { } return null; } } } | cs |
line 14 : 챗봇이 사용자에게 받을 때나 보낼 때 activity를 사용한다. 여기서 SendAsync로 Dialog를 보내는데 Dialog는 주제에 대한 메세지를 보낸다.
예를들어 "인사"만 관리하는 다이얼로그, "예약"을 관리하는 다이얼로그 등이 있을 수 있다. 그래서 큰 서비스에서는 하나의 다이얼로그가 아닌 여러 다이얼로그로 구분하는 것이 효율적이다. 현재 RootDialog로 연결이 되어 있는데 코드는 밑과 같다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | namespace BotApplication1.Dialogs { [Serializable] public class RootDialog : IDialog<object> { public Task StartAsync(IDialogContext context) { context.Wait(MessageReceivedAsync); return Task.CompletedTask; } private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<object> result) { var activity = await result as Activity; // Calculate something for us to return int length = (activity.Text ?? string.Empty).Length; // Return our reply to the user await context.PostAsync($"You sent {activity.Text} which was {length} characters"); context.Wait(MessageReceivedAsync); } } } | cs |
MessageReceivedAsync는 사용자의 메세지를 담아온다. IDialog인터페이스를 구현하는 RootDialog의 StartAsync메소드는 생성자, 진입점 역할을 한다. context.Wait는 대화의 흐름을 멈춘다는 의미이다. 그러면 이 메소드안에 사용자가 입력한 메세지가 들어가게 되는데 IAwaitable의 object형식으로 모든것을 받아서 activity로 형 변환을 해준다. 그리고 샘플에서는 길이를 계산에서 다시 PostAsync로 사용자 화면에 뿌려준다.
마지막 line23에서 재귀호출을 하였는데 샘플은 계속해서 echo기능을 하기 때문이다. 이 부분을 수정하여 흐름을 태우는 것이다.