@headless-lms/core 0.2.0 → 0.4.0
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.
- package/dist/assets/events.d.ts +42 -24
- package/dist/assets/events.js +1 -1
- package/dist/assets/events.js.map +1 -1
- package/dist/assets/file-urls.d.ts +20 -0
- package/dist/assets/file-urls.js +25 -0
- package/dist/assets/file-urls.js.map +1 -0
- package/dist/assets/index.d.ts +6 -4
- package/dist/assets/index.js +4 -2
- package/dist/assets/jobs.d.ts +15 -0
- package/dist/assets/jobs.js +30 -0
- package/dist/assets/jobs.js.map +1 -0
- package/dist/assets/model.d.ts +2 -2
- package/dist/assets/ports.d.ts +46 -15
- package/dist/assets/service.d.ts +38 -7
- package/dist/assets/service.js +287 -38
- package/dist/assets/service.js.map +1 -1
- package/dist/automations/actions.d.ts +13 -24
- package/dist/automations/actions.js +106 -42
- package/dist/automations/actions.js.map +1 -1
- package/dist/automations/catalog.js +226 -3
- package/dist/automations/catalog.js.map +1 -1
- package/dist/automations/community-derivations.d.ts +14 -0
- package/dist/automations/community-derivations.js +439 -0
- package/dist/automations/community-derivations.js.map +1 -0
- package/dist/automations/community-mail.d.ts +98 -0
- package/dist/automations/community-mail.js +70 -0
- package/dist/automations/community-mail.js.map +1 -0
- package/dist/automations/events.d.ts +18 -0
- package/dist/automations/index.d.ts +13 -4
- package/dist/automations/index.js +10 -2
- package/dist/automations/model.d.ts +10 -3
- package/dist/automations/model.js +15 -2
- package/dist/automations/model.js.map +1 -1
- package/dist/automations/notifications/debounce.d.ts +25 -0
- package/dist/automations/notifications/debounce.js +93 -0
- package/dist/automations/notifications/debounce.js.map +1 -0
- package/dist/automations/notifications/defaults.d.ts +8 -0
- package/dist/automations/notifications/defaults.js +316 -0
- package/dist/automations/notifications/defaults.js.map +1 -0
- package/dist/automations/notifications/delivery.d.ts +28 -0
- package/dist/automations/notifications/delivery.js +88 -0
- package/dist/automations/notifications/delivery.js.map +1 -0
- package/dist/automations/notifications/processor.d.ts +64 -0
- package/dist/automations/notifications/processor.js +270 -0
- package/dist/automations/notifications/processor.js.map +1 -0
- package/dist/automations/notifications/rules/content.d.ts +6 -0
- package/dist/automations/notifications/rules/content.js +39 -0
- package/dist/automations/notifications/rules/content.js.map +1 -0
- package/dist/automations/notifications/rules/discussion.d.ts +7 -0
- package/dist/automations/notifications/rules/discussion.js +678 -0
- package/dist/automations/notifications/rules/discussion.js.map +1 -0
- package/dist/automations/notifications/rules/entitlements.d.ts +6 -0
- package/dist/automations/notifications/rules/entitlements.js +249 -0
- package/dist/automations/notifications/rules/entitlements.js.map +1 -0
- package/dist/automations/notifications/rules/index.d.ts +6 -0
- package/dist/automations/notifications/rules/index.js +15 -0
- package/dist/automations/notifications/rules/index.js.map +1 -0
- package/dist/automations/notifications/rules/organizations.d.ts +6 -0
- package/dist/automations/notifications/rules/organizations.js +28 -0
- package/dist/automations/notifications/rules/organizations.js.map +1 -0
- package/dist/automations/notifications/rules/recipients.d.ts +32 -0
- package/dist/automations/notifications/rules/recipients.js +99 -0
- package/dist/automations/notifications/rules/recipients.js.map +1 -0
- package/dist/automations/notifications/service.d.ts +27 -0
- package/dist/automations/notifications/service.js +45 -0
- package/dist/automations/notifications/service.js.map +1 -0
- package/dist/automations/notifications/types.d.ts +7 -0
- package/dist/automations/notifications/types.js +473 -0
- package/dist/automations/notifications/types.js.map +1 -0
- package/dist/automations/ports.d.ts +121 -3
- package/dist/automations/schedule.d.ts +6 -0
- package/dist/automations/schedule.js +41 -0
- package/dist/automations/schedule.js.map +1 -0
- package/dist/automations/service.d.ts +20 -4
- package/dist/automations/service.js +246 -45
- package/dist/automations/service.js.map +1 -1
- package/dist/content/events.d.ts +712 -50
- package/dist/content/events.js +55 -1
- package/dist/content/events.js.map +1 -1
- package/dist/content/index.d.ts +6 -4
- package/dist/content/index.js +3 -1
- package/dist/content/model.d.ts +2 -2
- package/dist/content/notification-categories.d.ts +36 -0
- package/dist/content/notification-categories.js +64 -0
- package/dist/content/notification-categories.js.map +1 -0
- package/dist/content/ports.d.ts +90 -18
- package/dist/content/service.d.ts +57 -18
- package/dist/content/service.js +520 -25
- package/dist/content/service.js.map +1 -1
- package/dist/content/titles.d.ts +22 -0
- package/dist/content/titles.js +69 -0
- package/dist/content/titles.js.map +1 -0
- package/dist/content/types.d.ts +2 -2
- package/dist/discussion/authors.d.ts +10 -0
- package/dist/discussion/authors.js +23 -0
- package/dist/discussion/authors.js.map +1 -0
- package/dist/discussion/chats.d.ts +109 -0
- package/dist/discussion/chats.js +831 -0
- package/dist/discussion/chats.js.map +1 -0
- package/dist/discussion/digests.d.ts +24 -0
- package/dist/discussion/digests.js +104 -0
- package/dist/discussion/digests.js.map +1 -0
- package/dist/discussion/events.d.ts +785 -56
- package/dist/discussion/events.js +165 -5
- package/dist/discussion/events.js.map +1 -1
- package/dist/discussion/index.d.ts +12 -3
- package/dist/discussion/index.js +9 -1
- package/dist/discussion/jobs.d.ts +16 -0
- package/dist/discussion/jobs.js +40 -0
- package/dist/discussion/jobs.js.map +1 -0
- package/dist/discussion/mentions.d.ts +11 -0
- package/dist/discussion/mentions.js +35 -0
- package/dist/discussion/mentions.js.map +1 -0
- package/dist/discussion/ports.d.ts +372 -28
- package/dist/discussion/ports.js +6 -1
- package/dist/discussion/ports.js.map +1 -0
- package/dist/discussion/posts.d.ts +113 -0
- package/dist/discussion/posts.js +775 -0
- package/dist/discussion/posts.js.map +1 -0
- package/dist/discussion/service.d.ts +42 -11
- package/dist/discussion/service.js +364 -85
- package/dist/discussion/service.js.map +1 -1
- package/dist/discussion/subscriptions.d.ts +37 -0
- package/dist/discussion/subscriptions.js +99 -0
- package/dist/discussion/subscriptions.js.map +1 -0
- package/dist/discussion/titles.d.ts +26 -0
- package/dist/discussion/titles.js +84 -0
- package/dist/discussion/titles.js.map +1 -0
- package/dist/entitlements/events.d.ts +178 -11
- package/dist/entitlements/events.js +28 -1
- package/dist/entitlements/events.js.map +1 -1
- package/dist/entitlements/index.d.ts +6 -4
- package/dist/entitlements/index.js +3 -1
- package/dist/entitlements/jobs.d.ts +12 -0
- package/dist/entitlements/jobs.js +18 -0
- package/dist/entitlements/jobs.js.map +1 -0
- package/dist/entitlements/model.d.ts +3 -2
- package/dist/entitlements/ports.d.ts +128 -11
- package/dist/entitlements/rules.d.ts +12 -0
- package/dist/entitlements/rules.js +17 -0
- package/dist/entitlements/rules.js.map +1 -0
- package/dist/entitlements/service.d.ts +57 -3
- package/dist/entitlements/service.js +492 -2
- package/dist/entitlements/service.js.map +1 -1
- package/dist/identity/access.d.ts +6 -0
- package/dist/identity/access.js +7 -0
- package/dist/identity/access.js.map +1 -0
- package/dist/identity/devices.d.ts +30 -0
- package/dist/identity/devices.js +107 -0
- package/dist/identity/devices.js.map +1 -0
- package/dist/identity/events.d.ts +2 -2
- package/dist/identity/index.d.ts +7 -4
- package/dist/identity/index.js +4 -1
- package/dist/identity/model.d.ts +2 -1
- package/dist/identity/notification-settings.d.ts +28 -0
- package/dist/identity/notification-settings.js +113 -0
- package/dist/identity/notification-settings.js.map +1 -0
- package/dist/identity/ports.d.ts +97 -3
- package/dist/identity/service.d.ts +14 -3
- package/dist/identity/service.js +62 -5
- package/dist/identity/service.js.map +1 -1
- package/dist/integrations/events.d.ts +3 -3
- package/dist/integrations/model.js +1 -1
- package/dist/integrations/model.js.map +1 -1
- package/dist/integrations/service.js +2 -2
- package/dist/integrations/service.js.map +1 -1
- package/dist/organizations/access-scopes.d.ts +19 -0
- package/dist/organizations/access-scopes.js +89 -0
- package/dist/organizations/access-scopes.js.map +1 -0
- package/dist/organizations/events.d.ts +75 -33
- package/dist/organizations/events.js +6 -0
- package/dist/organizations/events.js.map +1 -1
- package/dist/organizations/index.d.ts +8 -6
- package/dist/organizations/index.js +5 -3
- package/dist/organizations/members.d.ts +8 -5
- package/dist/organizations/members.js.map +1 -1
- package/dist/organizations/notification-categories.d.ts +32 -0
- package/dist/organizations/notification-categories.js +51 -0
- package/dist/organizations/notification-categories.js.map +1 -0
- package/dist/organizations/ports.d.ts +17 -11
- package/dist/organizations/roles.d.ts +6 -10
- package/dist/organizations/roles.js +19 -7
- package/dist/organizations/roles.js.map +1 -1
- package/dist/organizations/service.d.ts +22 -11
- package/dist/organizations/service.js +164 -47
- package/dist/organizations/service.js.map +1 -1
- package/dist/organizations/types.d.ts +1 -10
- package/dist/progress/events.d.ts +14 -14
- package/dist/progress/index.d.ts +2 -2
- package/dist/progress/ports.d.ts +6 -1
- package/dist/progress/service.d.ts +3 -1
- package/dist/progress/service.js +6 -2
- package/dist/progress/service.js.map +1 -1
- package/dist/reporting/admin/index.d.ts +4 -0
- package/dist/reporting/admin/index.js +2 -0
- package/dist/reporting/admin/model.d.ts +108 -0
- package/dist/reporting/admin/ports.d.ts +27 -0
- package/dist/reporting/admin/service.d.ts +22 -0
- package/dist/reporting/admin/service.js +38 -0
- package/dist/reporting/admin/service.js.map +1 -0
- package/dist/reporting/member/index.d.ts +5 -0
- package/dist/reporting/member/index.js +2 -0
- package/dist/reporting/member/model.d.ts +157 -0
- package/dist/reporting/member/ports.d.ts +48 -0
- package/dist/reporting/member/service.d.ts +92 -0
- package/dist/reporting/member/service.js +364 -0
- package/dist/reporting/member/service.js.map +1 -0
- package/dist/shared/actor.d.ts +9 -0
- package/dist/shared/errors.d.ts +19 -1
- package/dist/shared/errors.js +27 -1
- package/dist/shared/errors.js.map +1 -1
- package/dist/shared/id.d.ts +14 -0
- package/dist/shared/id.js +15 -1
- package/dist/shared/id.js.map +1 -1
- package/dist/shared/mailer.d.ts +15 -2
- package/dist/shared/mailer.js +32 -5
- package/dist/shared/mailer.js.map +1 -1
- package/dist/shared/network.d.ts +10 -0
- package/dist/shared/network.js +211 -0
- package/dist/shared/network.js.map +1 -0
- package/dist/shared/notification-categories.d.ts +16 -0
- package/dist/shared/notification-categories.js +94 -0
- package/dist/shared/notification-categories.js.map +1 -0
- package/dist/shared/notification-settings.d.ts +14 -0
- package/dist/shared/notification-settings.js +61 -0
- package/dist/shared/notification-settings.js.map +1 -0
- package/dist/shared/ports.d.ts +48 -2
- package/dist/shared/settings.d.ts +2 -1
- package/dist/shared/settings.js +1 -0
- package/dist/shared/settings.js.map +1 -1
- package/dist/types/assets.d.ts +2 -2
- package/dist/types/automations.d.ts +15 -1
- package/dist/types/content.d.ts +2 -2
- package/dist/types/discussion.d.ts +11 -3
- package/dist/types/email-templates.d.ts +216 -1
- package/dist/types/entitlements.d.ts +2 -2
- package/dist/types/identity.d.ts +48 -2
- package/dist/types/index.d.ts +9 -8
- package/dist/types/notifications.d.ts +157 -0
- package/dist/types/ports.d.ts +6 -0
- package/dist/types/schemas/assets.d.ts +65 -37
- package/dist/types/schemas/assets.js +17 -12
- package/dist/types/schemas/assets.js.map +1 -1
- package/dist/types/schemas/automations.d.ts +9 -1
- package/dist/types/schemas/automations.js +13 -6
- package/dist/types/schemas/automations.js.map +1 -1
- package/dist/types/schemas/content.d.ts +396 -3
- package/dist/types/schemas/content.js +161 -3
- package/dist/types/schemas/content.js.map +1 -1
- package/dist/types/schemas/discussion.d.ts +443 -3
- package/dist/types/schemas/discussion.js +233 -4
- package/dist/types/schemas/discussion.js.map +1 -1
- package/dist/types/schemas/entitlements.d.ts +36 -2
- package/dist/types/schemas/entitlements.js +23 -1
- package/dist/types/schemas/entitlements.js.map +1 -1
- package/dist/types/schemas/identity.d.ts +27 -1
- package/dist/types/schemas/identity.js +14 -2
- package/dist/types/schemas/identity.js.map +1 -1
- package/dist/types/schemas/index.d.ts +9 -8
- package/dist/types/schemas/index.js +9 -8
- package/dist/types/schemas/notifications.d.ts +95 -0
- package/dist/types/schemas/notifications.js +56 -0
- package/dist/types/schemas/notifications.js.map +1 -0
- package/dist/types/schemas/organizations.d.ts +8 -0
- package/dist/types/schemas/organizations.js +2 -0
- package/dist/types/schemas/organizations.js.map +1 -1
- package/dist/types/schemas/progress.d.ts +3 -3
- package/dist/types/schemas/shared.d.ts +3 -1
- package/dist/types/schemas/shared.js +5 -1
- package/dist/types/schemas/shared.js.map +1 -1
- package/package.json +2 -2
- package/dist/reporting/courses/index.d.ts +0 -4
- package/dist/reporting/courses/index.js +0 -2
- package/dist/reporting/courses/model.d.ts +0 -24
- package/dist/reporting/courses/ports.d.ts +0 -13
- package/dist/reporting/courses/service.d.ts +0 -19
- package/dist/reporting/courses/service.js +0 -20
- package/dist/reporting/courses/service.js.map +0 -1
- package/dist/reporting/dashboard/index.d.ts +0 -4
- package/dist/reporting/dashboard/index.js +0 -2
- package/dist/reporting/dashboard/model.d.ts +0 -14
- package/dist/reporting/dashboard/ports.d.ts +0 -13
- package/dist/reporting/dashboard/service.d.ts +0 -19
- package/dist/reporting/dashboard/service.js +0 -20
- package/dist/reporting/dashboard/service.js.map +0 -1
- package/dist/reporting/learn/index.d.ts +0 -5
- package/dist/reporting/learn/index.js +0 -2
- package/dist/reporting/learn/model.d.ts +0 -23
- package/dist/reporting/learn/ports.d.ts +0 -43
- package/dist/reporting/learn/service.d.ts +0 -49
- package/dist/reporting/learn/service.js +0 -116
- package/dist/reporting/learn/service.js.map +0 -1
- package/dist/reporting/students/index.d.ts +0 -4
- package/dist/reporting/students/index.js +0 -2
- package/dist/reporting/students/model.d.ts +0 -51
- package/dist/reporting/students/model.js +0 -1
- package/dist/reporting/students/ports.d.ts +0 -15
- package/dist/reporting/students/ports.js +0 -1
- package/dist/reporting/students/service.d.ts +0 -20
- package/dist/reporting/students/service.js +0 -23
- package/dist/reporting/students/service.js.map +0 -1
- /package/dist/reporting/{courses → admin}/model.js +0 -0
- /package/dist/reporting/{courses → admin}/ports.js +0 -0
- /package/dist/reporting/{dashboard → member}/model.js +0 -0
- /package/dist/reporting/{dashboard → member}/ports.js +0 -0
- /package/dist/{reporting/learn/model.js → shared/actor.js} +0 -0
- /package/dist/{reporting/learn/ports.js → types/notifications.js} +0 -0
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
//#region src/automations/notifications/defaults.ts
|
|
2
|
+
const on = {
|
|
3
|
+
default: true,
|
|
4
|
+
locked: false
|
|
5
|
+
};
|
|
6
|
+
const off = {
|
|
7
|
+
default: false,
|
|
8
|
+
locked: false
|
|
9
|
+
};
|
|
10
|
+
const lockedOn = {
|
|
11
|
+
default: true,
|
|
12
|
+
locked: true
|
|
13
|
+
};
|
|
14
|
+
const DEFAULT_COMMUNITY_CATEGORIES = [
|
|
15
|
+
{
|
|
16
|
+
key: "about_you",
|
|
17
|
+
covers: [
|
|
18
|
+
{
|
|
19
|
+
type: "post.approved",
|
|
20
|
+
reasons: ["subject"]
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
type: "post.removed",
|
|
24
|
+
reasons: ["subject"]
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
type: "comment.removed",
|
|
28
|
+
reasons: ["subject"]
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
type: "space.invited",
|
|
32
|
+
reasons: ["subject"]
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
type: "space.request_approved",
|
|
36
|
+
reasons: ["subject"]
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
type: "space.request_declined",
|
|
40
|
+
reasons: ["subject"]
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
type: "community.welcome",
|
|
44
|
+
reasons: ["subject"]
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
type: "community.ending_soon",
|
|
48
|
+
reasons: ["subject"]
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
type: "chat.added",
|
|
52
|
+
reasons: ["subject"]
|
|
53
|
+
}
|
|
54
|
+
],
|
|
55
|
+
channels: {
|
|
56
|
+
inApp: lockedOn,
|
|
57
|
+
email: on,
|
|
58
|
+
push: on
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
key: "review",
|
|
63
|
+
covers: [
|
|
64
|
+
{
|
|
65
|
+
type: "post.awaiting_review",
|
|
66
|
+
reasons: ["moderator"]
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
type: "space.join_requested",
|
|
70
|
+
reasons: ["moderator"]
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
type: "content.flagged",
|
|
74
|
+
reasons: ["moderator"]
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
type: "message.flagged",
|
|
78
|
+
reasons: ["staff"]
|
|
79
|
+
}
|
|
80
|
+
],
|
|
81
|
+
channels: {
|
|
82
|
+
inApp: on,
|
|
83
|
+
email: on,
|
|
84
|
+
push: on
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
key: "mentions",
|
|
89
|
+
covers: [{
|
|
90
|
+
type: "mention",
|
|
91
|
+
reasons: ["mentioned"]
|
|
92
|
+
}],
|
|
93
|
+
channels: {
|
|
94
|
+
inApp: on,
|
|
95
|
+
email: on,
|
|
96
|
+
push: on
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
key: "comments_on_my_posts",
|
|
101
|
+
covers: [{
|
|
102
|
+
type: "comment.created",
|
|
103
|
+
reasons: ["post_author"]
|
|
104
|
+
}],
|
|
105
|
+
channels: {
|
|
106
|
+
inApp: on,
|
|
107
|
+
email: on,
|
|
108
|
+
push: on
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
key: "replies_to_my_comments",
|
|
113
|
+
covers: [{
|
|
114
|
+
type: "comment.created",
|
|
115
|
+
reasons: ["comment_author"]
|
|
116
|
+
}],
|
|
117
|
+
channels: {
|
|
118
|
+
inApp: on,
|
|
119
|
+
email: on,
|
|
120
|
+
push: on
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
key: "followed_posts",
|
|
125
|
+
covers: [{
|
|
126
|
+
type: "comment.created",
|
|
127
|
+
reasons: ["follower", "thread_participant"]
|
|
128
|
+
}],
|
|
129
|
+
channels: {
|
|
130
|
+
inApp: on,
|
|
131
|
+
email: off,
|
|
132
|
+
push: on
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
key: "messages",
|
|
137
|
+
covers: [
|
|
138
|
+
{
|
|
139
|
+
type: "message.sent",
|
|
140
|
+
reasons: ["participant"]
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
type: "chat.request",
|
|
144
|
+
reasons: ["participant"]
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
type: "message.reacted",
|
|
148
|
+
reasons: ["message_author"]
|
|
149
|
+
}
|
|
150
|
+
],
|
|
151
|
+
channels: {
|
|
152
|
+
inApp: on,
|
|
153
|
+
email: off,
|
|
154
|
+
push: on
|
|
155
|
+
}
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
key: "likes_on_my_posts",
|
|
159
|
+
covers: [{
|
|
160
|
+
type: "post.reacted",
|
|
161
|
+
reasons: ["post_author"]
|
|
162
|
+
}],
|
|
163
|
+
channels: {
|
|
164
|
+
inApp: on,
|
|
165
|
+
email: off,
|
|
166
|
+
push: off
|
|
167
|
+
}
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
key: "likes_on_my_comments",
|
|
171
|
+
covers: [{
|
|
172
|
+
type: "comment.reacted",
|
|
173
|
+
reasons: ["comment_author"]
|
|
174
|
+
}],
|
|
175
|
+
channels: {
|
|
176
|
+
inApp: on,
|
|
177
|
+
email: off,
|
|
178
|
+
push: off
|
|
179
|
+
}
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
key: "new_posts",
|
|
183
|
+
perSpace: true,
|
|
184
|
+
covers: [{
|
|
185
|
+
type: "post.published",
|
|
186
|
+
reasons: ["space_member"]
|
|
187
|
+
}],
|
|
188
|
+
channels: {
|
|
189
|
+
inApp: off,
|
|
190
|
+
email: off,
|
|
191
|
+
push: off
|
|
192
|
+
}
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
key: "digest",
|
|
196
|
+
covers: [{
|
|
197
|
+
type: "digest",
|
|
198
|
+
reasons: ["community_member"]
|
|
199
|
+
}],
|
|
200
|
+
channels: { email: on }
|
|
201
|
+
}
|
|
202
|
+
];
|
|
203
|
+
const DEFAULT_ORG_CATEGORIES = [
|
|
204
|
+
{
|
|
205
|
+
key: "about_you",
|
|
206
|
+
covers: [{
|
|
207
|
+
type: "moderator.assigned",
|
|
208
|
+
reasons: ["subject"]
|
|
209
|
+
}, {
|
|
210
|
+
type: "comment.removed",
|
|
211
|
+
reasons: ["subject"]
|
|
212
|
+
}],
|
|
213
|
+
channels: {
|
|
214
|
+
inApp: lockedOn,
|
|
215
|
+
email: on,
|
|
216
|
+
push: on
|
|
217
|
+
}
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
key: "review",
|
|
221
|
+
covers: [{
|
|
222
|
+
type: "content.flagged",
|
|
223
|
+
reasons: ["staff"]
|
|
224
|
+
}],
|
|
225
|
+
channels: {
|
|
226
|
+
inApp: on,
|
|
227
|
+
email: on,
|
|
228
|
+
push: on
|
|
229
|
+
}
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
key: "mentions",
|
|
233
|
+
covers: [{
|
|
234
|
+
type: "mention",
|
|
235
|
+
reasons: ["mentioned"]
|
|
236
|
+
}],
|
|
237
|
+
channels: {
|
|
238
|
+
inApp: on,
|
|
239
|
+
email: on,
|
|
240
|
+
push: on
|
|
241
|
+
}
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
key: "replies_to_my_comments",
|
|
245
|
+
covers: [{
|
|
246
|
+
type: "comment.created",
|
|
247
|
+
reasons: ["comment_author"]
|
|
248
|
+
}],
|
|
249
|
+
channels: {
|
|
250
|
+
inApp: on,
|
|
251
|
+
email: on,
|
|
252
|
+
push: on
|
|
253
|
+
}
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
key: "followed_threads",
|
|
257
|
+
covers: [{
|
|
258
|
+
type: "comment.created",
|
|
259
|
+
reasons: ["thread_participant"]
|
|
260
|
+
}],
|
|
261
|
+
channels: {
|
|
262
|
+
inApp: on,
|
|
263
|
+
email: off,
|
|
264
|
+
push: on
|
|
265
|
+
}
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
key: "likes_on_my_comments",
|
|
269
|
+
covers: [{
|
|
270
|
+
type: "comment.reacted",
|
|
271
|
+
reasons: ["comment_author"]
|
|
272
|
+
}],
|
|
273
|
+
channels: {
|
|
274
|
+
inApp: on,
|
|
275
|
+
email: off,
|
|
276
|
+
push: off
|
|
277
|
+
}
|
|
278
|
+
},
|
|
279
|
+
{
|
|
280
|
+
key: "access",
|
|
281
|
+
covers: [
|
|
282
|
+
{
|
|
283
|
+
type: "access.granted",
|
|
284
|
+
reasons: ["subject"]
|
|
285
|
+
},
|
|
286
|
+
{
|
|
287
|
+
type: "access.revoked",
|
|
288
|
+
reasons: ["subject"]
|
|
289
|
+
},
|
|
290
|
+
{
|
|
291
|
+
type: "community.membership_ended",
|
|
292
|
+
reasons: ["subject"]
|
|
293
|
+
}
|
|
294
|
+
],
|
|
295
|
+
channels: {
|
|
296
|
+
inApp: on,
|
|
297
|
+
email: lockedOn
|
|
298
|
+
}
|
|
299
|
+
},
|
|
300
|
+
{
|
|
301
|
+
key: "course_content",
|
|
302
|
+
covers: [{
|
|
303
|
+
type: "course.activity_added",
|
|
304
|
+
reasons: ["course_member"]
|
|
305
|
+
}],
|
|
306
|
+
channels: {
|
|
307
|
+
inApp: on,
|
|
308
|
+
email: off,
|
|
309
|
+
push: off
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
];
|
|
313
|
+
//#endregion
|
|
314
|
+
export { DEFAULT_COMMUNITY_CATEGORIES, DEFAULT_ORG_CATEGORIES };
|
|
315
|
+
|
|
316
|
+
//# sourceMappingURL=defaults.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaults.js","names":[],"sources":["../../../src/automations/notifications/defaults.ts"],"sourcesContent":["import type { NotificationCategory } from '../../types/index.js';\n\nconst on = { default: true, locked: false };\nconst off = { default: false, locked: false };\nconst lockedOn = { default: true, locked: true };\n\nexport const DEFAULT_COMMUNITY_CATEGORIES: NotificationCategory[] = [\n {\n key: 'about_you',\n covers: [\n { type: 'post.approved', reasons: ['subject'] },\n { type: 'post.removed', reasons: ['subject'] },\n { type: 'comment.removed', reasons: ['subject'] },\n { type: 'space.invited', reasons: ['subject'] },\n { type: 'space.request_approved', reasons: ['subject'] },\n { type: 'space.request_declined', reasons: ['subject'] },\n { type: 'community.welcome', reasons: ['subject'] },\n { type: 'community.ending_soon', reasons: ['subject'] },\n { type: 'chat.added', reasons: ['subject'] },\n ],\n channels: { inApp: lockedOn, email: on, push: on },\n },\n {\n key: 'review',\n covers: [\n { type: 'post.awaiting_review', reasons: ['moderator'] },\n { type: 'space.join_requested', reasons: ['moderator'] },\n { type: 'content.flagged', reasons: ['moderator'] },\n { type: 'message.flagged', reasons: ['staff'] },\n ],\n channels: { inApp: on, email: on, push: on },\n },\n {\n key: 'mentions',\n covers: [{ type: 'mention', reasons: ['mentioned'] }],\n channels: { inApp: on, email: on, push: on },\n },\n {\n key: 'comments_on_my_posts',\n covers: [{ type: 'comment.created', reasons: ['post_author'] }],\n channels: { inApp: on, email: on, push: on },\n },\n {\n key: 'replies_to_my_comments',\n covers: [{ type: 'comment.created', reasons: ['comment_author'] }],\n channels: { inApp: on, email: on, push: on },\n },\n {\n key: 'followed_posts',\n covers: [{ type: 'comment.created', reasons: ['follower', 'thread_participant'] }],\n channels: { inApp: on, email: off, push: on },\n },\n {\n key: 'messages',\n covers: [\n { type: 'message.sent', reasons: ['participant'] },\n { type: 'chat.request', reasons: ['participant'] },\n { type: 'message.reacted', reasons: ['message_author'] },\n ],\n channels: { inApp: on, email: off, push: on },\n },\n {\n key: 'likes_on_my_posts',\n covers: [{ type: 'post.reacted', reasons: ['post_author'] }],\n channels: { inApp: on, email: off, push: off },\n },\n {\n key: 'likes_on_my_comments',\n covers: [{ type: 'comment.reacted', reasons: ['comment_author'] }],\n channels: { inApp: on, email: off, push: off },\n },\n {\n key: 'new_posts',\n perSpace: true,\n covers: [{ type: 'post.published', reasons: ['space_member'] }],\n channels: { inApp: off, email: off, push: off },\n },\n {\n key: 'digest',\n covers: [{ type: 'digest', reasons: ['community_member'] }],\n channels: { email: on },\n },\n];\n\nexport const DEFAULT_ORG_CATEGORIES: NotificationCategory[] = [\n {\n key: 'about_you',\n covers: [\n { type: 'moderator.assigned', reasons: ['subject'] },\n { type: 'comment.removed', reasons: ['subject'] },\n ],\n channels: { inApp: lockedOn, email: on, push: on },\n },\n {\n key: 'review',\n covers: [{ type: 'content.flagged', reasons: ['staff'] }],\n channels: { inApp: on, email: on, push: on },\n },\n {\n key: 'mentions',\n covers: [{ type: 'mention', reasons: ['mentioned'] }],\n channels: { inApp: on, email: on, push: on },\n },\n {\n key: 'replies_to_my_comments',\n covers: [{ type: 'comment.created', reasons: ['comment_author'] }],\n channels: { inApp: on, email: on, push: on },\n },\n {\n key: 'followed_threads',\n covers: [{ type: 'comment.created', reasons: ['thread_participant'] }],\n channels: { inApp: on, email: off, push: on },\n },\n {\n key: 'likes_on_my_comments',\n covers: [{ type: 'comment.reacted', reasons: ['comment_author'] }],\n channels: { inApp: on, email: off, push: off },\n },\n {\n key: 'access',\n covers: [\n { type: 'access.granted', reasons: ['subject'] },\n { type: 'access.revoked', reasons: ['subject'] },\n { type: 'community.membership_ended', reasons: ['subject'] },\n ],\n channels: { inApp: on, email: lockedOn },\n },\n {\n key: 'course_content',\n covers: [{ type: 'course.activity_added', reasons: ['course_member'] }],\n channels: { inApp: on, email: off, push: off },\n },\n];\n"],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Logger } from "../../types/ports.js";
|
|
2
|
+
import { DeliveryDispatch } from "../../types/automations.js";
|
|
3
|
+
import "../../types/index.js";
|
|
4
|
+
import { ChannelRegistry } from "../../shared/ports.js";
|
|
5
|
+
import { DevicesService } from "../../identity/ports.js";
|
|
6
|
+
import "../../identity/index.js";
|
|
7
|
+
import { NotificationsRepository } from "../ports.js";
|
|
8
|
+
//#region src/automations/notifications/delivery.d.ts
|
|
9
|
+
declare const CHANNEL_NOT_CONFIGURED = "channel not configured";
|
|
10
|
+
declare const NO_ADDRESS = "no address";
|
|
11
|
+
declare const NOT_ACCEPTED = "not accepted";
|
|
12
|
+
type NotificationDeliveryParams = {
|
|
13
|
+
repo: Pick<NotificationsRepository, 'findDelivery' | 'markSent' | 'recordError' | 'markFailed'>;
|
|
14
|
+
channels: Pick<ChannelRegistry, 'get'>;
|
|
15
|
+
devices: Pick<DevicesService, 'removeDead'>;
|
|
16
|
+
logger?: Logger;
|
|
17
|
+
};
|
|
18
|
+
declare class NotificationDelivery {
|
|
19
|
+
private readonly repo;
|
|
20
|
+
private readonly channels;
|
|
21
|
+
private readonly devices;
|
|
22
|
+
private readonly logger;
|
|
23
|
+
constructor(params: NotificationDeliveryParams);
|
|
24
|
+
run(d: DeliveryDispatch, lastAttempt: boolean): Promise<void>;
|
|
25
|
+
}
|
|
26
|
+
//#endregion
|
|
27
|
+
export { CHANNEL_NOT_CONFIGURED, NOT_ACCEPTED, NO_ADDRESS, NotificationDelivery, NotificationDeliveryParams };
|
|
28
|
+
//# sourceMappingURL=delivery.d.ts.map
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { noopLogger } from "../../shared/logger.js";
|
|
2
|
+
//#region src/automations/notifications/delivery.ts
|
|
3
|
+
const CHANNEL_NOT_CONFIGURED = "channel not configured";
|
|
4
|
+
const NO_ADDRESS = "no address";
|
|
5
|
+
const NOT_ACCEPTED = "not accepted";
|
|
6
|
+
function messageOf(err) {
|
|
7
|
+
return err instanceof Error ? err.message : String(err);
|
|
8
|
+
}
|
|
9
|
+
var NotificationDelivery = class {
|
|
10
|
+
repo;
|
|
11
|
+
channels;
|
|
12
|
+
devices;
|
|
13
|
+
logger;
|
|
14
|
+
constructor(params) {
|
|
15
|
+
this.repo = params.repo;
|
|
16
|
+
this.channels = params.channels;
|
|
17
|
+
this.devices = params.devices;
|
|
18
|
+
this.logger = params.logger ?? noopLogger;
|
|
19
|
+
}
|
|
20
|
+
async run(d, lastAttempt) {
|
|
21
|
+
const found = await this.repo.findDelivery(d.orgId, d.deliveryId);
|
|
22
|
+
if (!found || found.delivery.status !== "pending") {
|
|
23
|
+
this.logger.debug("notification delivery skipped", {
|
|
24
|
+
orgId: d.orgId,
|
|
25
|
+
deliveryId: d.deliveryId,
|
|
26
|
+
status: found?.delivery.status ?? null
|
|
27
|
+
});
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const { delivery, notification } = found;
|
|
31
|
+
const log = {
|
|
32
|
+
orgId: d.orgId,
|
|
33
|
+
deliveryId: d.deliveryId,
|
|
34
|
+
notificationId: notification.id,
|
|
35
|
+
channel: delivery.channel,
|
|
36
|
+
type: notification.type
|
|
37
|
+
};
|
|
38
|
+
const channel = this.channels.get(delivery.channel);
|
|
39
|
+
if (!channel) {
|
|
40
|
+
await this.repo.markFailed(d.orgId, d.deliveryId, CHANNEL_NOT_CONFIGURED);
|
|
41
|
+
this.logger.warn("notification delivery failed: channel not configured", log);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
let to;
|
|
45
|
+
let result;
|
|
46
|
+
try {
|
|
47
|
+
to = await channel.recipient(d.orgId, notification.userId);
|
|
48
|
+
if (!to) {
|
|
49
|
+
await this.repo.markFailed(d.orgId, d.deliveryId, NO_ADDRESS);
|
|
50
|
+
this.logger.info("notification delivery failed: no address", log);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
result = await channel.deliver(notification, to);
|
|
54
|
+
} catch (err) {
|
|
55
|
+
const error = messageOf(err);
|
|
56
|
+
if (lastAttempt) {
|
|
57
|
+
await this.repo.markFailed(d.orgId, d.deliveryId, error);
|
|
58
|
+
this.logger.warn("notification delivery failed on its last attempt", {
|
|
59
|
+
...log,
|
|
60
|
+
err
|
|
61
|
+
});
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
await this.repo.recordError(d.orgId, d.deliveryId, error);
|
|
65
|
+
this.logger.warn("notification delivery attempt failed", {
|
|
66
|
+
...log,
|
|
67
|
+
err
|
|
68
|
+
});
|
|
69
|
+
throw err;
|
|
70
|
+
}
|
|
71
|
+
if (result.deadDeviceIds.length > 0) await this.devices.removeDead(d.orgId, result.deadDeviceIds);
|
|
72
|
+
if (!result.accepted) {
|
|
73
|
+
const error = result.error ?? "not accepted";
|
|
74
|
+
await this.repo.markFailed(d.orgId, d.deliveryId, error);
|
|
75
|
+
this.logger.info("notification delivery failed: not accepted", {
|
|
76
|
+
...log,
|
|
77
|
+
error
|
|
78
|
+
});
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
await this.repo.markSent(d.orgId, d.deliveryId, /* @__PURE__ */ new Date());
|
|
82
|
+
this.logger.info("notification delivered", log);
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
//#endregion
|
|
86
|
+
export { CHANNEL_NOT_CONFIGURED, NOT_ACCEPTED, NO_ADDRESS, NotificationDelivery };
|
|
87
|
+
|
|
88
|
+
//# sourceMappingURL=delivery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delivery.js","names":[],"sources":["../../../src/automations/notifications/delivery.ts"],"sourcesContent":["import type { DevicesService } from '../../identity/index.js';\nimport { noopLogger } from '../../shared/logger.js';\nimport type { ChannelRegistry, Logger } from '../../shared/ports.js';\nimport type { ChannelRecipient, DeliveryDispatch, DeliveryResult } from '../../types/index.js';\nimport type { NotificationsRepository } from '../ports.js';\n\nexport const CHANNEL_NOT_CONFIGURED = 'channel not configured';\nexport const NO_ADDRESS = 'no address';\nexport const NOT_ACCEPTED = 'not accepted';\n\nexport type NotificationDeliveryParams = {\n repo: Pick<NotificationsRepository, 'findDelivery' | 'markSent' | 'recordError' | 'markFailed'>;\n channels: Pick<ChannelRegistry, 'get'>;\n devices: Pick<DevicesService, 'removeDead'>;\n logger?: Logger;\n};\n\nfunction messageOf(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n\nexport class NotificationDelivery {\n private readonly repo: NotificationDeliveryParams['repo'];\n private readonly channels: Pick<ChannelRegistry, 'get'>;\n private readonly devices: Pick<DevicesService, 'removeDead'>;\n private readonly logger: Logger;\n\n constructor(params: NotificationDeliveryParams) {\n this.repo = params.repo;\n this.channels = params.channels;\n this.devices = params.devices;\n this.logger = params.logger ?? noopLogger;\n }\n\n async run(d: DeliveryDispatch, lastAttempt: boolean): Promise<void> {\n const found = await this.repo.findDelivery(d.orgId, d.deliveryId);\n if (!found || found.delivery.status !== 'pending') {\n this.logger.debug('notification delivery skipped', {\n orgId: d.orgId,\n deliveryId: d.deliveryId,\n status: found?.delivery.status ?? null,\n });\n return;\n }\n const { delivery, notification } = found;\n const log = {\n orgId: d.orgId,\n deliveryId: d.deliveryId,\n notificationId: notification.id,\n channel: delivery.channel,\n type: notification.type,\n };\n const channel = this.channels.get(delivery.channel);\n if (!channel) {\n await this.repo.markFailed(d.orgId, d.deliveryId, CHANNEL_NOT_CONFIGURED);\n this.logger.warn('notification delivery failed: channel not configured', log);\n return;\n }\n let to: ChannelRecipient | null;\n let result: DeliveryResult;\n try {\n to = await channel.recipient(d.orgId, notification.userId);\n if (!to) {\n await this.repo.markFailed(d.orgId, d.deliveryId, NO_ADDRESS);\n this.logger.info('notification delivery failed: no address', log);\n return;\n }\n result = await channel.deliver(notification, to);\n } catch (err) {\n const error = messageOf(err);\n if (lastAttempt) {\n await this.repo.markFailed(d.orgId, d.deliveryId, error);\n this.logger.warn('notification delivery failed on its last attempt', { ...log, err });\n return;\n }\n await this.repo.recordError(d.orgId, d.deliveryId, error);\n this.logger.warn('notification delivery attempt failed', { ...log, err });\n throw err;\n }\n if (result.deadDeviceIds.length > 0) {\n await this.devices.removeDead(d.orgId, result.deadDeviceIds);\n }\n if (!result.accepted) {\n const error = result.error ?? NOT_ACCEPTED;\n await this.repo.markFailed(d.orgId, d.deliveryId, error);\n this.logger.info('notification delivery failed: not accepted', { ...log, error });\n return;\n }\n await this.repo.markSent(d.orgId, d.deliveryId, new Date());\n this.logger.info('notification delivered', log);\n }\n}\n"],"mappings":";;AAMA,MAAa,yBAAyB;AACtC,MAAa,aAAa;AAC1B,MAAa,eAAe;AAS5B,SAAS,UAAU,KAAsB;CACvC,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AACxD;AAEA,IAAa,uBAAb,MAAkC;CAChC;CACA;CACA;CACA;CAEA,YAAY,QAAoC;EAC9C,KAAK,OAAO,OAAO;EACnB,KAAK,WAAW,OAAO;EACvB,KAAK,UAAU,OAAO;EACtB,KAAK,SAAS,OAAO,UAAU;CACjC;CAEA,MAAM,IAAI,GAAqB,aAAqC;EAClE,MAAM,QAAQ,MAAM,KAAK,KAAK,aAAa,EAAE,OAAO,EAAE,UAAU;EAChE,IAAI,CAAC,SAAS,MAAM,SAAS,WAAW,WAAW;GACjD,KAAK,OAAO,MAAM,iCAAiC;IACjD,OAAO,EAAE;IACT,YAAY,EAAE;IACd,QAAQ,OAAO,SAAS,UAAU;GACpC,CAAC;GACD;EACF;EACA,MAAM,EAAE,UAAU,iBAAiB;EACnC,MAAM,MAAM;GACV,OAAO,EAAE;GACT,YAAY,EAAE;GACd,gBAAgB,aAAa;GAC7B,SAAS,SAAS;GAClB,MAAM,aAAa;EACrB;EACA,MAAM,UAAU,KAAK,SAAS,IAAI,SAAS,OAAO;EAClD,IAAI,CAAC,SAAS;GACZ,MAAM,KAAK,KAAK,WAAW,EAAE,OAAO,EAAE,YAAY,sBAAsB;GACxE,KAAK,OAAO,KAAK,wDAAwD,GAAG;GAC5E;EACF;EACA,IAAI;EACJ,IAAI;EACJ,IAAI;GACF,KAAK,MAAM,QAAQ,UAAU,EAAE,OAAO,aAAa,MAAM;GACzD,IAAI,CAAC,IAAI;IACP,MAAM,KAAK,KAAK,WAAW,EAAE,OAAO,EAAE,YAAY,UAAU;IAC5D,KAAK,OAAO,KAAK,4CAA4C,GAAG;IAChE;GACF;GACA,SAAS,MAAM,QAAQ,QAAQ,cAAc,EAAE;EACjD,SAAS,KAAK;GACZ,MAAM,QAAQ,UAAU,GAAG;GAC3B,IAAI,aAAa;IACf,MAAM,KAAK,KAAK,WAAW,EAAE,OAAO,EAAE,YAAY,KAAK;IACvD,KAAK,OAAO,KAAK,oDAAoD;KAAE,GAAG;KAAK;IAAI,CAAC;IACpF;GACF;GACA,MAAM,KAAK,KAAK,YAAY,EAAE,OAAO,EAAE,YAAY,KAAK;GACxD,KAAK,OAAO,KAAK,wCAAwC;IAAE,GAAG;IAAK;GAAI,CAAC;GACxE,MAAM;EACR;EACA,IAAI,OAAO,cAAc,SAAS,GAChC,MAAM,KAAK,QAAQ,WAAW,EAAE,OAAO,OAAO,aAAa;EAE7D,IAAI,CAAC,OAAO,UAAU;GACpB,MAAM,QAAQ,OAAO,SAAA;GACrB,MAAM,KAAK,KAAK,WAAW,EAAE,OAAO,EAAE,YAAY,KAAK;GACvD,KAAK,OAAO,KAAK,8CAA8C;IAAE,GAAG;IAAK;GAAM,CAAC;GAChF;EACF;EACA,MAAM,KAAK,KAAK,SAAS,EAAE,OAAO,EAAE,4BAAY,IAAI,KAAK,CAAC;EAC1D,KAAK,OAAO,KAAK,0BAA0B,GAAG;CAChD;AACF"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { DomainEvent } from "../../types/shared.js";
|
|
2
|
+
import { Logger } from "../../types/ports.js";
|
|
3
|
+
import { AutomationEngine } from "../../types/automations.js";
|
|
4
|
+
import { RecipientList } from "../../types/notifications.js";
|
|
5
|
+
import "../../types/index.js";
|
|
6
|
+
import { ChannelRegistry, NotificationTypeRegistry } from "../../shared/ports.js";
|
|
7
|
+
import { DevicesService, NotificationSettingsService } from "../../identity/ports.js";
|
|
8
|
+
import "../../identity/index.js";
|
|
9
|
+
import { ChatDebounce, NotificationCategories, NotificationReads, NotificationsRepository, RecipientRule } from "../ports.js";
|
|
10
|
+
//#region src/automations/notifications/processor.d.ts
|
|
11
|
+
declare const IN_APP = "inApp";
|
|
12
|
+
declare const PUSH = "push";
|
|
13
|
+
declare const MESSAGE_SENT = "message.sent";
|
|
14
|
+
declare const DEVICE_WINDOW_MS: number;
|
|
15
|
+
type NotificationProcessorParams = {
|
|
16
|
+
rules: Record<string, RecipientRule>;
|
|
17
|
+
reads: NotificationReads;
|
|
18
|
+
types: Pick<NotificationTypeRegistry, 'get'>;
|
|
19
|
+
channels: Pick<ChannelRegistry, 'list' | 'get'>;
|
|
20
|
+
categories: NotificationCategories;
|
|
21
|
+
settings: Pick<NotificationSettingsService, 'getMany'>;
|
|
22
|
+
devices: Pick<DevicesService, 'withActiveDevices'>;
|
|
23
|
+
repo: Pick<NotificationsRepository, 'insert' | 'pendingDeliveriesForEvent'>;
|
|
24
|
+
engine: Pick<AutomationEngine, 'deliver'>;
|
|
25
|
+
debounce?: ChatDebounce;
|
|
26
|
+
now?: () => Date;
|
|
27
|
+
logger?: Logger;
|
|
28
|
+
};
|
|
29
|
+
declare function chatOf(refs: Pick<RecipientList, 'subject' | 'parent'>): string | null;
|
|
30
|
+
declare class NotificationProcessor {
|
|
31
|
+
private readonly rules;
|
|
32
|
+
private readonly reads;
|
|
33
|
+
private readonly types;
|
|
34
|
+
private readonly channels;
|
|
35
|
+
private readonly categories;
|
|
36
|
+
private readonly settings;
|
|
37
|
+
private readonly devices;
|
|
38
|
+
private readonly repo;
|
|
39
|
+
private readonly engine;
|
|
40
|
+
private readonly debounce;
|
|
41
|
+
private readonly now;
|
|
42
|
+
private readonly logger;
|
|
43
|
+
constructor(params: NotificationProcessorParams);
|
|
44
|
+
process(event: DomainEvent): Promise<void>;
|
|
45
|
+
file(orgId: string, sourceEventId: string, lists: RecipientList[], options: {
|
|
46
|
+
occurredAt: Date;
|
|
47
|
+
debounce: boolean;
|
|
48
|
+
}): Promise<void>;
|
|
49
|
+
private isValid;
|
|
50
|
+
private groups;
|
|
51
|
+
private categoriesOf;
|
|
52
|
+
private expand;
|
|
53
|
+
private collect;
|
|
54
|
+
private match;
|
|
55
|
+
private peopleWithDevice;
|
|
56
|
+
private fileOne;
|
|
57
|
+
private filed;
|
|
58
|
+
private coveredPairs;
|
|
59
|
+
private mentionsInChats;
|
|
60
|
+
private dispatch;
|
|
61
|
+
}
|
|
62
|
+
//#endregion
|
|
63
|
+
export { DEVICE_WINDOW_MS, IN_APP, MESSAGE_SENT, NotificationProcessor, NotificationProcessorParams, PUSH, chatOf };
|
|
64
|
+
//# sourceMappingURL=processor.d.ts.map
|