본문 바로가기
Develop/Toy Projects

[프로젝트] #1 - 심심이(SimSimi) API를 이용한 채팅 프로그램 만들기 😀🧨

by KyungHoon 2020. 6. 7.

안녕하세요 이번 포스트에서는 심심이(SimSimi) API를 이용하여 대화를 할 수 있는 프로그램을 만들어 보려고 합니다. 웹상에서만 심심이와 대화를 할 수 있었던 것을 보고 윈도우 응용프로그램으로 옮겨보고 싶어서 만들게 되었습니다. API를 사용할 수 있는 주소는 아래에 첨부해 두겠습니다. 그러면 지금부터 심심이 API를 이용해서 채팅 프로그램 만들기 시작하겠습니다.🏳‍🌈

 


이번 포스트는 총 2편으로 진행하려고 합니다. 1편에서는 심심이 API를 어떻게 사용하는지, 어떻게 요청을 보내는지에 대한 전체적인 로직(Model, ViewModel) 작업을 진행하려고 합니다. 그리고 2편에서는 요청한 데이터를 이용하여 UI상에 나타내고 디자인을 해보려고 합니다. 그러면 시작하겠습니다..!

 

 

🧨 1편 - 심심이(SimSimi API) 사용법과 CURL 요청 방법(Model, ViewModel) 작업.

 

🧨 2편 - CURL 요청을 통해 받아오는 메시지와 사용자의 메시지를 UI에 나타내어 보자!

 

 

https://workshop.simsimi.com/

 

 

SimSimi Workshop

Make a chatbot that allows for small talks.

workshop.simsimi.com

 

위의 링크에서 간단한 이메일 인증만 하시면 데모 프로젝트로 100회 동안 무료로 API를 사용할 수 있습니다. 저는 프로그램을 만들고 UI 작업을 하느라 계정을 더 만들어서 사용을 했었습니다 😅

 


 

간단한 인증절차를 거치고 대시보드로 이동을 하게 되면 DemoProject로 얼마나 사용했는지 몇 번 남았는지를 확인할 수 있습니다. API 키는 나중에 POST로 요청을 보낼 때 사용하게 됩니다.

 

 

대시 보드(Dash Board)

 


 

그러면 이제부터 본격적으로 심심이와 채팅을 할 수 있는 프로그램을 만들어 볼게요. 먼저 VisualStudio에서 WPF App으로 프로젝트를 하나 생성해 주세요. 저는 전체적인 구조를 ListView 두 개를 이용해서 화면의 왼쪽에는 심심이가 보내주는 메시지를, 화면의 오른쪽에는 사용자의 메시지를 띄어주려고 하였습니다.

 

그전에 모델부터 만들어 주도록 하겠습니다. 사실 모델은 분리를 하지 않고 ViewModel에서 그냥 사용하려고 하였는데, 막상 짜고 보니 복잡해 보여서 분리를 하였습니다. 모델 폴더를 만들고 그 안에 SimSimi 모델과 User의 모델을 만들어 주었습니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
using Prism.Mvvm;
 
namespace SimSimi_Talk.Model
{
    public class User : BindableBase
    {
        private string _userMessage;
        public string UserMessage
        {
            get => _userMessage;
            set
            {
                SetProperty(ref _userMessage, value);
            }
        }
    }
}
 
cs

   Model - User

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
using Prism.Mvvm;
 
namespace SimSimi_Talk.Model
{
    public class SimSimi : BindableBase
    {
        private string _simSimiMessage;
        public string SimSimiMessage
        {
            get => _simSimiMessage;
            set
            {
                SetProperty(ref _simSimiMessage, value);
            }
        }
    }
}
 
cs

       Model - SimSimi


 

이제는 ViewModel을 제작해보도록 할게요. 저는 ViewModel 폴더안에 SimSimiViewModel을 만들었습니다. 그리고 ListView에 ItemSource를 바인딩하기 위한 UserMsgItems와 SimSimiMsgItems를 ObservableCollection으로 프로퍼티를 만들어 두었습니다. 그리고 GetSimSimiMessage 메서드를 통해 사용자의 대화를 전달하여 심심이의 메시지를 받아오도록 하였습니다. 자세한 설명은 아래의 코드를 보면서 하도록 할게요.

 

API 사용 방법

 

코드를 보기전에 요청 방법을 먼저 보도록 할게요. 저는 처음 이 요청 예시를 보았을 때 살짝 당황을 했습니다. 기존의 오픈 API의 요청이나 사용방법과 다르게 CURL 요청을 해야 했습니다. CURL이란 Client URL로 서버와 통신할 수 있는 커맨드 명령어 툴이었습니다. 기존 SimSimi API의 요청 방식을 보도록 할게요. 이것을 사용하려면 리눅스 또는 가상 머신 환경에서 패키지 관리 시스템을 통해 설치를 해야 했습니다. 

 

-i -v -X -H -d
응답의 헤더를 출련한다. 중간 처리 과정, 오류 메시지, 요청 메시지와 응답메시지를 헤더와 본문을 포함하여 전체를 출력한다. 요청할 메소드를 지정한다. (GET, POST, DELETE, UPDATE...) 요청의 헤더를 지정해준다. 요청의 본문을 지정한다.

CURL 요청

 

 

그래서 저는 CURL 요청을 하기 위해 검색을 하고, 찾아보고 여러 과정을 거쳐서 아래의 GetSimSimiMessage() 메서드를 만들게 되었습니다. UI상에서 사용자가 메시지를 입력하면 그 메시지를 인자로 받아 POST 요청을 합니다. 그러면 심심이가 메시지를 받고 사용자의 메시지는 UserMsgItems에 저장이 되고, 심심이의 메시지는 SimSimiMsgItems에 저장이 됩니다. Property에 대해서는 아래에 첨부해 두도록 하겠습니다.

 

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
public async void GetSimSimiMessage(string userMsg)
{
    using (var httpClient = new HttpClient())
    {
        using (var request = new HttpRequestMessage(new HttpMethod("POST"), API_URL))
        {
            request.Headers.TryAddWithoutValidation
            (
                "x-api-key"" 발급받은 API - KEY VALUE "
            );
 
            request.Content = new StringContent("{\n \"utext\": \"" + userMsg + "\", \n\"lang\": \"ko\" \n}");
            request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
 
            var response = await httpClient.SendAsync(request);
            string res = await response.Content.ReadAsStringAsync();
 
            JToken jToken = JToken.Parse(res);
                    
            string sMsg = jToken["atext"].ToString();
 
            User user = new User();
            SimSimi simSimi = new SimSimi();
 
            user.UserMessage = userMsg;
            simSimi.SimSimiMessage = sMsg;
 
            // Property Value Add
            UserMsgItems.Add(user);
            SimSimiMsgItems.Add(simSimi);
        }
    }
}
cs

SimSimiViewModel.cs - GetSimSimiMessage() 메서드

 

 

중간에 JToken으로 Parse()를 해주는 이유는 키 값으로 "atext"에 접근을 해서 메시지를 빼내 오기 위해서입니다.

또한 response를 응답받은 후 response.Content.ReadAsStringAsync()를 해주는 이유는 응답의 Content의

값을 가져오기 위해서 해주는 것입니다.

 

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
private const string API_URL = "https://wsapi.simsimi.com/190410/talk";
 
#region Properties
private ObservableCollection<User> _userMsgItems = new ObservableCollection<User>();
public ObservableCollection<User> UserMsgItems
{
    get => _userMsgItems;
    set
    {
        SetProperty(ref _userMsgItems, value);
    }
}
 
private ObservableCollection<SimSimi> _simSimiMsgItems = new ObservableCollection<SimSimi>();
public ObservableCollection<SimSimi> SimSimiMsgItems
{
    get => _simSimiMsgItems;
    set
    {
        SetProperty(ref _simSimiMsgItems, value);
    }
}
 
private double _tbMsgHeight;
public double TbMsgHeight
{
    get => _tbMsgHeight;
    set
    {
        SetProperty(ref _tbMsgHeight, value);
    }
}
#endregion
cs

Properties

 


이렇게 Model과 ViewModel을 다 만들었습니다. 이러고 나서 GetSimSimiMessage()의 인자로 사용자의 메시지만 인자로 넘기게 되면 성공적으로 심심이의 메시지를 받아올 수 있을 것입니다. 한번 실행해 볼까요?

 

결과 화면

 

어떤가요? 성공적으로 메시지가 받아와 졌나요? 오늘은 여기까지 하겠습니다. 다음 2편에서는 이 받은 메시지를 UI상에 띄우고 디자인을 한 후 연속적으로 대화를 할 수 있도록 하겠습니다. 감사합니다 😄

댓글