|
@@ -1,8 +1,13 @@
|
|
# Sendy Mail List Spec
|
|
# Sendy Mail List Spec
|
|
|
|
+* Using rails to get member groups from kdan cloud
|
|
|
|
+* Using gem Sequel to access sendy mysql db
|
|
|
|
|
|
-Using rails to get member groups from kdan cloud.
|
|
|
|
-
|
|
|
|
-Using gem Sequel to access sendy mysql db
|
|
|
|
|
|
+# Story
|
|
|
|
+* Need a one-time promotion mail list creater.
|
|
|
|
+* Need to do a/b testing on a certain event.
|
|
|
|
+* Should not bother opt-out users.
|
|
|
|
+* Should not sent to mark-as-spam users.
|
|
|
|
+* Should not sent to invalid email address.
|
|
|
|
|
|
# Features
|
|
# Features
|
|
1. To create list
|
|
1. To create list
|
|
@@ -19,79 +24,60 @@ Using gem Sequel to access sendy mysql db
|
|
* app\_series (receipt.product.app.app_series)
|
|
* app\_series (receipt.product.app.app_series)
|
|
* pack (receipt.product.pack)
|
|
* pack (receipt.product.pack)
|
|
* platform (receipt.product.app.device)
|
|
* platform (receipt.product.app.device)
|
|
- * subscription\_status (kdan.pack\_subscriptions)
|
|
|
|
|
|
+ * subscription\_status (kdan.subscriptions)
|
|
* A/B Testing
|
|
* A/B Testing
|
|
* Main version %, default 100%
|
|
* Main version %, default 100%
|
|
|
|
|
|
3. To prevent unsubscribed, bounced, complaint emails into the list
|
|
3. To prevent unsubscribed, bounced, complaint emails into the list
|
|
* Unsubscribe flag should be considered as global
|
|
* Unsubscribe flag should be considered as global
|
|
- * Cache unsubscribed, bounced, complaint emails as black list
|
|
|
|
|
|
|
|
4. To delete list
|
|
4. To delete list
|
|
|
|
|
|
# Models
|
|
# Models
|
|
|
|
+## Member Center
|
|
|
|
+### Member
|
|
|
|
+~~~ruby
|
|
|
|
+add_column :members, :sendy_sub_status, enum: [:active, :unsubscribed, :bounced, :bounced_soft, :complaint]
|
|
|
|
+~~~
|
|
|
|
+### Schedule.rb
|
|
|
|
+* update :sendy\_sub\_status every 15m
|
|
|
|
+* select subscribers.timestamp \> 15.minutes.ago
|
|
|
|
+
|
|
## IAP Service
|
|
## IAP Service
|
|
### Kdan
|
|
### Kdan
|
|
-```
|
|
|
|
-has_many :pack_subscriptions, class: 'KdanPackSubscriptionStatus'
|
|
|
|
-```
|
|
|
|
-### Pack
|
|
|
|
-```
|
|
|
|
-has_many :products
|
|
|
|
-has_many :subscribed_kdans, class: 'KdanPackSubscriptionStatus'
|
|
|
|
-```
|
|
|
|
-
|
|
|
|
-```
|
|
|
|
-{
|
|
|
|
- name:string,
|
|
|
|
- code:string
|
|
|
|
-}
|
|
|
|
-```
|
|
|
|
-
|
|
|
|
-```
|
|
|
|
-# C365
|
|
|
|
-Pack.create(name: 'Creativity 365', code: 'C365')
|
|
|
|
-Pack.create(name: 'Creativity 365 Teacher & Student Offer', code: 'C365TS')
|
|
|
|
-Pack.create(name: 'Creativity 365 Education', code: 'C365EDU')
|
|
|
|
-Pack.create(name: 'Creativity 365 Business', code: 'C365BUS')
|
|
|
|
-# D365
|
|
|
|
-Pack.create(name: 'Document 365', code: 'D365')
|
|
|
|
-Pack.create(name: 'Document 365 Volumen Licensing', code: 'D365VL')
|
|
|
|
-# Cloud
|
|
|
|
-Pack.create(name: 'Cloud Pack for Animation Desk', code: 'cloud_pack_ad')
|
|
|
|
-Pack.create(name: 'Cloud Pack for Noteledge', code: 'cloud_pack_nl')
|
|
|
|
-Pack.create(name: 'Cloud Pack for PDF', code: 'cloud_pack_pdf')
|
|
|
|
-Pack.create(name: 'Cloud Pack for Write-on', code: 'cloud_pack_wo')
|
|
|
|
-Pack.create(name: 'Cloud Pack for Pocket Scanner', code: 'cloud_pack_scan')
|
|
|
|
-# Deluxe
|
|
|
|
-Pack.create(name: 'Deluxe Pack for Animation Desk', code: 'deluxe_pack_Ad')
|
|
|
|
-Pack.create(name: 'Deluxe Pack for Noteledge', code: 'deluxe_pack_nl')
|
|
|
|
-Pack.create(name: 'Deluxe Pack for PDF', code: 'deluxe_pack_pdf')
|
|
|
|
-Pack.create(name: 'Deluxe Pack for Write-on', code: 'deluxe_pack_wo')
|
|
|
|
-Pack.create(name: 'Deluxe Pack for Pocket Scanner', code: 'deluxe_pack_scan')
|
|
|
|
-```
|
|
|
|
-### Product
|
|
|
|
-```
|
|
|
|
-belongs_to :pack
|
|
|
|
-```
|
|
|
|
-### KdanPackSubscriptionStatus
|
|
|
|
-```
|
|
|
|
|
|
+~~~ruby
|
|
|
|
+has_many :subscriptions, class: 'KdanPackSubscription'
|
|
|
|
+~~~
|
|
|
|
+### KdanProduct
|
|
|
|
+~~~ruby
|
|
|
|
+has_many :subscriptions, class: 'KdanPackSubscription'
|
|
|
|
+~~~
|
|
|
|
+### KdanPackSubscription
|
|
|
|
+* only apply to following packs
|
|
|
|
+ * Creativity 365
|
|
|
|
+ * ---Creativity 365 Teacher & Student---
|
|
|
|
+ * Document 365
|
|
|
|
+ * ~~Creativity 365 Education~~
|
|
|
|
+ * ~~Creativity 365 Business~~
|
|
|
|
+ * ~~Document 365 Volume Licensing~~
|
|
|
|
+
|
|
|
|
+~~~ruby
|
|
belongs_to :kdan
|
|
belongs_to :kdan
|
|
-belongs_to :pack
|
|
|
|
-```
|
|
|
|
-```
|
|
|
|
|
|
+belongs_to :kdan_product
|
|
|
|
+~~~
|
|
|
|
+~~~ruby
|
|
{
|
|
{
|
|
kdan_id:integer,
|
|
kdan_id:integer,
|
|
pack_id:integer,
|
|
pack_id:integer,
|
|
stauts:[free_trial, active, expired, refund, cancel]
|
|
stauts:[free_trial, active, expired, refund, cancel]
|
|
}
|
|
}
|
|
-```
|
|
|
|
-* free\_trial: this subscription is in its free trial period.
|
|
|
|
-* active: this subscription is active now.
|
|
|
|
-* expired: this subscription is expired now.
|
|
|
|
-* cancel: this subscription has been canceled on auto-renew.
|
|
|
|
-* refund: this subscription has been refund.
|
|
|
|
-* status priority: active \> free\_trial \> expired \> refund \> cancel
|
|
|
|
|
|
+~~~
|
|
|
|
+* free\_trial: Subscription is in free trial period.
|
|
|
|
+* active: Subscription is active now.
|
|
|
|
+* expired: Subscription is expired now.
|
|
|
|
+* cancel: Auto-renew canceled but current subscription not changed.
|
|
|
|
+* refund: Auto-renew canceled and current subscription rollbacked.
|
|
|
|
+* status priority: **active \> free\_trial \> expired \> cancel \> refund**
|
|
|
|
|
|
### Schedule.rb
|
|
### Schedule.rb
|
|
* update KdanPackSubscriptionStatus every 15m
|
|
* update KdanPackSubscriptionStatus every 15m
|
|
@@ -100,7 +86,7 @@ belongs_to :pack
|
|
|
|
|
|
## CR System
|
|
## CR System
|
|
### SendyMailList
|
|
### SendyMailList
|
|
-```
|
|
|
|
|
|
+~~~ruby
|
|
{
|
|
{
|
|
description:string,
|
|
description:string,
|
|
sendy_list_long_id:string,
|
|
sendy_list_long_id:string,
|
|
@@ -113,17 +99,7 @@ belongs_to :pack
|
|
complaint_count:integer,
|
|
complaint_count:integer,
|
|
sendy_delete_at:datetime,
|
|
sendy_delete_at:datetime,
|
|
}
|
|
}
|
|
-```
|
|
|
|
-### SendyBlackList
|
|
|
|
-```
|
|
|
|
-{
|
|
|
|
- email:string,
|
|
|
|
- reason: [unsubscribed, bounced, bounced_soft, complaint]
|
|
|
|
-}
|
|
|
|
-```
|
|
|
|
-### Schedule.rb
|
|
|
|
-* update SendyBlackList every 15m
|
|
|
|
-* select subscribers.timestamp > 15.minutes.ago
|
|
|
|
|
|
+~~~
|
|
|
|
|
|
# Views
|
|
# Views
|
|
## CR System
|
|
## CR System
|
|
@@ -154,11 +130,11 @@ Going to Build up Sendy list [Go]
|
|
----
|
|
----
|
|
|
|
|
|
* List Name: [ZCR] my list ver. A
|
|
* List Name: [ZCR] my list ver. A
|
|
-* List Count: 100
|
|
|
|
|
|
+* List Count: 50
|
|
* List Content:
|
|
* List Content:
|
|
* kdan\_id, email, from\_application, comfirmed, location, language, app\_series, pack, platform
|
|
* kdan\_id, email, from\_application, comfirmed, location, language, app\_series, pack, platform
|
|
|
|
|
|
* List Name: [ZCR] my list ver. B
|
|
* List Name: [ZCR] my list ver. B
|
|
-* List Count: 100
|
|
|
|
|
|
+* List Count: 50
|
|
* List Content:
|
|
* List Content:
|
|
* kdan\_id, email, from\_application, comfirmed, location, language, app\_series, pack, platform
|
|
* kdan\_id, email, from\_application, comfirmed, location, language, app\_series, pack, platform
|