Skip to content

Commit

Permalink
feat: Notify users of plan changes (#4271)
Browse files Browse the repository at this point in the history
When we receive a plan change from the cloudery (i.e. a new feature
set that's not a sponsorship), we send a notification (preferably a
push one) to the user to invite them to reload their mobile app and/or
their browser page so flags can be refreshed.

This is especially useful when the user is expecting to gain new
features.
  • Loading branch information
taratatach committed Dec 22, 2023
2 parents 676a77b + d48fe9a commit 5666dba
Show file tree
Hide file tree
Showing 15 changed files with 1,195 additions and 905 deletions.
25 changes: 25 additions & 0 deletions assets/locales/de.po
Original file line number Diff line number Diff line change
Expand Up @@ -893,6 +893,31 @@ msgstr "Check our plans"
msgid "Notifications OAuth Clients Devices Text"
msgstr "Manage my devices"

msgid "Notifications Plan Changed Title"
msgstr "Your plan change has been validated!"

msgid "Notifications Plan Changed Message"
msgstr "Click here to reload the app and apply the changes."

msgid "Notifications Plan Changed Greeting"
msgstr "Hello,"

msgid "Notifications Plan Changed Intro"
msgstr ""
"We are pleased to confirm that your plan change has been validated.\n"
"Here are our recommendations to make the most of it:"

msgid "Notifications Plan Changed Recommendation 1"
msgstr "On your computer: refresh the page if your Cozy is open."

msgid "Notifications Plan Changed Recommendation 2"
msgstr "On your smartphone (Cozy app): close and relaunch the app."

msgid "Notifications Plan Changed Outro"
msgstr ""
"Don't hesitate to contact us if you have any questions about subscriptions or using your Cozy.\n"
"Claude will be delighted to help you with all your questions!"

msgid "Terms of services have been updated"
msgstr ""
"Um DSGVO-konform zu sein hat Cozy Cloud seine Nutzungsbedingungen zum 25. "
Expand Down
25 changes: 25 additions & 0 deletions assets/locales/en.po
Original file line number Diff line number Diff line change
Expand Up @@ -1170,6 +1170,31 @@ msgstr "Check our plans"
msgid "Notifications OAuth Clients Devices Text"
msgstr "Manage my devices"

msgid "Notifications Plan Changed Title"
msgstr "Your plan change has been validated!"

msgid "Notifications Plan Changed Message"
msgstr "Click here to reload the app and apply the changes."

msgid "Notifications Plan Changed Greeting"
msgstr "Hello,"

msgid "Notifications Plan Changed Intro"
msgstr ""
"We are pleased to confirm that your plan change has been validated.\n"
"Here are our recommendations to make the most of it:"

msgid "Notifications Plan Changed Recommendation 1"
msgstr "On your computer: refresh the page if your Cozy is open."

msgid "Notifications Plan Changed Recommendation 2"
msgstr "On your smartphone (Cozy app): close and relaunch the app."

msgid "Notifications Plan Changed Outro"
msgstr ""
"Don't hesitate to contact us if you have any questions about subscriptions or using your Cozy.\n"
"Claude will be delighted to help you with all your questions!"

msgid "Terms of services have been updated"
msgstr "To comply with the GDPR, Cozy Cloud has updated its Terms of Services that have taken effect on May 25, 2018"

Expand Down
25 changes: 25 additions & 0 deletions assets/locales/es.po
Original file line number Diff line number Diff line change
Expand Up @@ -907,6 +907,31 @@ msgstr "Check our plans"
msgid "Notifications OAuth Clients Devices Text"
msgstr "Manage my devices"

msgid "Notifications Plan Changed Title"
msgstr "Your plan change has been validated!"

msgid "Notifications Plan Changed Message"
msgstr "Click here to reload the app and apply the changes."

msgid "Notifications Plan Changed Greeting"
msgstr "Hello,"

msgid "Notifications Plan Changed Intro"
msgstr ""
"We are pleased to confirm that your plan change has been validated.\n"
"Here are our recommendations to make the most of it:"

msgid "Notifications Plan Changed Recommendation 1"
msgstr "On your computer: refresh the page if your Cozy is open."

msgid "Notifications Plan Changed Recommendation 2"
msgstr "On your smartphone (Cozy app): close and relaunch the app."

msgid "Notifications Plan Changed Outro"
msgstr ""
"Don't hesitate to contact us if you have any questions about subscriptions or using your Cozy.\n"
"Claude will be delighted to help you with all your questions!"

msgid "Terms of services have been updated"
msgstr ""
"Para cumplir con la GDPR que estará vigente a partir del 25 de mayo de 2018,"
Expand Down
25 changes: 25 additions & 0 deletions assets/locales/fr.po
Original file line number Diff line number Diff line change
Expand Up @@ -1275,6 +1275,31 @@ msgstr "Voir les offres"
msgid "Notifications OAuth Clients Devices Text"
msgstr "Gérer mes appareils"

msgid "Notifications Plan Changed Title"
msgstr "Votre changement d’offre a été validé !"

msgid "Notifications Plan Changed Message"
msgstr "Cliquez ici pour relancer l’app, et appliquer les modifications."

msgid "Notifications Plan Changed Greeting"
msgstr "Bonjour,"

msgid "Notifications Plan Changed Intro"
msgstr ""
"Nous avons le plaisir de vous confirmer que votre changement d’offre a bien été validé.\n"
"Voici nos recommendations pour en profiter au mieux :"

msgid "Notifications Plan Changed Recommendation 1"
msgstr "Sur votre ordinateur : actualiser la page si votre Cozy est ouvert."

msgid "Notifications Plan Changed Recommendation 2"
msgstr "Sur votre smartphone (app Cozy) : fermer et relancer l’app."

msgid "Notifications Plan Changed Outro"
msgstr ""
"N’hésitez pas à nous contacter pour toute question en lien avec les abonnements, ou l’utilisation de votre Cozy.\n"
"Claude se fera un plaisir de vous accompagner sur tous vos sujets !"

msgid "Terms of services have been updated"
msgstr ""
"Dans le cadre du RGPD, Cozy Cloud met à jour ses Conditions Générales "
Expand Down
25 changes: 25 additions & 0 deletions assets/locales/ja.po
Original file line number Diff line number Diff line change
Expand Up @@ -715,6 +715,31 @@ msgstr "Check our plans"
msgid "Notifications OAuth Clients Devices Text"
msgstr "Manage my devices"

msgid "Notifications Plan Changed Title"
msgstr "Your plan change has been validated!"

msgid "Notifications Plan Changed Message"
msgstr "Click here to reload the app and apply the changes."

msgid "Notifications Plan Changed Greeting"
msgstr "Hello,"

msgid "Notifications Plan Changed Intro"
msgstr ""
"We are pleased to confirm that your plan change has been validated.\n"
"Here are our recommendations to make the most of it:"

msgid "Notifications Plan Changed Recommendation 1"
msgstr "On your computer: refresh the page if your Cozy is open."

msgid "Notifications Plan Changed Recommendation 2"
msgstr "On your smartphone (Cozy app): close and relaunch the app."

msgid "Notifications Plan Changed Outro"
msgstr ""
"Don't hesitate to contact us if you have any questions about subscriptions or using your Cozy.\n"
"Claude will be delighted to help you with all your questions!"

msgid "Terms of services have been updated"
msgstr "GDPR を遵守するため、Cozy Cloud は2018年5月25日に施行された利用規約を更新しました"

Expand Down
25 changes: 25 additions & 0 deletions assets/locales/nl_NL.po
Original file line number Diff line number Diff line change
Expand Up @@ -1091,6 +1091,31 @@ msgstr "Check our plans"
msgid "Notifications OAuth Clients Devices Text"
msgstr "Manage my devices"

msgid "Notifications Plan Changed Title"
msgstr "Your plan change has been validated!"

msgid "Notifications Plan Changed Message"
msgstr "Click here to reload the app and apply the changes."

msgid "Notifications Plan Changed Greeting"
msgstr "Hello,"

msgid "Notifications Plan Changed Intro"
msgstr ""
"We are pleased to confirm that your plan change has been validated.\n"
"Here are our recommendations to make the most of it:"

msgid "Notifications Plan Changed Recommendation 1"
msgstr "On your computer: refresh the page if your Cozy is open."

msgid "Notifications Plan Changed Recommendation 2"
msgstr "On your smartphone (Cozy app): close and relaunch the app."

msgid "Notifications Plan Changed Outro"
msgstr ""
"Don't hesitate to contact us if you have any questions about subscriptions or using your Cozy.\n"
"Claude will be delighted to help you with all your questions!"

msgid "Terms of services have been updated"
msgstr ""
"Om te voldoen aan de GDPR heeft Cozy Cloud zijn algemene voorwaarden "
Expand Down
18 changes: 18 additions & 0 deletions assets/mails/notifications_plan_changed.mjml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{{define "content"}}
<mj-text mj-class="title content-medium">
<img src="https://files.cozycloud.cc/email-assets/stack/icon-check-circle.png" width="16" height="16" style="vertical-align:sub;"/>&nbsp;
{{t "Notifications Plan Changed Title"}}
</mj-text>
<mj-text mj-class="content-medium">
{{tHTML "Notifications Plan Changed Intro"}}
</mj-text>
<mj-text mj-class="content-medium">
<ul style="margin: 0">
<li>{{t "Notifications Plan Changed Recommendation 1"}}</li>
<li>{{t "Notifications Plan Changed Recommendation 2"}}</li>
</ul>
</mj-text>
<mj-text mj-class="content-medium">
{{tHTML "Notifications Plan Changed Outro"}}
</mj-text>
{{end}}
9 changes: 9 additions & 0 deletions assets/mails/notifications_plan_changed.text
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{{t "Notifications Plan Changed Title"}}
---

{{t "Notifications Plan Changed Intro"}}

- {{t "Notifications Plan Changed Recommendation 1"}}
- {{t "Notifications Plan Changed Recommendation 2"}}

{{t "Notifications Plan Changed Outro"}}
1 change: 1 addition & 0 deletions docs/assets.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ with given parameter. For example:
* http://cozy.localhost:8080/dev/mails/notifications_diskquota
* http://cozy.localhost:8080/dev/mails/notifications_oauthclients
* http://cozy.localhost:8080/dev/mails/notifications_sharing
* http://cozy.localhost:8080/dev/mails/notifications_plan_changed
* http://cozy.localhost:8080/dev/mails/passphrase_hint
* http://cozy.localhost:8080/dev/mails/passphrase_reset
* http://cozy.localhost:8080/dev/mails/sharing_request
Expand Down
9 changes: 9 additions & 0 deletions model/instance/instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,15 @@ func (i *Instance) HasPremiumLinksEnabled() bool {
return false
}

func (i *Instance) HasFeatureSet(set string) bool {
for _, s := range i.FeatureSets {
if set == s {
return true
}
}
return false
}

// ensure Instance implements couchdb.Doc
var (
_ couchdb.Doc = &Instance{}
Expand Down
16 changes: 16 additions & 0 deletions model/instance/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,19 @@ func APIManagerClient(inst *Instance) *manager.APIClient {

return manager.NewAPIClient(api.URL, api.Token)
}

var cbPlanChanged func(i *Instance)

// RegisterPlanChangeCallback registers the given callback, called whenever
// PushPlanChangeNotification is called.
func RegisterPlanChangeCallback(cb func(*Instance)) {
cbPlanChanged = cb
}

// PushPlanChangeNotification calls the plan change callback for the given instance if
// it was registered.
func PushPlanChangeNotification(inst *Instance) {
if cbPlanChanged != nil {
cbPlanChanged(inst)
}
}
23 changes: 23 additions & 0 deletions model/notification/center/notification_center.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ const (
// NotificationOAuthClients category for sending alert when exceeding the
// connected OAuth clients limit.
NotificationOAuthClients = "oauth-clients"
// NotificationsPlanChanged category for sending alert when a we receive a
// request for a feature set (i.e. plan) change.
NotificationsPlanChanged = "plan-changed"
)

var (
Expand All @@ -45,6 +48,12 @@ var (
Stateful: false,
MailTemplate: "notifications_oauthclients",
},
NotificationsPlanChanged: {
Description: "Invite the user to reload their app to reload the flags after a plan change",
Collapsible: false,
Stateful: false,
MailTemplate: "notifications_plan_changed",
},
}
)

Expand Down Expand Up @@ -109,6 +118,20 @@ func init() {
}
PushStack(i.DomainName(), NotificationOAuthClients, n)
})

instance.RegisterPlanChangeCallback(func(i *instance.Instance) {
n := &notification.Notification{
Title: i.Translate("Notifications Plan Changed Title"),
Message: i.Translate("Notifications Plan Changed Message"),
Slug: consts.SettingsSlug,
Data: map[string]interface{}{
// For mobile push notification
"refresh": "true",
},
PreferredChannels: []string{"mobile"},
}
PushStack(i.DomainName(), NotificationsPlanChanged, n)
})
}

// PushStack creates and sends a new notification where the source is the stack.
Expand Down
20 changes: 20 additions & 0 deletions web/instances/feature.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"net/http"
"sort"
"strings"

"github.com/cozy/cozy-stack/model/feature"
"github.com/cozy/cozy-stack/model/instance"
Expand Down Expand Up @@ -67,10 +68,29 @@ func putFeatureSets(c echo.Context) error {
return wrapError(err)
}
sort.Strings(list)

hasNewPlan := false
for _, newSet := range list {
// Skip sponsorship sets
if strings.HasPrefix(newSet, "s-") {
continue
}

if !inst.HasFeatureSet(newSet) {
hasNewPlan = true
break
}
}

inst.FeatureSets = list
if err := instance.Update(inst); err != nil {
return wrapError(err)
}

if hasNewPlan {
instance.PushPlanChangeNotification(inst)
}

return c.JSON(http.StatusOK, inst.FeatureSets)
}

Expand Down
Loading

0 comments on commit 5666dba

Please sign in to comment.