LINEBOT에서 대화 상태(컨텍스트) 관리(세션 관리?)

하고 싶은 일



대화의 스테이터스(컨텍스트)와 같은 것을 서버측에 갖게 해 두고(웹 앱의 세션 같은 느낌?), 그에 의해 응답이 바뀌는 LINEBOT를 만들고 싶다.

이미지로서는 이런 느낌.


자연 언어 해석이라든지, DeepLearning이라든지, RNN이라든지, 잡담 BOT이라든지, 그러한 고도의 이야기가 아닙니다.

실현 방법



사용자 ID를 key, 저장할 값을 모은 클래스를 value로 한 map을 작성하기로 했습니다.

그 외, 메세지에 응답하는 개소의 구현은 sample-spring-boot-kitchensink (을)를 참고로 했습니다 (replyText 메소드).
언어는 Java입니다.

실은 더 왕도의 방법(≒라이브러리, 프레임워크)이 있다, 라고 하는 것이 있으면 꼭 가르쳐 주세요.

상태를 저장하는 클래스



Status.java
public class Status {

    private String context = "0";//ステータス
    private String place = "";//場所

    public String getContext() {
        return context;
    }
    public void setContext(String context) {
        this.context = context;
    }

    public String getPlace() {
        return place;
    }
    public void setPlace(String place) {
        this.place = place;
    }

}

지도



PseudoSession.java
public class PseudoSession {

    private static Map<String,Status> statusMap = new HashMap<>();

    public static Status getStatus(String userId) {
        return PseudoSession.statusMap.get(userId);
    }

    public static void putStatus(String userId, Status status) {
        PseudoSession.statusMap.put(userId, status);
    }

    public static String readContext(String userId) {
        return PseudoSession.statusMap.get(userId).getContext();
    }

    public static String readPlace(String userId) {
        return PseudoSession.statusMap.get(userId).getPlace();
    }

    public static void updateContext(String userId, String context) {
        Status newStatus = PseudoSession.statusMap.get(userId);
        newStatus.setContext(context);
        PseudoSession.statusMap.put(userId, newStatus);
    }

    public static void updatePlace(String userId, String place) {
        Status newStatus = PseudoSession.statusMap.get(userId);
        newStatus.setPlace(place);
        PseudoSession.statusMap.put(userId, newStatus);
    }

}

주요 처리



Controller.java
    private void handleTextContent(String replyToken, Event event, TextMessageContent content)
            throws Exception {
        final String text = content.getText();
        final String userId = event.getSource().getUserId();

        //初めてアクセスするユーザーの場合、mapに値を入れる
        if (Objects.isNull(PseudoSession.getStatus(userId))) {
            PseudoSession.putStatus(userId, new Status());
        }

        if(PseudoSession.readContext(userId).equals("0")) {

            if (text.equals("天気教えて")) {
                this.replyText(replyToken,"どこの天気?");
                PseudoSession.updateContext(userId,"1");
            } else {
                this.replyText(replyToken,"「天気教えて」って入力してみて!");
            }

        }else if (PseudoSession.readContext(userId).equals("1")) {

            if (!("富山".equals(text))&&!("石川".equals(text))) {
                this.replyText(replyToken,"富山か石川しか分からないんだ");
            } else {
                this.replyText(replyToken,"いつの天気?");
                PseudoSession.updatePlace(userId,text);
                PseudoSession.updateContext(userId,"2");
            }

        }else if (PseudoSession.readContext(userId).equals("2")) {

            if (!("今日".equals(text))&&!("明日".equals(text))) {
                this.replyText(
                        replyToken,"今日か明日しか分からないんだ");
            } else {
                String answer = text + "の"
                        + PseudoSession.readPlace(userId) + "の"
                        + "天気は晴れです。";
                this.replyText(replyToken,answer);
                PseudoSession.updatePlace(userId,"");
                PseudoSession.updateContext(userId,"0");
            }
        }
    }


결과



좋은 웹페이지 즐겨찾기