Skip to content

Commit d51d7eb

Browse files
tokuhiromimasahiro
authored andcommitted
Support memberJoin/memberLeft event. Close #313 (#320)
1 parent b9f2161 commit d51d7eb

File tree

7 files changed

+239
-1
lines changed

7 files changed

+239
-1
lines changed

line-bot-model/src/main/java/com/linecorp/bot/model/event/Event.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@
3535
@JsonSubTypes.Type(PostbackEvent.class),
3636
@JsonSubTypes.Type(BeaconEvent.class),
3737
@JsonSubTypes.Type(AccountLinkEvent.class),
38-
@JsonSubTypes.Type(ThingsEvent.class)
38+
@JsonSubTypes.Type(ThingsEvent.class),
39+
@JsonSubTypes.Type(MemberJoinedEvent.class),
40+
@JsonSubTypes.Type(MemberLeftEvent.class)
3941
})
4042
@JsonTypeInfo(
4143
use = JsonTypeInfo.Id.NAME,
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
* Copyright 2019 LINE Corporation
3+
*
4+
* LINE Corporation licenses this file to you under the Apache License,
5+
* version 2.0 (the "License"); you may not use this file except in compliance
6+
* with the License. You may obtain a copy of the License at:
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13+
* License for the specific language governing permissions and limitations
14+
* under the License.
15+
*/
16+
17+
package com.linecorp.bot.model.event;
18+
19+
import java.time.Instant;
20+
import java.util.List;
21+
22+
import com.fasterxml.jackson.annotation.JsonCreator;
23+
import com.fasterxml.jackson.annotation.JsonTypeName;
24+
25+
import com.linecorp.bot.model.event.source.Source;
26+
27+
import lombok.Value;
28+
29+
/**
30+
* Event object for when a user joins a group or room that the bot is in.
31+
*/
32+
@Value
33+
@JsonTypeName("memberJoined")
34+
public class MemberJoinedEvent implements Event, ReplyEvent {
35+
/**
36+
* Token for replying to this event.
37+
*/
38+
private final String replyToken;
39+
40+
/**
41+
* JSON object which contains the source of the event.
42+
*/
43+
private final Source source;
44+
45+
/**
46+
* Time of the event.
47+
*/
48+
private final Instant timestamp;
49+
50+
/**
51+
* User ID of users who joined.
52+
*/
53+
private final JoinedMembers joined;
54+
55+
@JsonCreator
56+
public MemberJoinedEvent(
57+
final String replyToken,
58+
final Source source,
59+
final JoinedMembers joined,
60+
final Instant timestamp) {
61+
this.replyToken = replyToken;
62+
this.source = source;
63+
this.joined = joined;
64+
this.timestamp = timestamp;
65+
}
66+
67+
@Value
68+
public static class JoinedMembers {
69+
// User ID of users who joined
70+
List<Source> members;
71+
72+
@JsonCreator
73+
public JoinedMembers(List<Source> members) {
74+
this.members = members;
75+
}
76+
}
77+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* Copyright 2019 LINE Corporation
3+
*
4+
* LINE Corporation licenses this file to you under the Apache License,
5+
* version 2.0 (the "License"); you may not use this file except in compliance
6+
* with the License. You may obtain a copy of the License at:
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13+
* License for the specific language governing permissions and limitations
14+
* under the License.
15+
*/
16+
17+
package com.linecorp.bot.model.event;
18+
19+
import java.time.Instant;
20+
import java.util.List;
21+
22+
import com.fasterxml.jackson.annotation.JsonCreator;
23+
import com.fasterxml.jackson.annotation.JsonTypeName;
24+
25+
import com.linecorp.bot.model.event.source.Source;
26+
27+
import lombok.Value;
28+
29+
@Value
30+
@JsonTypeName("memberLeft")
31+
public class MemberLeftEvent implements Event {
32+
/**
33+
* JSON object which contains the source of the event.
34+
*/
35+
private final Source source;
36+
37+
/**
38+
* Time of the event.
39+
*/
40+
private final Instant timestamp;
41+
42+
/**
43+
* User ID of users who joined.
44+
*/
45+
private final LeftMembers left;
46+
47+
@JsonCreator
48+
public MemberLeftEvent(
49+
final Source source,
50+
final LeftMembers left,
51+
final Instant timestamp) {
52+
this.source = source;
53+
this.left = left;
54+
this.timestamp = timestamp;
55+
}
56+
57+
@Value
58+
public static class LeftMembers {
59+
// User ID of users who joined
60+
List<Source> members;
61+
62+
@JsonCreator
63+
public LeftMembers(List<Source> members) {
64+
this.members = members;
65+
}
66+
}
67+
}

line-bot-model/src/test/java/com/linecorp/bot/model/event/CallbackRequestTest.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.io.InputStream;
2323
import java.nio.charset.StandardCharsets;
2424
import java.time.Instant;
25+
import java.util.stream.Collectors;
2526

2627
import org.junit.Test;
2728
import org.springframework.util.StreamUtils;
@@ -38,6 +39,7 @@
3839
import com.linecorp.bot.model.event.message.TextMessageContent;
3940
import com.linecorp.bot.model.event.message.UnknownMessageContent;
4041
import com.linecorp.bot.model.event.source.GroupSource;
42+
import com.linecorp.bot.model.event.source.Source;
4143
import com.linecorp.bot.model.event.source.UnknownSource;
4244
import com.linecorp.bot.model.event.source.UserSource;
4345
import com.linecorp.bot.model.event.things.ThingsContent;
@@ -412,6 +414,36 @@ public void testLineThingsUnlink() throws IOException {
412414
});
413415
}
414416

417+
@Test
418+
public void testMemberJoined() throws IOException {
419+
parse("callback/member_joined.json", callbackRequest -> {
420+
assertDestination(callbackRequest);
421+
Event event = callbackRequest.getEvents().get(0);
422+
assertThat(event.getSource()).isInstanceOf(GroupSource.class);
423+
assertThat(event).isInstanceOf(MemberJoinedEvent.class);
424+
MemberJoinedEvent memberJoinedEvent = (MemberJoinedEvent) event;
425+
String uids = memberJoinedEvent.getJoined().getMembers().stream()
426+
.map(Source::getUserId)
427+
.collect(Collectors.joining(","));
428+
assertThat(uids).isEqualTo("U111111");
429+
});
430+
}
431+
432+
@Test
433+
public void testMemberLeft() throws IOException {
434+
parse("callback/member_left.json", callbackRequest -> {
435+
assertDestination(callbackRequest);
436+
Event event = callbackRequest.getEvents().get(0);
437+
assertThat(event.getSource()).isInstanceOf(GroupSource.class);
438+
assertThat(event).isInstanceOf(MemberLeftEvent.class);
439+
MemberLeftEvent memberLeftEvent = (MemberLeftEvent) event;
440+
String uids = memberLeftEvent.getLeft().getMembers().stream()
441+
.map(Source::getUserId)
442+
.collect(Collectors.joining(","));
443+
assertThat(uids).isEqualTo("U111111");
444+
});
445+
}
446+
415447
// Event, that has brand new eventType
416448
@Test
417449
public void testUnknown() throws IOException {
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"events": [
3+
{
4+
"type": "memberJoined",
5+
"replyToken": "REPLYTOKEN12345",
6+
"source": {
7+
"groupId": "C1234567890",
8+
"type": "group"
9+
},
10+
"timestamp": 1553506027708,
11+
"joined": {
12+
"members": [
13+
{
14+
"userId": "U111111",
15+
"type": "user"
16+
}
17+
]
18+
}
19+
}
20+
],
21+
"destination": "Uab012345678901234567890123456789"
22+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"events": [
3+
{
4+
"type": "memberLeft",
5+
"source": {
6+
"groupId": "C1234567890",
7+
"type": "group"
8+
},
9+
"timestamp": 1553506027708,
10+
"left": {
11+
"members": [
12+
{
13+
"userId": "U111111",
14+
"type": "user"
15+
}
16+
]
17+
}
18+
}
19+
],
20+
"destination": "Uab012345678901234567890123456789"
21+
}

sample-spring-boot-kitchensink/src/main/java/com/example/bot/spring/KitchenSinkController.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@
4848
import com.linecorp.bot.model.event.Event;
4949
import com.linecorp.bot.model.event.FollowEvent;
5050
import com.linecorp.bot.model.event.JoinEvent;
51+
import com.linecorp.bot.model.event.MemberJoinedEvent;
52+
import com.linecorp.bot.model.event.MemberLeftEvent;
5153
import com.linecorp.bot.model.event.MessageEvent;
5254
import com.linecorp.bot.model.event.PostbackEvent;
5355
import com.linecorp.bot.model.event.UnfollowEvent;
@@ -227,6 +229,21 @@ public void handleBeaconEvent(BeaconEvent event) {
227229
this.replyText(replyToken, "Got beacon message " + event.getBeacon().getHwid());
228230
}
229231

232+
@EventMapping
233+
public void handleMemberJoined(MemberJoinedEvent event) {
234+
String replyToken = event.getReplyToken();
235+
this.replyText(replyToken, "Got memberJoined message " + event.getJoined().getMembers()
236+
.stream().map(Source::getUserId)
237+
.collect(Collectors.joining(",")));
238+
}
239+
240+
@EventMapping
241+
public void handleMemberLeft(MemberLeftEvent event) {
242+
log.info("Got memberLeft message: {}", event.getLeft().getMembers()
243+
.stream().map(Source::getUserId)
244+
.collect(Collectors.joining(",")));
245+
}
246+
230247
@EventMapping
231248
public void handleOtherEvent(Event event) {
232249
log.info("Received message(Ignored): {}", event);

0 commit comments

Comments
 (0)