ucf_messages 0.0.0 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3b4b645825ac3205350f97d15fabafe8551cc69d97d5dfd86c331a422495e06b
4
- data.tar.gz: 6355dc527edbbb98b69288c2a6f217bd3044b4da9878072a9722532a688f7ed5
3
+ metadata.gz: 962901768f374b0c0f9ed8ad05d79aeb3f42c8a6005b59142171b6d55b3f729b
4
+ data.tar.gz: fb978e752328c7501262a7017498edc0a5c71c19db890f682747f7770954d1c2
5
5
  SHA512:
6
- metadata.gz: 6347432278fb1a5c2ce000f3aa03e157e07c2a817cc7b332a51ecb9450099f5c5f9077aeb8d4a5a5cafd4bed2f64176489507b42386a8dedfdc7fd932f72960f
7
- data.tar.gz: 9c94a7f8ecf744bfd0fff702be373c7f75e8b1dd461cd4bd3c116fc078aaafaf67d6bca19549c9b9331221f049329792b982b61f41b8ceaab0fa16f36cd25c9a
6
+ metadata.gz: d08375c4a13a07c15de68a83c1576ab8136851190a0b8bae13ad4c34a8ded36b37fd7f390408825847487bd1616030d52246405b0db884e95a818fb79ea589a4
7
+ data.tar.gz: 398220faebec9a410f91a044afbba9f7d69a1eb4b6f87952451b9c5891cc3863b18668fffb8996ebea7b91e065b1ad936a16a0782f95c6979126d455ec0913ca
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Enumerable
4
+ def many?
5
+ cnt = 0
6
+ if block_given?
7
+ any? do |element|
8
+ cnt += 1 if yield element
9
+ cnt > 1
10
+ end
11
+ else
12
+ any? { (cnt += 1) > 1 }
13
+ end
14
+ end
15
+
16
+ def pluck(*keys)
17
+ if keys.many?
18
+ map { |element| keys.map { |key| element[key] } }
19
+ else
20
+ key = keys.first
21
+ map { |element| element[key] }
22
+ end
23
+ end
24
+ end
25
+
26
+ class Array
27
+ def second
28
+ self[1]
29
+ end
30
+ end
data/lib/ucf_messages.rb CHANGED
@@ -1,5 +1,284 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'activesupport_extensions'
4
+
1
5
  class UcfMessages
2
- def self.hi
3
- puts 'Hello world!'
6
+ MAX_REWARD_THRESHOLD = 5000
7
+
8
+ class << self
9
+ def message(response)
10
+ @protocol = response.protocol_subscription.protocol
11
+ @protocol_completion = response.protocol_subscription.protocol_completion
12
+ @curidx = current_index
13
+ pooled_message
14
+ end
15
+
16
+ private
17
+
18
+ # There are two rewards: the first one is the multiplication factor for regular responses.
19
+ # The second one is the multiplication factor for the streak responses, of which the threshold
20
+ # property determines the start of the streak.
21
+ def streak_size
22
+ @protocol&.rewards&.second&.threshold || 3
23
+ end
24
+
25
+ # rubocop:disable Metrics/PerceivedComplexity
26
+ def pooled_message
27
+ sms_pool = []
28
+
29
+ # Is this the first invitation? (= are we sending an invite for the first response in the prot sub?)
30
+ sms_pool += first_invitation_pool if first_invitation?
31
+ sms_pool += missed_previous_response if missed_previous_response? && sms_pool.empty?
32
+ sms_pool += rejoined_after_missing_some if rejoined_after_missing_some? && sms_pool.empty?
33
+ sms_pool += threshold_conditions if sms_pool.empty?
34
+ sms_pool += streak_conditions if sms_pool.empty?
35
+ sms_pool += default_pool if sms_pool.empty?
36
+
37
+ # Sample returns a random entry from the array
38
+ sms_pool.sample
39
+ end
40
+ # rubocop:enable Metrics/PerceivedComplexity
41
+
42
+ def threshold_conditions
43
+ current_protocol_completion = truncated_protocol_completion
44
+ rewards_before = @protocol.calculate_reward(current_protocol_completion, false)
45
+ rewards_after = @protocol.calculate_reward(current_protocol_completion, true)
46
+
47
+ sms_pool = []
48
+ 1000.step(MAX_REWARD_THRESHOLD, 1000) do |threshold|
49
+ # 1000 = 10 euro
50
+ # override the current sms_pool so we only get the message for the highest threshold reached
51
+ sms_pool = rewards_threshold_pool(threshold) if rewards_before < threshold && rewards_after >= threshold
52
+ end
53
+ sms_pool
54
+ end
55
+
56
+ # rubocop:disable Metrics/MethodLength
57
+ def rewards_threshold_pool(threshold)
58
+ case threshold
59
+ when 1000 # 10 euro
60
+ [
61
+ 'Whoop! Na deze vragenlijst heb je al €10 euro verdiend. Ga zo door!'
62
+ ]
63
+ when 2000 # 20 euro
64
+ [
65
+ 'Je gaat hard! Na deze vragenlijst heb je al €20 euro gespaard.'
66
+ ]
67
+ when 3000 # 30 euro
68
+ [
69
+ 'De teller blijft lopen! Na deze vragenlijst passeer jij de €30 euro :D'
70
+ ]
71
+ when 4000 # 40 euro
72
+ [
73
+ 'Geweldig, na deze vragenlijst heb je al 40 euro verdiend!'
74
+ ]
75
+ when 5000 # 50 euro
76
+ [
77
+ 'Wat heb jij je ontzettend goed ingezet! Inmiddels heb je al bijna 50 euro verdiend! Vul snel de volgende ' \
78
+ 'vragenlijst in.'
79
+ ]
80
+ else
81
+ []
82
+ end
83
+ end
84
+ # rubocop:enable Metrics/MethodLength
85
+
86
+ def streak_conditions
87
+ sms_pool = []
88
+
89
+ # Streak about to be 3
90
+ sms_pool += about_to_be_on_streak_pool if @protocol_completion[@curidx][:streak] == streak_size
91
+
92
+ # On bonus streak (== on streak > 3)
93
+ sms_pool += on_streak_pool if @protocol_completion[@curidx][:streak] > streak_size && sms_pool.empty?
94
+
95
+ sms_pool
96
+ end
97
+
98
+ def about_to_be_on_streak_pool
99
+ [
100
+ 'Je bent goed bezig {{deze_student}}! Vul deze vragenlijst in en bereik een bonus-streak! Je verdient dan ' \
101
+ 'elke week 50% meer!'
102
+ ]
103
+ end
104
+
105
+ def on_streak_pool
106
+ [
107
+ 'Fijn dat je zo behulpzaam bent, {{deze_student}}! Vul je opnieuw de vragenlijst in?',
108
+ 'Je zit nog steeds in je bonus-streak! Je u-can-feel spaarpotje raakt al behoorlijk vol ;) Vul direct de ' \
109
+ 'vragenlijst in om je bonus-streak te behouden.',
110
+ 'Bedankt voor je inzet! Ga zo door :D Er staat weer een nieuwe vragenlijst voor je klaar.',
111
+ '{{deze_student}}, je bent een topper! Bedankt voor je goede hulp! Vul je direct de vragenlijst weer in?',
112
+ 'Goed bezig met je bonus-streak, ga zo door!',
113
+ 'Super dat je de vragenlijst al zo vaak achter elkaar hebt ingevuld, bedankt en ga zo door!',
114
+ 'Hoi {{deze_student}}! Vul je de vragenlijst weer in om geld te verdienen?'
115
+ ]
116
+ end
117
+
118
+ def first_invitation_pool
119
+ [
120
+ 'Welkom bij het u-can-feel dagboekonderzoek! Doe je ook mee? We vragen je om elke week in een paar ' \
121
+ 'minuten wat vragen te beantwoorden over hoe het met je gaat. Daarmee help je ons met ons onderzoek ' \
122
+ 'én kun je geld verdienen. Via de link kun je meer informatie krijgen en de eerste vragenlijst ' \
123
+ 'invullen.'
124
+ ]
125
+ end
126
+
127
+ def default_pool
128
+ [
129
+ 'Hoi {{deze_student}}! Er staat een vragenlijst voor je klaar, vul je hem weer in? :D',
130
+ 'Een u-can-feel tip: vul drie weken achter elkaar een vragenlijst in en verdien een bonus voor elke ' \
131
+ 'vragenlijst!',
132
+ 'Hoi {{deze_student}}! Vul direct de volgende vragenlijst in. Het kost je maar een paar minuten en je helpt ' \
133
+ 'ons enorm!',
134
+ 'Hallo {{deze_student}}, verdien een euro! Vul nu de vragenlijst in!',
135
+ 'Fijn dat jij meedoet! Vul je de vragenlijst weer in? Door jou kunnen leerlingen met wie het niet zo goed ' \
136
+ 'gaat nog betere begeleiding krijgen in de toekomst!',
137
+ 'Help {{je_school}} nog beter te worden in wat ze doen en vul nu de vragenlijst in!',
138
+ 'Heel fijn dat je meedoet! Vul je de vragenlijst weer in? Hiermee help je {{je_school}} om leerlingen nog ' \
139
+ 'beter te begeleiden!'
140
+ ]
141
+ end
142
+
143
+ def not_everything_missed
144
+ [
145
+ 'Je hebt ons al enorm geholpen met de vragenlijsten die je hebt ingevuld, {{deze_student}}. Wil je ons ' \
146
+ 'weer helpen én daarmee geld verdienen?',
147
+ 'Hoi {{deze_student}}, doe je deze week weer mee aan het u-can-feel onderzoek? Vul de vragenlijst in en ' \
148
+ 'verdien een euro.',
149
+ 'Hoi {{deze_student}}! Vul direct de volgende vragenlijst in. Het kost je maar een paar minuten en je helpt ' \
150
+ 'ons enorm!',
151
+ 'Doe je weer mee aan het u-can-feel onderzoek, {{deze_student}}? Daarmee help je ons enorm én verdien je geld.',
152
+ 'We hebben je al even gemist, {{deze_student}}! Help je deze week weer mee met het u-can-feel onderzoek? Het ' \
153
+ 'kost maar een paar minuten van je tijd. Je helpt ons en je school. En je verdient er zelf ook een euro mee.'
154
+ ]
155
+ end
156
+
157
+ def missed_everything
158
+ [
159
+ 'Je bent nog niet gestart met het u-can-feel dagboekonderzoek, {{deze_student}}! Doe je alsnog mee? We ' \
160
+ 'vragen je om elke week een paar minuten wat vragen te beantwoorden over hoe het met je gaat. Daarmee help ' \
161
+ 'je ons met ons onderzoek én kun je geld verdienen. Via de link kun je meer informatie krijgen en de eerste ' \
162
+ 'vragenlijst invullen.'
163
+ ]
164
+ end
165
+
166
+ def missed_one_after_streak
167
+ [
168
+ 'Je was heel goed bezig met het u-can-feel onderzoek {{deze_student}}. Probeer je opnieuw de bonus-streak ' \
169
+ 'te halen om extra geld te verdienen?'
170
+ ]
171
+ end
172
+
173
+ def missed_one_not_after_streak
174
+ [
175
+ 'We hebben je gemist vorige week. Help je deze week weer mee met het u-can-feel onderzoek? Het kost maar ' \
176
+ 'een paar minuten van je tijd. Je helpt ons en je school. Én je verdient er een euro mee.'
177
+ ]
178
+ end
179
+
180
+ def rejoined_after_missing_one
181
+ [
182
+ 'Na een weekje rust ben je er sinds vorige week weer bij. Heel fijn dat je weer mee doet met het u-can-feel ' \
183
+ 'onderzoek! Daarmee help je ons enorm. Vul je direct de volgende vragenlijst in?'
184
+ ]
185
+ end
186
+
187
+ def rejoined_after_missing_multiple
188
+ [
189
+ 'Sinds vorige week doe je weer mee aan het u-can-feel onderzoek! Super! Vul nog twee vragenlijsten in en je ' \
190
+ 'krijgt een bonus!'
191
+ ]
192
+ end
193
+
194
+ def rejoined_after_missing_some
195
+ sms_pool = []
196
+
197
+ sms_pool += rejoined_after_missing_one if rejoined_after_missing_one?
198
+ sms_pool += rejoined_after_missing_multiple if sms_pool.empty?
199
+
200
+ sms_pool
201
+ end
202
+
203
+ def missed_previous_response
204
+ sms_pool = []
205
+ # [missed] only the last?
206
+ sms_pool += missed_last_only if missed_last_only?
207
+ sms_pool += missed_everything if missed_everything? && sms_pool.empty?
208
+ sms_pool += not_everything_missed if sms_pool.empty?
209
+
210
+ sms_pool
211
+ end
212
+
213
+ def missed_last_only
214
+ sms_pool = []
215
+
216
+ sms_pool += missed_one_after_streak if missed_one_after_streak?
217
+ sms_pool += missed_one_not_after_streak if sms_pool.empty?
218
+
219
+ sms_pool
220
+ end
221
+
222
+ def truncated_protocol_completion
223
+ @protocol_completion[0..@curidx]
224
+ end
225
+
226
+ def current_index
227
+ # -1 in case there are no other measurements
228
+ @protocol_completion.find_index { |entry| entry[:future] } || -1
229
+ end
230
+
231
+ def first_invitation?
232
+ @curidx.zero?
233
+ end
234
+
235
+ def missed_previous_response?
236
+ # Minimal pattern: .C (X = completed, C = current)
237
+ # index: 01
238
+ @curidx.positive? &&
239
+ !@protocol_completion[@curidx - 1][:completed]
240
+ end
241
+
242
+ def missed_last_only?
243
+ # Minimal pattern: X.C (X = completed, C = current)
244
+ # index: 012
245
+ @curidx > 1 &&
246
+ !@protocol_completion[@curidx - 1][:completed] &&
247
+ @protocol_completion[@curidx - 2][:completed]
248
+ end
249
+
250
+ def missed_one_after_streak?
251
+ # Minimal pattern: XXX.C (X = completed, C = current)
252
+ # index: 01234
253
+ @curidx > 2 && # only make sure that we can check the index at curidx-2.
254
+ !@protocol_completion[@curidx - 1][:completed] &&
255
+ @protocol_completion[@curidx - 2][:completed] &&
256
+ @protocol_completion[@curidx - 2][:streak] >= streak_size
257
+ end
258
+
259
+ def missed_everything?
260
+ # Minimal pattern: .C (X = completed, C = current)
261
+ # index: 01
262
+ @curidx.positive? &&
263
+ @protocol_completion[0..(@curidx - 1)].pluck(:completed).none?
264
+ end
265
+
266
+ def rejoined_after_missing_one?
267
+ # Minimal pattern: X.XC (X = completed, C = current)
268
+ # index: 0123
269
+ @curidx > 2 &&
270
+ @protocol_completion[@curidx - 1][:completed] &&
271
+ !@protocol_completion[@curidx - 2][:completed] &&
272
+ @protocol_completion[@curidx - 3][:completed]
273
+ end
274
+
275
+ def rejoined_after_missing_some?
276
+ # Minimal pattern: X.XC (X = completed, C = current)
277
+ # index: 0123
278
+ @curidx > 2 &&
279
+ @protocol_completion[@curidx - 1][:completed] &&
280
+ !@protocol_completion[@curidx - 2][:completed] &&
281
+ @protocol_completion[0..(@curidx - 3)].pluck(:completed).any?
282
+ end
4
283
  end
5
284
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ucf_messages
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ando Emerencia
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-09-20 00:00:00.000000000 Z
11
+ date: 2021-11-29 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: library for determining which invitation text to use
14
14
  email: info@compsy.ch
@@ -16,8 +16,9 @@ executables: []
16
16
  extensions: []
17
17
  extra_rdoc_files: []
18
18
  files:
19
+ - lib/activesupport_extensions.rb
19
20
  - lib/ucf_messages.rb
20
- homepage: https://rubygems.org/gems/ucf_messages
21
+ homepage: https://github.com/compsy/ucf_messages
21
22
  licenses:
22
23
  - MIT
23
24
  metadata: {}
@@ -29,7 +30,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
29
30
  requirements:
30
31
  - - ">="
31
32
  - !ruby/object:Gem::Version
32
- version: '0'
33
+ version: '3.0'
33
34
  required_rubygems_version: !ruby/object:Gem::Requirement
34
35
  requirements:
35
36
  - - ">="