Skip to content

Commit 6ca80bb

Browse files
authored
feat(in-app): Adds support active period for in-app messages. (#173)
* feat(in-app): Adds support active period for in-app messages.
1 parent 70209fa commit 6ca80bb

File tree

6 files changed

+403
-1
lines changed

6 files changed

+403
-1
lines changed

AndroidSDKCore/src/main/java/com/leanplum/internal/ActionManager.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import com.leanplum.callbacks.ActionCallback;
3232
import com.leanplum.utils.SharedPreferencesUtil;
3333

34+
import java.util.Date;
3435
import java.util.HashMap;
3536
import java.util.List;
3637
import java.util.Map;
@@ -60,6 +61,7 @@ public static class MessageMatchResult {
6061
public boolean matchedTrigger;
6162
public boolean matchedUnlessTrigger;
6263
public boolean matchedLimit;
64+
public boolean matchedActivePeriod;
6365
}
6466

6567
public static synchronized ActionManager getInstance() {
@@ -264,6 +266,18 @@ public MessageMatchResult shouldShowMessage(String messageId, Map<String, Object
264266
limitConfig = CollectionUtil.uncheckedCast(limitConfigObj);
265267
}
266268
result.matchedLimit = matchesLimits(messageId, limitConfig);
269+
270+
// 4. Must be within active period.
271+
Object messageStartTime = messageConfig.get("startTime");
272+
Object messageEndTime = messageConfig.get("endTime");
273+
if (messageStartTime == null || messageEndTime == null) {
274+
result.matchedActivePeriod = true;
275+
} else {
276+
long currentTime = new Date().getTime();
277+
result.matchedActivePeriod = currentTime >= (long) messageStartTime &&
278+
currentTime <= (long) messageEndTime;
279+
}
280+
267281
return result;
268282
}
269283

AndroidSDKCore/src/main/java/com/leanplum/internal/LeanplumInternal.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ static void maybePerformActions(String[] whenConditions, String eventName, int f
183183
result.matchedTrigger |= conditionResult.matchedTrigger;
184184
result.matchedUnlessTrigger |= conditionResult.matchedUnlessTrigger;
185185
result.matchedLimit |= conditionResult.matchedLimit;
186+
result.matchedActivePeriod |= conditionResult.matchedActivePeriod;
186187
}
187188

188189
// Make sure we cancel before matching in case the criteria overlap.
@@ -205,6 +206,11 @@ public void variablesChanged() {
205206
});
206207
}
207208

209+
// Make sure message is within the active period.
210+
if(!result.matchedActivePeriod){
211+
continue;
212+
}
213+
208214
if (result.matchedTrigger) {
209215
ActionManager.getInstance().recordMessageTrigger(internalMessageId);
210216

AndroidSDKTests/src/test/java/com/leanplum/LeanplumInAppMessageTriggerTest.java

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
*/
4141
public class LeanplumInAppMessageTriggerTest extends AbstractTest {
4242
/**
43-
* Tests message triggers on start and impression is recorded.
43+
* Tests message triggers on start and impression is recorded. No active period provided.
4444
*/
4545
@Test
4646
public void testTriggerOnStart() {
@@ -55,6 +55,40 @@ public void testTriggerOnStart() {
5555
assertFalse(actionManager.getMessageImpressionOccurrences(messageId).isEmpty());
5656
}
5757

58+
59+
/**
60+
* Tests message triggers on start and impression is recorded. Message within active period.
61+
*/
62+
@Test
63+
public void testTriggerOnStartInActivePeriod() {
64+
final String messageId = "Trigger on start";
65+
ActionManager actionManager = ActionManager.getInstance();
66+
assertEquals(0, actionManager.getMessageTriggerOccurrences(messageId));
67+
assertTrue(actionManager.getMessageImpressionOccurrences(messageId).isEmpty());
68+
69+
setupSDK(mContext, "/responses/start_message_response_in_active_period.json");
70+
// Assert the trigger and message impression occurred.
71+
assertEquals(1, actionManager.getMessageTriggerOccurrences(messageId));
72+
assertFalse(actionManager.getMessageImpressionOccurrences(messageId).isEmpty());
73+
}
74+
75+
76+
/**
77+
* Tests outdated message does not trigger on start.
78+
*/
79+
@Test
80+
public void testTriggerOnStartOutActivePeriod() {
81+
final String messageId = "Trigger on start";
82+
ActionManager actionManager = ActionManager.getInstance();
83+
assertEquals(0, actionManager.getMessageTriggerOccurrences(messageId));
84+
assertTrue(actionManager.getMessageImpressionOccurrences(messageId).isEmpty());
85+
86+
setupSDK(mContext, "/responses/start_message_response_out_active_period.json");
87+
// Assert the trigger and message impression occurred.
88+
assertEquals(0, actionManager.getMessageTriggerOccurrences(messageId));
89+
assertTrue(actionManager.getMessageImpressionOccurrences(messageId).isEmpty());
90+
}
91+
5892
/**
5993
* Tests message triggers on start or resume, and impression is recorded. Starts in background.
6094
*/

AndroidSDKTests/src/test/java/com/leanplum/_whitebox/InAppMessagePrioritizationTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,9 @@ public void before() throws Exception {
6868
mMessageMatchResult = new ActionManager.MessageMatchResult();
6969
Whitebox.setInternalState(mMessageMatchResult, "matchedTrigger", true);
7070
Whitebox.setInternalState(mMessageMatchResult, "matchedLimit", true);
71+
Whitebox.setInternalState(mMessageMatchResult, "matchedActivePeriod", true);
7172
assertTrue(mMessageMatchResult.matchedTrigger);
73+
assertTrue(mMessageMatchResult.matchedActivePeriod);
7274
assertTrue(mMessageMatchResult.matchedLimit);
7375

7476

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
{
2+
"response": [
3+
{
4+
"actionDefinitions": {
5+
"Alert": {
6+
"values": {
7+
"Dismiss action": {
8+
"__name__": ""
9+
},
10+
"Message": "Alert message goes here.",
11+
"Dismiss text": "OK",
12+
"Title": "LeanplumSample"
13+
},
14+
"kinds": {
15+
"Dismiss action": "ACTION",
16+
"Message": "TEXT",
17+
"Dismiss text": "TEXT",
18+
"Title": "TEXT"
19+
},
20+
"kind": 3,
21+
"options": null
22+
}
23+
},
24+
"isRegistered": false,
25+
"regions": {
26+
},
27+
"messages": {
28+
"Trigger on start": {
29+
"countdown": 86400,
30+
"action": "Alert",
31+
"whenTriggers": {
32+
"children": [
33+
{
34+
"subject": "start",
35+
"objects": [],
36+
"verb": ""
37+
}
38+
],
39+
"verb": "OR"
40+
},
41+
"parentCampaignId": null,
42+
"vars": {
43+
"Dismiss action": {
44+
"__name__": ""
45+
},
46+
"Message": "Alert message goes here.",
47+
"__name__": "Alert",
48+
"Title": "Push",
49+
"Dismiss text": "OK"
50+
},
51+
"hasImpressionCriteria": false,
52+
"priority": 1000,
53+
"whenLimits": {
54+
"children": [
55+
{
56+
"subject": "times",
57+
"objects": [],
58+
"verb": "limitUser",
59+
"noun": 1
60+
}
61+
],
62+
"verb": "AND"
63+
},
64+
"startTime":1524507600000,
65+
"endTime":7836202020000
66+
},
67+
"Trigger on advance": {
68+
"countdown": 86400,
69+
"action": "Alert",
70+
"whenTriggers": {
71+
"children": [
72+
{
73+
"subject": "state",
74+
"objects": [],
75+
"verb": "triggers",
76+
"noun": "Registered"
77+
}
78+
],
79+
"verb": "OR"
80+
},
81+
"parentCampaignId": null,
82+
"vars": {
83+
"Dismiss action": {
84+
"__name__": ""
85+
},
86+
"Message": "Alert message goes here.",
87+
"__name__": "Alert",
88+
"Title": "LeanplumSample",
89+
"Dismiss text": "OK"
90+
},
91+
"hasImpressionCriteria": false,
92+
"priority": 1000,
93+
"whenLimits": {
94+
"children": [],
95+
"subject": null,
96+
"objects": []
97+
}
98+
},
99+
"Trigger on Attribute changes": {
100+
"countdown": 86400,
101+
"action": "Alert",
102+
"whenTriggers": {
103+
"children": [
104+
{
105+
"subject": "userAttribute",
106+
"objects": [],
107+
"verb": "changes",
108+
"noun": "Nickname"
109+
}
110+
],
111+
"verb": "OR"
112+
},
113+
"parentCampaignId": null,
114+
"vars": {
115+
"Dismiss action": {
116+
"__name__": ""
117+
},
118+
"Message": "Alert message goes here.",
119+
"__name__": "Alert",
120+
"Title": "LeanplumSample",
121+
"Dismiss text": "OK"
122+
},
123+
"hasImpressionCriteria": false,
124+
"priority": 1000,
125+
"whenLimits": {
126+
"children": [],
127+
"subject": null,
128+
"objects": []
129+
}
130+
}
131+
},
132+
"varsFromCode": {
133+
"emptyDictionary": {
134+
"integerValue": 50
135+
},
136+
"dictionaryVariable": {
137+
"unicode": "?.!s\u0153\u2211\u03c0\u00f8\u02c6\u02dc\u00a8&\/\/.sd",
138+
"test_number": 535,
139+
"test_string": "string"
140+
},
141+
"arrayVariable": {
142+
"[0]": 1,
143+
"[2]": 3,
144+
"[1]": 2,
145+
"[3]": 4,
146+
"[4]": 5
147+
},
148+
"intVariable": 100,
149+
"boolVariable": false,
150+
"floatVariable": 5,
151+
"integerVariable": 1,
152+
"fileVariable": "leanplum_watermark.jpg",
153+
"stringVariable": "test_string"
154+
},
155+
"latestVersion": "1.4.0.2",
156+
"vars": {
157+
},
158+
"fileAttributes": {
159+
"PlugIns\/Leanplum-SDK_Tests.xctest\/test.file": {
160+
"_empty_": {
161+
"hash": "754e4eaae3c92be6e5d45c92b385c8fd",
162+
"size": 25
163+
}
164+
}
165+
},
166+
"token": "jRSv9YRFQ9yVPN80JP0quwHmN9rKk0Crm7awgTwZgCs",
167+
"variants": [
168+
],
169+
"syncNewsfeed": false,
170+
"success": true
171+
}
172+
]
173+
}

0 commit comments

Comments
 (0)