Skip to content

Commit 280cdd1

Browse files
committed
Add ListenTask to duga-core
1 parent 07da298 commit 280cdd1

File tree

5 files changed

+243
-20
lines changed

5 files changed

+243
-20
lines changed

duga-core/build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ dependencies {
2020
compile 'org.apache.commons:commons-lang3:3.4'
2121
compile 'org.apache.httpcomponents:httpclient:4.3.5'
2222
compile 'com.gistlabs:mechanize:2.0.0-RC1'
23+
compile 'com.fasterxml.jackson.core:jackson-core:2.7.1'
24+
compile 'com.fasterxml.jackson.core:jackson-databind:2.7.1-1'
2325
}
2426

2527
def getMavenSettingsCredentials() {

duga-core/src/main/java/net/zomis/duga/chat/listen/ChatMessageIncoming.java

Lines changed: 80 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,43 +2,105 @@
22

33
//import org.apache.commons.lang.StringEscapeUtils;
44

5+
import com.fasterxml.jackson.annotation.JsonProperty;
56
import net.zomis.duga.chat.ChatBot;
67
import net.zomis.duga.chat.WebhookParameters;
78

89
public class ChatMessageIncoming {
910

10-
String content;
11-
int event_type;
12-
long message_id;
13-
long room_id;
14-
long time_stamp;
15-
long user_id;
16-
long parent_id;
17-
long id;
18-
String user_name;
19-
int message_stars;
20-
String room_name;
21-
long target_user_id;
22-
boolean show_parent;
11+
@JsonProperty
12+
private String content;
13+
@JsonProperty("event_type")
14+
private int eventType;
15+
@JsonProperty("message_id")
16+
private long messageId;
17+
@JsonProperty("room_id")
18+
private long roomId;
19+
@JsonProperty("time_stamp")
20+
private long timestamp;
21+
@JsonProperty("user_id")
22+
private long userId;
23+
@JsonProperty("parent_id")
24+
private long parentId;
25+
@JsonProperty("id")
26+
private long id;
27+
@JsonProperty("user_name")
28+
private String userName;
29+
@JsonProperty("message_stars")
30+
private int messageStars;
31+
@JsonProperty("room_name")
32+
private String roomName;
33+
@JsonProperty("target_user_id")
34+
private long targetUserId;
35+
@JsonProperty("show_parent")
36+
private boolean showParent;
2337

2438
ChatBot bot;
2539
WebhookParameters params;
2640

27-
void reply(String message) {
28-
bot.postSingle(params, ":" + message_id + " " + message);
41+
public void reply(String message) {
42+
bot.postSingle(params, ":" + messageId + " " + message);
2943
}
3044

31-
void post(String message) {
45+
public void post(String message) {
3246
bot.postSingle(params, message);
3347
}
3448

35-
void ping(String message) {
49+
public void ping(String message) {
3650
bot.postSingle(params, "@$user_name $message");
3751
}
3852

3953
@Override
4054
public String toString() {
41-
return "Room $room_id: $user_name ($user_id) said $content";
55+
return String.format("Room %s: %s (%d) said %s", roomId, userName, userId, content);
56+
}
57+
58+
public int getEventType() {
59+
return eventType;
60+
}
61+
62+
public int getMessageStars() {
63+
return messageStars;
64+
}
65+
66+
public long getId() {
67+
return id;
68+
}
69+
70+
public long getMessageId() {
71+
return messageId;
72+
}
73+
74+
public long getParentId() {
75+
return parentId;
76+
}
77+
78+
public long getRoomId() {
79+
return roomId;
80+
}
81+
82+
public long getTargetUserId() {
83+
return targetUserId;
84+
}
85+
86+
public long getTimestamp() {
87+
return timestamp;
88+
}
89+
90+
public long getUserId() {
91+
return userId;
92+
}
93+
94+
public String getContent() {
95+
return content;
96+
}
97+
98+
public String getRoomName() {
99+
return roomName;
100+
}
101+
102+
public String getUserName() {
103+
return userName;
42104
}
43105

44106
// public void cleanHTML() {
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package net.zomis.duga.chat.listen;
2+
3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
5+
import java.util.List;
6+
7+
public class ListenRoot {
8+
9+
@JsonProperty
10+
private int ms;
11+
@JsonProperty
12+
private long time;
13+
@JsonProperty
14+
private long sync;
15+
16+
@JsonProperty
17+
private List<ChatMessageIncoming> events;
18+
19+
public int getMs() {
20+
return ms;
21+
}
22+
23+
public List<ChatMessageIncoming> getEvents() {
24+
return events;
25+
}
26+
27+
public long getSync() {
28+
return sync;
29+
}
30+
31+
public long getTime() {
32+
return time;
33+
}
34+
35+
}
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
package net.zomis.duga.chat.listen;
2+
3+
import com.fasterxml.jackson.databind.ObjectMapper;
4+
import com.gistlabs.mechanize.Resource;
5+
import com.gistlabs.mechanize.document.json.JsonDocument;
6+
import com.gistlabs.mechanize.document.json.node.JsonNode;
7+
import com.gistlabs.mechanize.impl.MechanizeAgent;
8+
import net.zomis.duga.chat.StackExchangeChatBot;
9+
import net.zomis.duga.chat.WebhookParameters;
10+
11+
import java.io.IOException;
12+
import java.io.UnsupportedEncodingException;
13+
import java.util.HashMap;
14+
import java.util.List;
15+
import java.util.Map;
16+
import java.util.function.Consumer;
17+
18+
public class ListenTask implements Runnable {
19+
20+
private static final int NUM_MESSAGES = 10;
21+
22+
private final StackExchangeChatBot bot;
23+
private final String room;
24+
private final WebhookParameters params;
25+
private long lastHandledId;
26+
private long lastMessageTime;
27+
private MechanizeAgent agent;
28+
private final Consumer<ChatMessageIncoming> handler;
29+
30+
public ListenTask(StackExchangeChatBot bot, String room, Consumer<ChatMessageIncoming> handler) {
31+
this.bot = bot;
32+
this.room = room;
33+
this.params = WebhookParameters.toRoom(room);
34+
this.agent = new MechanizeAgent();
35+
this.handler = handler;
36+
}
37+
38+
synchronized void latestMessages() {
39+
Map<String, String> parameters = new HashMap<>();
40+
String fkey = bot.getFKey();
41+
if (fkey == null) {
42+
return;
43+
}
44+
parameters.put("fkey", fkey);
45+
parameters.put("mode", "messages");
46+
parameters.put("msgCount", String.valueOf(NUM_MESSAGES));
47+
Resource response;
48+
try {
49+
response = agent.post("http://chat.stackexchange.com/chats/" + room + "/events", parameters);
50+
} catch (UnsupportedEncodingException e) {
51+
throw new IllegalStateException(e);
52+
}
53+
54+
if (!(response instanceof JsonDocument)) {
55+
System.out.println("Unexpected response: " + response);
56+
return;
57+
}
58+
59+
System.out.println("Checking for events in room " + room);
60+
JsonDocument jsonDocument = (JsonDocument) response;
61+
JsonNode node = jsonDocument.getRoot();
62+
63+
ObjectMapper mapper = new ObjectMapper();
64+
ListenRoot root;
65+
try {
66+
root = mapper.readValue(node.toString(), ListenRoot.class);
67+
} catch (IOException e) {
68+
throw new RuntimeException(e);
69+
}
70+
71+
List<ChatMessageIncoming> events = root.getEvents();
72+
long previousId = lastHandledId;
73+
for (ChatMessageIncoming message : events) {
74+
message.bot = bot;
75+
message.params = params;
76+
if (message.getMessageId() <= lastHandledId) {
77+
continue;
78+
}
79+
lastHandledId = Math.max(lastHandledId, message.getMessageId());
80+
lastMessageTime = Math.max(lastMessageTime, message.getTimestamp());
81+
if (previousId <= 0) {
82+
System.out.println("Previous id 0, skipping " + message.getContent());
83+
continue;
84+
}
85+
86+
handler.accept(message);
87+
}
88+
if (previousId <= 0) {
89+
bot.postSingle(params, "Monking! (Duga is now listening for commands)");
90+
}
91+
/* Root node: {"ms":4,"time":41194973,"sync":1433551091,"events":
92+
[{"room_id":16134,"event_type":1,"time_stamp":1433547911,"user_id":125580,"user_name":"Duga","message_id":22039309,"content":"Loki Astari vs. Simon Andr&#233; Forsberg: 4383 diff. Year: -1368. Quarter: -69. Month: -5. Week: +60. Day: -25."}
93+
,{"room_id":16134,"event_type":1,"time_stamp":1433548817,"user_id":125580,"user_name":"Duga","message_id":22039366,"content":"<b><i>RELOAD!<\/i><\/b>"}
94+
,{"room_id":16134,"event_type":1,"time_stamp":1433548849,"user_id":125580,"user_name":"Duga","message_id":22039371,"content":"&#91;<a href=\"https://github.com/retailcoder/Rubberduck\" rel=\"nofollow\"><b>retailcoder/Rubberduck<\/b><\/a>&#93; 12 commits. 2 closed issues. 5 issue comments."}
95+
,{"room_id":16134,"event_type":1,"time_stamp":1433551821,"user_id":98071,"user_name":"Simon André Forsberg","parent_id":22039371,"show_parent":true,"message_id":22039768,"content":"@Duga No open issues today?"}]}
96+
97+
Success: {"id":22039802,"time":1433552063}
98+
*/
99+
}
100+
101+
@Override
102+
public void run() {
103+
try {
104+
latestMessages();
105+
} catch (RuntimeException ex) {
106+
ex.printStackTrace();
107+
}
108+
}
109+
}

duga-core/src/test/java/net/zomis/duga/DugaTest.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,21 @@
66
import net.zomis.duga.chat.WebhookParameters;
77
import net.zomis.duga.chat.events.DugaStartedEvent;
88
import net.zomis.duga.chat.events.DugaStopEvent;
9+
import net.zomis.duga.chat.listen.ChatMessageIncoming;
10+
import net.zomis.duga.chat.listen.ListenTask;
911

1012
import java.io.FileReader;
1113
import java.io.IOException;
1214
import java.util.Properties;
1315
import java.util.Scanner;
16+
import java.util.concurrent.Executors;
17+
import java.util.concurrent.ScheduledExecutorService;
18+
import java.util.concurrent.TimeUnit;
1419

1520
public class DugaTest {
1621

17-
private static final WebhookParameters room = WebhookParameters.toRoom("16134");
22+
private static final WebhookParameters room = WebhookParameters.toRoom("20298");
23+
static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
1824

1925
public static void main(String[] args) {
2026

@@ -37,13 +43,21 @@ public static void main(String[] args) {
3743
config.setChatThrottle(10000);
3844
config.setChatMaxBurst(2);
3945
config.setChatMinimumDelay(500);
40-
ChatBot bot = new StackExchangeChatBot(config);
46+
StackExchangeChatBot bot = new StackExchangeChatBot(config);
4147
bot.registerListener(DugaStartedEvent.class,
4248
e -> new Thread(() -> interactive(e)).start());
4349
bot.registerListener(DugaStopEvent.class, DugaTest::shutdown);
4450
System.out.println("Starting bot...");
4551
bot.start();
4652
System.out.println("Bot started.");
53+
scheduler.scheduleAtFixedRate(new ListenTask(bot, "20298", DugaTest::handle), 0, 3000, TimeUnit.MILLISECONDS);
54+
}
55+
56+
private static void handle(ChatMessageIncoming chatMessageIncoming) {
57+
System.out.println(chatMessageIncoming);
58+
if (chatMessageIncoming.getContent().equals("Monking!")) {
59+
chatMessageIncoming.reply("Monking!");
60+
}
4761
}
4862

4963
private static void shutdown(DugaStopEvent event) {
@@ -65,6 +79,7 @@ private static void interactive(DugaStartedEvent event) {
6579
}
6680
bot.stop();
6781
scanner.close();
82+
scheduler.shutdownNow();
6883
}
6984

7085
}

0 commit comments

Comments
 (0)