@things-factory/notification 8.0.0-beta.0 → 8.0.0-beta.2
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/package.json +8 -8
- package/client/actions/notification-fcm.ts +0 -148
- package/client/bootstrap.ts +0 -135
- package/client/index.ts +0 -6
- package/client/pages/notification/notification-list-page.ts +0 -258
- package/client/pages/notification-rule/notification-rule-importer.ts +0 -87
- package/client/pages/notification-rule/notification-rule-list-page.ts +0 -386
- package/client/reducers/notification.ts +0 -27
- package/client/route.ts +0 -10
- package/client/tsconfig.json +0 -13
- package/client/viewparts/notification-badge.ts +0 -54
- package/client/viewparts/notification-item.ts +0 -246
- package/client/viewparts/notification-list.ts +0 -160
- package/client/viewparts/notification-sender.ts +0 -142
- package/client/viewparts/notification-setting-let.ts +0 -222
- package/docs/images/config-app-1.png +0 -0
- package/docs/images/config-app-2.png +0 -0
- package/docs/images/config-server-key.png +0 -0
- package/docs/images/config-service-account.png +0 -0
- package/docs/images/config-vapidkey-1.png +0 -0
- package/docs/images/config-vapidkey-2-get-public-key.png +0 -0
- package/docs/images/config-vapidkey-3-get-private-key.png +0 -0
- package/docs/images/element-notification-badge.png +0 -0
- package/docs/images/element-notification-list.png +0 -0
- package/docs/images/element-notification-setting-let.png +0 -0
- package/docs/images/push-test-on-chrome-1.png +0 -0
- package/docs/images/push-test-on-chrome-2.png +0 -0
- package/docs/images/push-test-on-firebase-1.png +0 -0
- package/docs/images/push-test-on-firebase-2.png +0 -0
- package/docs/images/push-test-on-firebase-3.png +0 -0
- package/docs/images/push-test-on-firebase-4.png +0 -0
- package/server/controllers/fcm.ts +0 -214
- package/server/controllers/index.ts +0 -1
- package/server/index.ts +0 -5
- package/server/middlewares/index.ts +0 -5
- package/server/middlewares/notification-middleware.ts +0 -73
- package/server/routers/notification-router.ts +0 -67
- package/server/routes.ts +0 -11
- package/server/service/index.ts +0 -42
- package/server/service/notification/directive-notification.ts +0 -71
- package/server/service/notification/index.ts +0 -14
- package/server/service/notification/notification-mutation.ts +0 -119
- package/server/service/notification/notification-query.ts +0 -76
- package/server/service/notification/notification-subscription.ts +0 -44
- package/server/service/notification/notification-type.ts +0 -55
- package/server/service/notification/notification.ts +0 -105
- package/server/service/notification-rule/event-subscriber.ts +0 -20
- package/server/service/notification-rule/index.ts +0 -9
- package/server/service/notification-rule/notification-rule-history.ts +0 -136
- package/server/service/notification-rule/notification-rule-mutation.ts +0 -203
- package/server/service/notification-rule/notification-rule-query.ts +0 -65
- package/server/service/notification-rule/notification-rule-type.ts +0 -71
- package/server/service/notification-rule/notification-rule.ts +0 -125
- package/server/tsconfig.json +0 -9
|
@@ -1,222 +0,0 @@
|
|
|
1
|
-
import '@material/web/icon/icon.js'
|
|
2
|
-
import '@material/web/switch/switch.js'
|
|
3
|
-
import '@operato/i18n/ox-i18n.js'
|
|
4
|
-
import '@things-factory/setting-base'
|
|
5
|
-
import './notification-sender'
|
|
6
|
-
|
|
7
|
-
import Clipboard from 'clipboard'
|
|
8
|
-
import { css, html, LitElement } from 'lit'
|
|
9
|
-
import { customElement, property } from 'lit/decorators.js'
|
|
10
|
-
|
|
11
|
-
import { notify, openPopup } from '@operato/layout'
|
|
12
|
-
import { i18next, localize } from '@operato/i18n'
|
|
13
|
-
|
|
14
|
-
import { getSubscriptionToken, isSupportingMessaging, subscribe, unsubscribe } from '../actions/notification-fcm'
|
|
15
|
-
|
|
16
|
-
@customElement('notification-setting-let')
|
|
17
|
-
export class NotificationSettingLet extends localize(i18next)(LitElement) {
|
|
18
|
-
static styles = [
|
|
19
|
-
css`
|
|
20
|
-
div[onoff] {
|
|
21
|
-
display: flex;
|
|
22
|
-
align-items: center;
|
|
23
|
-
border-bottom: var(--border-dim-color);
|
|
24
|
-
margin-bottom: var(--spacing-medium);
|
|
25
|
-
padding-bottom: var(--spacing-medium);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
div[info] {
|
|
29
|
-
display: flex;
|
|
30
|
-
flex-direction: column;
|
|
31
|
-
position: relative;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
label {
|
|
35
|
-
display: flex;
|
|
36
|
-
gap: 10px;
|
|
37
|
-
align-items: center;
|
|
38
|
-
|
|
39
|
-
font: var(--label-font);
|
|
40
|
-
color: var(--md-sys-color-on-surface);
|
|
41
|
-
text-transform: var(--label-text-transform);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
[test] {
|
|
45
|
-
margin-left: auto;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
input {
|
|
49
|
-
border: var(--border-dim-color);
|
|
50
|
-
border-radius: var(--border-radius);
|
|
51
|
-
margin: var(--input-margin);
|
|
52
|
-
padding: var(--input-padding);
|
|
53
|
-
font: var(--input-font);
|
|
54
|
-
|
|
55
|
-
flex: 1;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
[button-in-field] {
|
|
59
|
-
--md-icon-size: 18px;
|
|
60
|
-
position: absolute;
|
|
61
|
-
top: 24px;
|
|
62
|
-
right: 4px;
|
|
63
|
-
width: 30px;
|
|
64
|
-
padding: 2px;
|
|
65
|
-
border-radius: var(--border-radius, 5px);
|
|
66
|
-
color: var(--md-sys-color-on-secondary, #fff);
|
|
67
|
-
background-color: var(--md-sys-color-secondary, #394e64);
|
|
68
|
-
}
|
|
69
|
-
`
|
|
70
|
-
]
|
|
71
|
-
|
|
72
|
-
@property({ type: Object }) subscription?: any
|
|
73
|
-
@property({ type: Boolean }) supported?: boolean
|
|
74
|
-
|
|
75
|
-
clipboard: any
|
|
76
|
-
|
|
77
|
-
render() {
|
|
78
|
-
const supported = !!this.supported
|
|
79
|
-
|
|
80
|
-
return html`
|
|
81
|
-
<setting-let>
|
|
82
|
-
<ox-i18n slot="title" msgid="title.notification subscription"></ox-i18n>
|
|
83
|
-
|
|
84
|
-
${supported
|
|
85
|
-
? html`
|
|
86
|
-
<div slot="content" onoff>
|
|
87
|
-
<label>
|
|
88
|
-
<md-switch
|
|
89
|
-
label="allow message"
|
|
90
|
-
?selected=${!!this.subscription}
|
|
91
|
-
@click=${e => this.onClickSwitch(e)}
|
|
92
|
-
></md-switch>
|
|
93
|
-
${String(i18next.t('label.allow push message'))}
|
|
94
|
-
</label>
|
|
95
|
-
<md-outlined-button test @click=${e => this.ontest()}
|
|
96
|
-
>${String(i18next.t('button.push message test'))}</md-outlined-button
|
|
97
|
-
>
|
|
98
|
-
</div>
|
|
99
|
-
|
|
100
|
-
<div slot="content" info>
|
|
101
|
-
<label for="subscription-token"><ox-i18n msgid="label.subscription token"></ox-i18n></label>
|
|
102
|
-
<input
|
|
103
|
-
id="subscription-token"
|
|
104
|
-
type="text"
|
|
105
|
-
name="subscription-token"
|
|
106
|
-
.value=${this.subscription || ''}
|
|
107
|
-
readonly
|
|
108
|
-
/>
|
|
109
|
-
<md-icon button-in-field clipboard-copy @click=${e => e.preventDefault()}>content_copy</md-icon>
|
|
110
|
-
</div>
|
|
111
|
-
`
|
|
112
|
-
: html` <div slot="content">${i18next.t('text.push notification is not supported in your browser')}</div>`}
|
|
113
|
-
</setting-let>
|
|
114
|
-
`
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
updated(changes) {
|
|
118
|
-
if (changes.has('supported') && this.supported) {
|
|
119
|
-
const copybuttons = this.renderRoot.querySelectorAll('[clipboard-copy]')
|
|
120
|
-
|
|
121
|
-
this.clipboard = new Clipboard(copybuttons, {
|
|
122
|
-
target: trigger => trigger.parentElement!.querySelector('input')!
|
|
123
|
-
})
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
async connectedCallback() {
|
|
128
|
-
super.connectedCallback()
|
|
129
|
-
|
|
130
|
-
if (!('Notification' in window)) {
|
|
131
|
-
return
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
this.supported = await isSupportingMessaging()
|
|
135
|
-
this.subscription = await getSubscriptionToken()
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
async onClickSwitch(e) {
|
|
139
|
-
const target = e.target
|
|
140
|
-
const on = target.selected
|
|
141
|
-
|
|
142
|
-
if (!('Notification' in window)) {
|
|
143
|
-
notify({
|
|
144
|
-
level: 'error',
|
|
145
|
-
message: i18next.t('This browser does not support desktop notification')
|
|
146
|
-
})
|
|
147
|
-
|
|
148
|
-
return
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
try {
|
|
152
|
-
if (Notification.permission !== 'granted') {
|
|
153
|
-
const permission = await Notification.requestPermission()
|
|
154
|
-
if (permission === 'denied') {
|
|
155
|
-
notify({
|
|
156
|
-
level: 'error',
|
|
157
|
-
message: i18next.t('text.web push notification unblock guide')
|
|
158
|
-
})
|
|
159
|
-
}
|
|
160
|
-
return
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
if (Notification.permission === 'granted') {
|
|
164
|
-
if (on) {
|
|
165
|
-
const subscription = await getSubscriptionToken()
|
|
166
|
-
|
|
167
|
-
if (subscription) {
|
|
168
|
-
this.subscription = subscription
|
|
169
|
-
notify({
|
|
170
|
-
level: 'info',
|
|
171
|
-
message: i18next.t('text.notification subscribed already')
|
|
172
|
-
})
|
|
173
|
-
} else {
|
|
174
|
-
this.subscription = await subscribe()
|
|
175
|
-
|
|
176
|
-
this.subscription &&
|
|
177
|
-
notify({
|
|
178
|
-
level: 'info',
|
|
179
|
-
message: i18next.t('text.notification subscribe started')
|
|
180
|
-
})
|
|
181
|
-
}
|
|
182
|
-
} else {
|
|
183
|
-
if (this.subscription) {
|
|
184
|
-
await unsubscribe()
|
|
185
|
-
|
|
186
|
-
this.subscription = await getSubscriptionToken()
|
|
187
|
-
|
|
188
|
-
notify({
|
|
189
|
-
level: 'info',
|
|
190
|
-
message: i18next.t('text.notification unsubscribed')
|
|
191
|
-
})
|
|
192
|
-
} else {
|
|
193
|
-
notify({
|
|
194
|
-
level: 'info',
|
|
195
|
-
message: i18next.t('text.notification unsubscribed already')
|
|
196
|
-
})
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
} else {
|
|
200
|
-
notify({
|
|
201
|
-
level: 'error',
|
|
202
|
-
message: i18next.t('text.notification subscribing failed')
|
|
203
|
-
})
|
|
204
|
-
}
|
|
205
|
-
} catch (err) {
|
|
206
|
-
notify({
|
|
207
|
-
level: 'error',
|
|
208
|
-
message: String(err)
|
|
209
|
-
})
|
|
210
|
-
} finally {
|
|
211
|
-
target.checked = !!this.subscription
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
ontest() {
|
|
216
|
-
openPopup(html` <notification-sender></notification-sender> `, {
|
|
217
|
-
backdrop: true,
|
|
218
|
-
size: 'large',
|
|
219
|
-
title: i18next.t('title.notification-sender')
|
|
220
|
-
})
|
|
221
|
-
}
|
|
222
|
-
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,214 +0,0 @@
|
|
|
1
|
-
import fetch from 'node-fetch'
|
|
2
|
-
|
|
3
|
-
import { config, logger } from '@things-factory/env'
|
|
4
|
-
|
|
5
|
-
import { initializeApp, cert } from 'firebase-admin/app'
|
|
6
|
-
import { getMessaging } from 'firebase-admin/messaging'
|
|
7
|
-
|
|
8
|
-
const notificationConfig = config.get('notification') || {}
|
|
9
|
-
const { fcm, vapidKey } = notificationConfig
|
|
10
|
-
const { serviceAccount, appConfig, serverKey } = fcm || {}
|
|
11
|
-
const { publicKey } = vapidKey || {}
|
|
12
|
-
|
|
13
|
-
var messaging
|
|
14
|
-
|
|
15
|
-
if (serviceAccount) {
|
|
16
|
-
try {
|
|
17
|
-
const app = initializeApp({
|
|
18
|
-
credential: cert(serviceAccount)
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
messaging = getMessaging(app)
|
|
22
|
-
} catch (err) {
|
|
23
|
-
logger.error('incorrect notification configuration')
|
|
24
|
-
logger.error(err)
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export function getConfig() {
|
|
29
|
-
return messaging
|
|
30
|
-
? {
|
|
31
|
-
appConfig,
|
|
32
|
-
vapidPublicKey: publicKey
|
|
33
|
-
}
|
|
34
|
-
: {}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* sendNotification
|
|
39
|
-
*
|
|
40
|
-
* @param receiver user.id who will receive notification
|
|
41
|
-
* @param message message object to be sent
|
|
42
|
-
*/
|
|
43
|
-
export async function sendNotification({ receivers, message }) {
|
|
44
|
-
if (!messaging) {
|
|
45
|
-
return
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
notify({
|
|
49
|
-
receivers,
|
|
50
|
-
...message
|
|
51
|
-
})
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export async function register(user, { subscription }) {
|
|
55
|
-
if (!messaging || !subscription || !user) {
|
|
56
|
-
return false
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
try {
|
|
60
|
-
var notification_key = await getDeviceGroup(user.id)
|
|
61
|
-
|
|
62
|
-
if (!notification_key) {
|
|
63
|
-
await postDeviceGroup({
|
|
64
|
-
operation: 'create',
|
|
65
|
-
notification_key_name: user.id,
|
|
66
|
-
registration_ids: [subscription]
|
|
67
|
-
})
|
|
68
|
-
} else {
|
|
69
|
-
await postDeviceGroup({
|
|
70
|
-
operation: 'add',
|
|
71
|
-
notification_key_name: user.id,
|
|
72
|
-
notification_key,
|
|
73
|
-
registration_ids: [subscription]
|
|
74
|
-
})
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
return true
|
|
78
|
-
} catch (err) {
|
|
79
|
-
return
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
export async function unregister(user, { subscription }) {
|
|
84
|
-
if (!messaging || !subscription || !user) {
|
|
85
|
-
return false
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
try {
|
|
89
|
-
var notification_key = await getDeviceGroup(user.id)
|
|
90
|
-
|
|
91
|
-
if (notification_key) {
|
|
92
|
-
await postDeviceGroup({
|
|
93
|
-
operation: 'remove',
|
|
94
|
-
notification_key_name: user.id,
|
|
95
|
-
notification_key,
|
|
96
|
-
registration_ids: [subscription]
|
|
97
|
-
})
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
return true
|
|
101
|
-
} catch (err) {
|
|
102
|
-
return
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
export async function notify({ receivers, privileges, tokens, topic, title, body, data, image, actions }) {
|
|
107
|
-
if (!messaging) {
|
|
108
|
-
return
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// Caution: non-string attributes are not allowed in FCM payload validation
|
|
112
|
-
var notification = {
|
|
113
|
-
title: title || '',
|
|
114
|
-
body: body || '',
|
|
115
|
-
image: image || ''
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
if (tokens && tokens instanceof Array && tokens.length > 0) {
|
|
119
|
-
if (tokens.length > 1) {
|
|
120
|
-
const response = await messaging.sendMulticast({
|
|
121
|
-
notification,
|
|
122
|
-
data,
|
|
123
|
-
tokens
|
|
124
|
-
})
|
|
125
|
-
|
|
126
|
-
if (response.failureCount > 0) {
|
|
127
|
-
const failedTokens = []
|
|
128
|
-
response.responses.forEach((resp, idx) => {
|
|
129
|
-
if (!resp.success) {
|
|
130
|
-
failedTokens.push(tokens[idx])
|
|
131
|
-
}
|
|
132
|
-
})
|
|
133
|
-
logger.error('List of tokens that caused failures: ' + failedTokens)
|
|
134
|
-
}
|
|
135
|
-
} else {
|
|
136
|
-
const token = tokens[0]
|
|
137
|
-
|
|
138
|
-
try {
|
|
139
|
-
const response = await messaging.send({
|
|
140
|
-
notification,
|
|
141
|
-
data,
|
|
142
|
-
token
|
|
143
|
-
})
|
|
144
|
-
logger.log('Successfully sent message:', response)
|
|
145
|
-
} catch (err) {
|
|
146
|
-
logger.error('Error sending message:', err)
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
if (topic) {
|
|
152
|
-
try {
|
|
153
|
-
const response = await messaging.send({
|
|
154
|
-
notification,
|
|
155
|
-
data,
|
|
156
|
-
topic
|
|
157
|
-
})
|
|
158
|
-
logger.log('Successfully sent message:', response)
|
|
159
|
-
} catch (err) {
|
|
160
|
-
logger.error('Error sending message:', err)
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
if (receivers && receivers instanceof Array) {
|
|
165
|
-
for (let receiver of receivers) {
|
|
166
|
-
const notification_key = await getDeviceGroup(receiver)
|
|
167
|
-
|
|
168
|
-
if (notification_key) {
|
|
169
|
-
await messaging.sendToDeviceGroup(notification_key, {
|
|
170
|
-
notification,
|
|
171
|
-
data
|
|
172
|
-
})
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
async function postDeviceGroup(body) {
|
|
179
|
-
var response = await fetch('https://fcm.googleapis.com/fcm/notification', {
|
|
180
|
-
method: 'POST',
|
|
181
|
-
headers: {
|
|
182
|
-
'Content-Type': 'application/json',
|
|
183
|
-
Authorization: `key=${serverKey}`,
|
|
184
|
-
project_id: appConfig.messagingSenderId
|
|
185
|
-
},
|
|
186
|
-
body: JSON.stringify(body)
|
|
187
|
-
})
|
|
188
|
-
|
|
189
|
-
if (response.ok) {
|
|
190
|
-
const { notification_key } = await response.json()
|
|
191
|
-
return notification_key
|
|
192
|
-
} else {
|
|
193
|
-
console.error('postDeviceGroup-notok', response.status, await response.text())
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
async function getDeviceGroup(notificationKeyName) {
|
|
198
|
-
const response = await fetch(
|
|
199
|
-
`https://fcm.googleapis.com/fcm/notification?notification_key_name=${notificationKeyName}`,
|
|
200
|
-
{
|
|
201
|
-
method: 'GET',
|
|
202
|
-
headers: {
|
|
203
|
-
'Content-Type': 'application/json',
|
|
204
|
-
Authorization: `key=${serverKey}`,
|
|
205
|
-
project_id: appConfig.messagingSenderId
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
)
|
|
209
|
-
|
|
210
|
-
if (response.ok) {
|
|
211
|
-
const { notification_key } = await response.json()
|
|
212
|
-
return notification_key
|
|
213
|
-
}
|
|
214
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './fcm'
|
package/server/index.ts
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import { pubsub } from '@things-factory/shell'
|
|
2
|
-
import { logger } from '@things-factory/env'
|
|
3
|
-
|
|
4
|
-
import { notify } from '../controllers/fcm'
|
|
5
|
-
|
|
6
|
-
const debug = require('debug')('things-factory:notification:notification-middleware')
|
|
7
|
-
|
|
8
|
-
function notifier(context) {
|
|
9
|
-
return async function ({
|
|
10
|
-
receivers,
|
|
11
|
-
privileges,
|
|
12
|
-
tokens,
|
|
13
|
-
topic,
|
|
14
|
-
type,
|
|
15
|
-
subject = 'info',
|
|
16
|
-
title,
|
|
17
|
-
body,
|
|
18
|
-
image,
|
|
19
|
-
url,
|
|
20
|
-
actions,
|
|
21
|
-
timestamp = Date.now(),
|
|
22
|
-
mode = 'background'
|
|
23
|
-
}) {
|
|
24
|
-
const { domain, user } = context.state
|
|
25
|
-
|
|
26
|
-
try {
|
|
27
|
-
if (mode === 'background') {
|
|
28
|
-
/* for send webpush notification message */
|
|
29
|
-
|
|
30
|
-
await notify({
|
|
31
|
-
receivers,
|
|
32
|
-
privileges,
|
|
33
|
-
tokens,
|
|
34
|
-
topic,
|
|
35
|
-
title,
|
|
36
|
-
body,
|
|
37
|
-
data: {
|
|
38
|
-
type,
|
|
39
|
-
url,
|
|
40
|
-
timestamp: String(timestamp)
|
|
41
|
-
},
|
|
42
|
-
image,
|
|
43
|
-
actions
|
|
44
|
-
})
|
|
45
|
-
} else {
|
|
46
|
-
/* for send publish notification to clients */
|
|
47
|
-
// TODO CONFIRM data format
|
|
48
|
-
await pubsub.publish('notification', {
|
|
49
|
-
notification: {
|
|
50
|
-
domain,
|
|
51
|
-
subject,
|
|
52
|
-
type,
|
|
53
|
-
title,
|
|
54
|
-
body,
|
|
55
|
-
image,
|
|
56
|
-
url,
|
|
57
|
-
timestamp
|
|
58
|
-
}
|
|
59
|
-
})
|
|
60
|
-
}
|
|
61
|
-
} catch (err) {
|
|
62
|
-
logger.error(err)
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
export async function notificationMiddleware(context: any, next: any) {
|
|
68
|
-
if (!context.state.notify) {
|
|
69
|
-
context.state.notify = notifier(context)
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
await next()
|
|
73
|
-
}
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import Router from 'koa-router'
|
|
2
|
-
import { ILike } from 'typeorm'
|
|
3
|
-
|
|
4
|
-
import { User } from '@things-factory/auth-base'
|
|
5
|
-
import { getRepository } from '@things-factory/shell'
|
|
6
|
-
|
|
7
|
-
import { getConfig, register, unregister } from '../controllers/fcm'
|
|
8
|
-
|
|
9
|
-
const debug = require('debug')('things-factory:notification:notification-router')
|
|
10
|
-
|
|
11
|
-
export const notificationRouter = new Router({
|
|
12
|
-
prefix: '/notification'
|
|
13
|
-
})
|
|
14
|
-
|
|
15
|
-
notificationRouter.get('/config', async (context, next) => {
|
|
16
|
-
const config = getConfig()
|
|
17
|
-
|
|
18
|
-
context.type = 'application/json'
|
|
19
|
-
context.body = config
|
|
20
|
-
})
|
|
21
|
-
|
|
22
|
-
notificationRouter.post('/register', async (context, next) => {
|
|
23
|
-
const { user } = context.state
|
|
24
|
-
const { body } = context.request
|
|
25
|
-
context.body = await register(user, body)
|
|
26
|
-
context.status = 200
|
|
27
|
-
})
|
|
28
|
-
|
|
29
|
-
notificationRouter.post('/unregister', async (context, next) => {
|
|
30
|
-
const { user } = context.state
|
|
31
|
-
const { body } = context.request
|
|
32
|
-
context.body = await unregister(user, body)
|
|
33
|
-
context.status = 200
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
notificationRouter.post('/notify', async (context, next) => {
|
|
37
|
-
const { user, domain, notify } = context.state
|
|
38
|
-
const repository = getRepository(User)
|
|
39
|
-
|
|
40
|
-
var { receivers, ...options } = context.request.body
|
|
41
|
-
|
|
42
|
-
debug('post:/notify', receivers, receivers.split(','), options)
|
|
43
|
-
|
|
44
|
-
// TODO filter only users having current domain privilege
|
|
45
|
-
receivers = (
|
|
46
|
-
await Promise.all(
|
|
47
|
-
receivers
|
|
48
|
-
.split(',')
|
|
49
|
-
.map(email => email.trim())
|
|
50
|
-
.map(async email => {
|
|
51
|
-
var receiver: User = await repository.findOneBy({ email: ILike(email) })
|
|
52
|
-
return receiver && receiver.id
|
|
53
|
-
})
|
|
54
|
-
)
|
|
55
|
-
).filter(receiver => !!receiver)
|
|
56
|
-
|
|
57
|
-
debug('post:/notify', receivers, user.id)
|
|
58
|
-
|
|
59
|
-
await notify({
|
|
60
|
-
receivers: receivers.length > 0 ? receivers : [user.id],
|
|
61
|
-
...options
|
|
62
|
-
})
|
|
63
|
-
|
|
64
|
-
context.body = {
|
|
65
|
-
success: true
|
|
66
|
-
}
|
|
67
|
-
})
|
package/server/routes.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { notificationRouter } from './routers/notification-router'
|
|
2
|
-
|
|
3
|
-
process.on('bootstrap-module-global-public-route' as any, (app, globalPublicRouter) => {})
|
|
4
|
-
|
|
5
|
-
process.on('bootstrap-module-global-private-route' as any, (app, globalPrivateRouter) => {})
|
|
6
|
-
|
|
7
|
-
process.on('bootstrap-module-domain-public-route' as any, (app, domainPublicRouter) => {})
|
|
8
|
-
|
|
9
|
-
process.on('bootstrap-module-domain-private-route' as any, (app, domainPrivateRouter) => {
|
|
10
|
-
domainPrivateRouter.use('', notificationRouter.routes(), notificationRouter.allowedMethods())
|
|
11
|
-
})
|
package/server/service/index.ts
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
/* EXPORT ENTITY TYPES */
|
|
2
|
-
export * from './notification-rule/notification-rule'
|
|
3
|
-
export * from './notification/notification'
|
|
4
|
-
|
|
5
|
-
/* IMPORT ENTITIES AND RESOLVERS */
|
|
6
|
-
import {
|
|
7
|
-
entities as NotificationRuleEntities,
|
|
8
|
-
resolvers as NotificationRuleResolvers,
|
|
9
|
-
subscribers as NotificationRuleSubscribers
|
|
10
|
-
} from './notification-rule'
|
|
11
|
-
import {
|
|
12
|
-
entities as NotificationEntities,
|
|
13
|
-
typeDefs as NotificationTypeDefs,
|
|
14
|
-
resolvers as NotificationResolvers,
|
|
15
|
-
directives as NotificationDirectives
|
|
16
|
-
} from './notification'
|
|
17
|
-
|
|
18
|
-
export const entities = [
|
|
19
|
-
/* ENTITIES */
|
|
20
|
-
...NotificationRuleEntities,
|
|
21
|
-
...NotificationEntities
|
|
22
|
-
]
|
|
23
|
-
|
|
24
|
-
export const subscribers = [
|
|
25
|
-
/* SUBSCRIBERS */
|
|
26
|
-
...NotificationRuleSubscribers
|
|
27
|
-
]
|
|
28
|
-
|
|
29
|
-
export const schema = {
|
|
30
|
-
typeDefs: {
|
|
31
|
-
...NotificationTypeDefs
|
|
32
|
-
},
|
|
33
|
-
resolverClasses: [
|
|
34
|
-
/* RESOLVER CLASSES */
|
|
35
|
-
...NotificationRuleResolvers,
|
|
36
|
-
...NotificationResolvers,
|
|
37
|
-
...NotificationResolvers
|
|
38
|
-
],
|
|
39
|
-
directives: {
|
|
40
|
-
...NotificationDirectives
|
|
41
|
-
}
|
|
42
|
-
}
|