LINEBOTで会話のステータス（文脈）管理（セッション管理？）

##やりたいこと
会話のステータス（文脈）のようなものをサーバー側に持たせておいて（Webアプリのセッションみたいな感じ？）、それによって応答が変わるようなLINEBOTを作りたい。

イメージとしてはこんな感じ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/566051/7aa13981-bd3c-532f-b175-8decc8b9d44b.png)


自然言語解析とか、DeepLearningとか、RNNとか、雑談BOTとか、そういった高度な話ではありません。

##実現方法

ユーザーIDをkey、保存すべき値を集めたクラスをvalueにしたmapを作成することにしました。

その他、メッセージに応答する箇所の実装は[sample-spring-boot-kitchensink](https://github.com/line/line-bot-sdk-java/tree/master/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");
			}
		}
	}

```
##結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/566051/f93e8a07-b464-3c86-3860-8f7a05db1876.png)