Skip to content

Commit

Permalink
Add Candidate Date Picker. fixes #246 @3h
Browse files Browse the repository at this point in the history
  • Loading branch information
みぞ@CrazyBeatCoder committed Dec 24, 2017
1 parent d719488 commit 36f53e2
Show file tree
Hide file tree
Showing 17 changed files with 302 additions and 34 deletions.
104 changes: 82 additions & 22 deletions src/main/java/com/mizo0203/hoshiguma/HoshigumaLineBotServlet.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,18 @@
import com.google.appengine.repackaged.com.google.api.client.util.Base64;
import com.mizo0203.hoshiguma.repo.Repository;
import com.mizo0203.hoshiguma.repo.State;
import com.mizo0203.hoshiguma.repo.line.messaging.data.EventData;
import com.mizo0203.hoshiguma.repo.line.messaging.data.MessageData;
import com.mizo0203.hoshiguma.repo.line.messaging.data.MessageObject;
import com.mizo0203.hoshiguma.repo.line.messaging.data.ReplyMessageData;
import com.mizo0203.hoshiguma.repo.line.messaging.data.WebhooksData;
import com.mizo0203.hoshiguma.repo.line.messaging.data.RequestBody;
import com.mizo0203.hoshiguma.repo.line.messaging.data.TemplateMessageObject;
import com.mizo0203.hoshiguma.repo.line.messaging.data.TextMessageObject;
import com.mizo0203.hoshiguma.repo.line.messaging.data.WebHookEventObject;
import com.mizo0203.hoshiguma.repo.line.messaging.data.action.Action;
import com.mizo0203.hoshiguma.repo.line.messaging.data.action.DateTimePickerAction;
import com.mizo0203.hoshiguma.repo.line.messaging.data.action.DateTimePickerAction.Mode;
import com.mizo0203.hoshiguma.repo.line.messaging.data.action.PostBackAction;
import com.mizo0203.hoshiguma.repo.line.messaging.data.template.ButtonTemplate;
import com.mizo0203.hoshiguma.repo.line.messaging.data.template.Template;
import com.mizo0203.hoshiguma.util.HttpPostUtil;
import com.mizo0203.hoshiguma.util.PaserUtil;
import java.io.IOException;
Expand All @@ -15,6 +23,9 @@
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SignatureException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
Expand Down Expand Up @@ -67,16 +78,19 @@ public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOEx
LOG.log(Level.SEVERE, "", e);
return;
}
WebhooksData webhooks = PaserUtil.parseWebhooksData(line);
for (EventData event : webhooks.events) {
RequestBody webhooks = PaserUtil.parseWebhooksData(line);
for (WebHookEventObject event : webhooks.events) {
LOG.info("replyToken: " + event.replyToken);
switch (event.type) {
case EventData.TYPE_JOIN:
case WebHookEventObject.TYPE_JOIN:
onLineJoin(event);
break;
case EventData.TYPE_MESSAGE:
case WebHookEventObject.TYPE_MESSAGE:
onLineMessage(event);
break;
case WebHookEventObject.TYPE_POST_BACK:
onLinePostBack(event);
break;
default:
break;
}
Expand All @@ -86,50 +100,96 @@ public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOEx
}
}

private void onLineJoin(EventData event) {
private void onLineJoin(WebHookEventObject event) {
mRepository.clearEvent(event.source);
ReplyMessageData replyMessageData = new ReplyMessageData();
replyMessageData.replyToken = event.replyToken;
replyMessageData.messages = new MessageData[1];
replyMessageData.messages[0] = new MessageData();
replyMessageData.messages[0].type = "text";
mRepository.setEventName(event.source, null);
replyMessageData.messages[0].text = "幹事は任せろ!\nイベント名は?";
replyMessageData.messages = new MessageObject[1];
replyMessageData.messages[0] = new TextMessageObject("幹事は任せろ!\nところで何の飲み会だっけ?w");
postLine(PaserUtil.toJson(replyMessageData));
}

private void onLineMessage(final EventData event) {
private void onLineMessage(final WebHookEventObject event) {
LOG.info("text: " + event.message.text);
if (event.message.text == null) {
return;
}
ReplyMessageData replyMessageData = new ReplyMessageData();
replyMessageData.replyToken = event.replyToken;
replyMessageData.messages = new MessageData[1];
replyMessageData.messages[0] = new MessageData();
replyMessageData.messages[0].type = "text";
State state = mRepository.getState(event.source);
switch (state) {
case NO_EVENT_NAME: {
String event_name = event.message.text.split("\n")[0];
mRepository.setEventName(event.source, event_name);
replyMessageData.messages[0].text = event_name + "だな!\n了解!!\n日程はもう決まったのか?"; // TODO:
replyMessageData.messages = new MessageObject[1];
replyMessageData.messages[0] = createMessageData(
"ああ、" + event_name + "だったな!\n早速、日程調整するぞ!!\n候補を教えてくれ!");
// イベント名の修正機能
// 日程調整機能の ON/OFF 切り替え
postLine(PaserUtil.toJson(replyMessageData));
break;
}
case HAS_EVENT_NAME: {
//noinspection unused
String event_name = mRepository.getEventName(event.source);
replyMessageData.messages[0].text = event_name + "の件だな!\n早速、日程調整するぞ!!\n候補を教えてくれ!";
postLine(PaserUtil.toJson(replyMessageData));
// NOP
break;
}
default:
break;
}
}

private void onLinePostBack(WebHookEventObject event) {
ReplyMessageData replyMessageData = new ReplyMessageData();
replyMessageData.replyToken = event.replyToken;
switch (event.postback.data) {
case "data1": {
SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm");
String strDate = event.postback.params.datetime;
try {
Date date = fmt.parse(strDate);
System.out.println(strDate + "をDateオブジェクトへ変換 → " + date);//[2]
mRepository.addCandidateDate(event.source, date);
Date[] candidateDates = mRepository.getCandidateDates(event.source);
SimpleDateFormat format2 = new SimpleDateFormat("MM/dd(E) HH:mm -");
StringBuilder text = new StringBuilder("↓候補日時一覧だ!↓");
for (Date candidateDate : candidateDates) {
text.append("\n").append(format2.format(candidateDate));
}
replyMessageData.messages = new MessageObject[1];
replyMessageData.messages[0] = new TextMessageObject(text.toString());
postLine(PaserUtil.toJson(replyMessageData));
} catch (ParseException e) {
e.printStackTrace();
}
break;
}
case "data2": {
replyMessageData.messages = new MessageObject[1];
replyMessageData.messages[0] = new TextMessageObject("了解だ!");
postLine(PaserUtil.toJson(replyMessageData));
break;
}
case "data3": {
mRepository.clearCandidateDate(event.source);
replyMessageData.messages = new MessageObject[1];
replyMessageData.messages[0] = createMessageData("候補をクリアしたぞ!\n改めて候補を教えてくれ!");
postLine(PaserUtil.toJson(replyMessageData));
break;
}
}
}

private MessageObject createMessageData(String text) {
Action[] actions = new Action[3];
actions[0] = new DateTimePickerAction("data1", Mode.DATE_TIME).label("候補日時を追加(最大10)");
actions[1] = new PostBackAction("data2").label("候補日時の追加を完了");
actions[2] = new PostBackAction("data3").label("候補日時の追加をクリア");
Template template = new ButtonTemplate(text,
actions);
return new TemplateMessageObject(
"テンプレートメッセージはiOS版およびAndroid版のLINE 6.7.0以降で対応しています。", template);
}

private void verifySignature(String channelSecret, String httpRequestBody, String expectSignature)
throws NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException, SignatureException {
SecretKeySpec key = new SecretKeySpec(channelSecret.getBytes(), "HmacSHA256");
Expand Down
45 changes: 45 additions & 0 deletions src/main/java/com/mizo0203/hoshiguma/repo/Repository.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
import com.mizo0203.hoshiguma.repo.line.messaging.data.SourceData;
import com.mizo0203.hoshiguma.repo.objectify.entity.KeyEntity;
import com.mizo0203.hoshiguma.repo.objectify.entity.LineTalkRoomConfig;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.logging.Logger;

public class Repository {
Expand Down Expand Up @@ -44,6 +48,47 @@ public String getEventName(SourceData source) {
return config.event_name;
}

public void addCandidateDate(SourceData source, Date candidateDate) {
LineTalkRoomConfig config = getOrCreateLineTalkRoomConfig(source);
if (config == null) {
return;
}
if (config.candidate_dates == null) {
config.candidate_dates = new Date[0];
}
List<Date> candidateDateList = new ArrayList<>(Arrays.asList(config.candidate_dates));
candidateDateList.add(candidateDate);
config.candidate_dates = candidateDateList.toArray(new Date[candidateDateList.size()]);
mOfyRepository.saveLineTalkRoomConfig(config);
}

public Date[] getCandidateDates(SourceData source) {
LineTalkRoomConfig config = getOrCreateLineTalkRoomConfig(source);
if (config == null) {
return null;
}
return config.candidate_dates;
}

public void clearCandidateDate(SourceData source) {
LineTalkRoomConfig config = getOrCreateLineTalkRoomConfig(source);
if (config == null) {
return;
}
config.candidate_dates = null;
mOfyRepository.saveLineTalkRoomConfig(config);
}

public void clearEvent(SourceData source) {
LineTalkRoomConfig config = getOrCreateLineTalkRoomConfig(source);
if (config == null) {
return;
}
config.event_name = null;
config.candidate_dates = null;
mOfyRepository.saveLineTalkRoomConfig(config);
}

private LineTalkRoomConfig getOrCreateLineTalkRoomConfig(SourceData source) {
String key = createLineTalkRoomConfigKey(source);
if (key == null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.mizo0203.hoshiguma.repo.line.messaging.data;

@SuppressWarnings({"unused", "WeakerAccess"})
public abstract class MessageObject {

public final String type;

public MessageObject(String type) {
this.type = type;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.mizo0203.hoshiguma.repo.line.messaging.data;

public class PostBack {

public String data;
public Params params;

public static class Params {

public String date;
public String time;
public String datetime;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@
public class ReplyMessageData {

public String replyToken;
public MessageData[] messages;
public MessageObject[] messages;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@

import java.util.Arrays;

/**
* リクエストボディ
*/
@SuppressWarnings({"unused", "WeakerAccess"})
public class WebhooksData {
public class RequestBody {

public EventData[] events;
public WebHookEventObject[] events;

@Override
public String toString() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.mizo0203.hoshiguma.repo.line.messaging.data;

import com.mizo0203.hoshiguma.repo.line.messaging.data.template.Template;

@SuppressWarnings({"unused", "WeakerAccess"})
public class TemplateMessageObject extends MessageObject {

public final String altText;
public final Template template;

public TemplateMessageObject(String altText, Template template) {
super("template");
this.altText = altText;
this.template = template;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.mizo0203.hoshiguma.repo.line.messaging.data;

@SuppressWarnings({"unused", "WeakerAccess"})
public class TextMessageObject extends MessageObject {

public final String text;

public TextMessageObject(String text) {
super("text");
this.text = text;
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package com.mizo0203.hoshiguma.repo.line.messaging.data;

@SuppressWarnings({"unused", "WeakerAccess"})
public class EventData {
@SuppressWarnings({"unused", "WeakerAccess", "SpellCheckingInspection"})
public class WebHookEventObject {

public static final String TYPE_JOIN = "join";
public static final String TYPE_MESSAGE = "message";
public static final String TYPE_POST_BACK = "postback";
public String replyToken;
public String type;
public long timestamp;
public SourceData source;
public MessageData message;
public PostBack postback;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.mizo0203.hoshiguma.repo.line.messaging.data.action;

public abstract class Action {

public final String type;

public Action(String type) {
this.type = type;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.mizo0203.hoshiguma.repo.line.messaging.data.action;

@SuppressWarnings({"unused", "WeakerAccess"})
public class DateTimePickerAction extends Action {

public String label;
public String data;
public String mode;
public String initial;
public String max;
public String min;

public DateTimePickerAction(String data, Mode mode) {
super("datetimepicker");
this.data = data;
this.mode = mode.toString();
}

public DateTimePickerAction label(String label) {
this.label = label;
return this;
}

public enum Mode {
DATE,
TIME,
DATE_TIME,;

@Override
public String toString() {
switch (this) {
case DATE:
return "date";
case TIME:
return "time";
case DATE_TIME:
return "datetime";
default:
throw new IllegalStateException(super.toString());
}
}
}
}
Loading

0 comments on commit 36f53e2

Please sign in to comment.