-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Filter push messages #25
Merged
Merged
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
02e591f
Prep for push messaging
e8f0d01
Add signup and send_next_message flows. TODO: Tests
cd789bc
Add send next message test
ef374ea
Fix tests for new Flow Tester
61f622b
FT v 0.3.6 dummy
d857b77
Add tests for filtering by contact fields
f45515f
Format code
7438bf5
Merge branch 'main' into filter-push-messages
HawkiesZA File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
```stack | ||
# One trigger for each message that needs to be sent in OCS | ||
|
||
trigger(interval: "+5m", relative_to: "contact.push_messaging_signup") | ||
trigger(interval: "+10m", relative_to: "contact.push_messaging_signup") | ||
|
||
``` | ||
|
||
This stack fetches the message to be sent based on the difference between the current time and the signup time. | ||
|
||
It handles the following message types: | ||
|
||
* Template messages. Assumes template message with two variables. Sets the first to the contact's whatsapp profile name, and the second to the literal "Second" | ||
* Text messages. Sends the title, followed by the body, of the whatsapp message, in a single message to the user. | ||
|
||
It then increments the content set position on the contact, and runs the stack that handles scheduling the next message in the message set. | ||
|
||
## Configuration | ||
|
||
This Journey requires the `config.contentrepo_token` global variable to be set. | ||
|
||
This Journey also requires configuration for "gender", "age", and/or "relationship" which is used to fetch the correct Ordered Content Set. | ||
|
||
## Contact fields | ||
|
||
* push_messaging_signup, the time the user signed up for these messages. The name of this contact field should be changed according to the implementation, otherwise all the push messages will overwrite each other's scheduled times. | ||
* whatsapp_profile_name, used to personalise the template sent to the user | ||
|
||
## Flow results | ||
|
||
* template_sent, which message template was sent | ||
* message_sent, the message sent to the user | ||
|
||
## Connections to other stacks | ||
|
||
This Journey does not link to any other Journeys | ||
|
||
## Determine message | ||
|
||
This block figures out which message to send to the user based on the difference between the current time, and when the user signed up plus the trigger time. This way if we update CMS with a new message then the correct sequence is still followed for users partway through. | ||
|
||
```stack | ||
card DetermineMessage | ||
when now() >= datetime_add(contact.push_messaging_signup, 5, "m") and | ||
now() < datetime_add(contact.push_messaging_signup, 10, "m"), | ||
then: CalculateAge do | ||
# send first message | ||
push_messaging_content_set_position = 0 | ||
end | ||
|
||
# Add your other conditions here | ||
|
||
card DetermineMessage, then: CalculateAge do | ||
# send second message | ||
push_messaging_content_set_position = 1 | ||
end | ||
|
||
``` | ||
|
||
## Calculate Age & Determine Age Range | ||
|
||
CMS uses age ranges, so in order to filter by age, we need get the age either from the `age` contact field or calculate it from the `year_of_birth` contact field, and then determine which age range it falls into. | ||
|
||
```stack | ||
card CalculateAge, then: DetermineAgeRange do | ||
# age = | ||
# if is_nil_or_empty(contact.age) do | ||
# year(now()) - contact.year_of_birth | ||
# else | ||
# contact.age | ||
# end | ||
# we don't currently have an age contact field and it seems silly to have to create it for | ||
# this journey | ||
age = | ||
if is_nil_or_empty(contact.year_of_birth) do | ||
0 | ||
else | ||
year(now()) - contact.year_of_birth | ||
end | ||
end | ||
|
||
card DetermineAgeRange when age >= 15 and age <= 18, then: GetMessage do | ||
age_range = "15 - 18" | ||
end | ||
|
||
card DetermineAgeRange when age >= 25 and age <= 30, then: GetMessage do | ||
age_range = "25 - 30" | ||
end | ||
|
||
card DetermineAgeRange, then: GetMessage do | ||
age_range = "" | ||
end | ||
|
||
``` | ||
|
||
```stack | ||
card GetMessage, then: SendMessage do | ||
contentsets = | ||
get( | ||
"https://content-repo-api-qa.prk-k8s.prd-p6t.org/api/v2/orderedcontent/", | ||
headers: [ | ||
["Authorization", "Token @global.config.contentrepo_token"] | ||
], | ||
query: [ | ||
["gender", "@contact.gender"], | ||
["age", "@age_range"], | ||
["relationship", "@contact.relationship_status"] | ||
] | ||
) | ||
|
||
contentset = contentsets.body.results[0] | ||
|
||
contentset_item = contentset.pages[push_messaging_content_set_position] | ||
|
||
page = | ||
get( | ||
"https://content-repo-api-qa.prk-k8s.prd-p6t.org/api/v2/pages/@contentset_item.id/", | ||
headers: [ | ||
["Authorization", "Token @global.config.contentrepo_token"] | ||
], | ||
query: [["whatsapp", "true"]] | ||
) | ||
end | ||
|
||
card SendMessage when page.body.body.is_whatsapp_template do | ||
write_result("template_sent", "@page.body.body.whatsapp_template_name") | ||
|
||
send_message_template("@page.body.body.whatsapp_template_name", "en_US", [ | ||
"@contact.whatsapp_profile_name", | ||
"Second" | ||
]) | ||
end | ||
|
||
card SendMessage do | ||
write_result("message_sent", "@page.body.id") | ||
|
||
text(""" | ||
@page.body.title | ||
|
||
@page.body.body.text.value.message | ||
""") | ||
end | ||
|
||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
# Push Messaging: Signup | ||
|
||
This flow asks the user whether they want to sign up for the testing push messaging. | ||
|
||
If they decline, then we exit | ||
|
||
If they accept, then we search the ordered content sets on contentrepo for the one with the profile fields specified in the config. | ||
|
||
## Configuration | ||
|
||
This Journey requires the `config.contentrepo_token` global variable to be set. | ||
|
||
This Journey also requires configuration for "gender", "age", and/or "relationship" which is used to fetch the correct Ordered Content Set. | ||
|
||
## Contact fields | ||
|
||
* push_messaging_signup, the time when they signed up for push messages | ||
|
||
## Flow results | ||
|
||
* push_messaging_signup, the id of the content set that the user signed up for, or no if they didn't sign up | ||
|
||
## Connections to other stacks | ||
|
||
This Journey does not link to any other Journeys | ||
|
||
```stack | ||
card AskSignup do | ||
buttons(FetchContentSet: "Yes, please", Exit: "No, thank you") do | ||
text(""" | ||
Hi! | ||
|
||
Would you like to sign up to our testing messaging set? | ||
|
||
You will receive 5 messages, one every 5 minutes. | ||
""") | ||
end | ||
end | ||
|
||
card FetchContentSet, then: CompleteSignup do | ||
contentsets = | ||
get( | ||
"https://content-repo-api-qa.prk-k8s.prd-p6t.org/api/v2/orderedcontent/", | ||
headers: [ | ||
["Authorization", "Token @global.config.contentrepo_token"] | ||
], | ||
query: [ | ||
["gender", "@contact.gender"], | ||
["age", "@contact.age"], | ||
["relationship", "@contact.relationship"] | ||
] | ||
) | ||
|
||
contentset = contentsets.body.results[0] | ||
end | ||
|
||
card CompleteSignup do | ||
signup_time = now() | ||
update_contact(push_messaging_signup: "@signup_time") | ||
write_result("push_messaging_signup", "@contentset.id") | ||
text("Thank you for signing up! You will receive your first message shortly") | ||
end | ||
|
||
card Exit do | ||
write_result("push_messaging_signup", "no") | ||
text("Thank you! You will not be sent any messages.") | ||
end | ||
|
||
``` |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this an old comment that can be removed, or one we should keep there for future dev?