mirror of
https://github.com/hcengineering/platform.git
synced 2025-01-22 19:38:17 +00:00
UBERF-9230: Fix ses webpush (#7760)
Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
parent
82a9204076
commit
90e8ca4e97
@ -15,6 +15,7 @@
|
||||
//
|
||||
|
||||
import activity, { ActivityMessage, DocUpdateMessage } from '@hcengineering/activity'
|
||||
import { Analytics } from '@hcengineering/analytics'
|
||||
import chunter, { ChatMessage } from '@hcengineering/chunter'
|
||||
import contact, {
|
||||
Employee,
|
||||
@ -39,7 +40,6 @@ import core, {
|
||||
generateId,
|
||||
MeasureContext,
|
||||
MixinUpdate,
|
||||
RateLimiter,
|
||||
Ref,
|
||||
RefTo,
|
||||
SortingOrder,
|
||||
@ -82,7 +82,6 @@ import serverView from '@hcengineering/server-view'
|
||||
import { markupToText, stripTags } from '@hcengineering/text-core'
|
||||
import { encodeObjectURI } from '@hcengineering/view'
|
||||
import { workbenchId } from '@hcengineering/workbench'
|
||||
import { Analytics } from '@hcengineering/analytics'
|
||||
|
||||
import { Content, ContextsCache, ContextsCacheKey, NotifyParams, NotifyResult } from './types'
|
||||
import {
|
||||
@ -92,6 +91,7 @@ import {
|
||||
getNotificationContent,
|
||||
getNotificationLink,
|
||||
getNotificationProviderControl,
|
||||
getObjectSpace,
|
||||
getTextPresenter,
|
||||
getUsersInfo,
|
||||
isAllowed,
|
||||
@ -103,8 +103,7 @@ import {
|
||||
replaceAll,
|
||||
toReceiverInfo,
|
||||
updateNotifyContextsSpace,
|
||||
type NotificationProviderControl,
|
||||
getObjectSpace
|
||||
type NotificationProviderControl
|
||||
} from './utils'
|
||||
|
||||
export function getPushCollaboratorTx (
|
||||
@ -602,13 +601,7 @@ export async function createPushNotification (
|
||||
}
|
||||
}
|
||||
|
||||
const limiter = new RateLimiter(5)
|
||||
for (const subscription of userSubscriptions) {
|
||||
await limiter.add(async () => {
|
||||
await sendPushToSubscription(sesURL, sesAuth, control, target, subscription, data)
|
||||
})
|
||||
}
|
||||
await limiter.waitProcessing()
|
||||
void sendPushToSubscription(sesURL, sesAuth, control, target, userSubscriptions, data)
|
||||
}
|
||||
|
||||
async function sendPushToSubscription (
|
||||
@ -616,11 +609,11 @@ async function sendPushToSubscription (
|
||||
sesAuth: string | undefined,
|
||||
control: TriggerControl,
|
||||
targetUser: Ref<Account>,
|
||||
subscription: PushSubscription,
|
||||
subscriptions: PushSubscription[],
|
||||
data: PushData
|
||||
): Promise<void> {
|
||||
try {
|
||||
const result: 'ok' | 'clear-push' = (
|
||||
const result: Ref<PushSubscription>[] = (
|
||||
await (
|
||||
await fetch(concatLink(sesURL, '/web-push'), {
|
||||
method: 'post',
|
||||
@ -629,15 +622,17 @@ async function sendPushToSubscription (
|
||||
...(sesAuth != null ? { Authorization: `Bearer ${sesAuth}` } : {})
|
||||
},
|
||||
body: JSON.stringify({
|
||||
subscription,
|
||||
subscriptions,
|
||||
data
|
||||
})
|
||||
})
|
||||
).json()
|
||||
).result
|
||||
if (result === 'clear-push') {
|
||||
const tx = control.txFactory.createTxRemoveDoc(subscription._class, subscription.space, subscription._id)
|
||||
await control.apply(control.ctx, [tx])
|
||||
if (result.length > 0) {
|
||||
const domain = control.hierarchy.findDomain(notification.class.PushSubscription)
|
||||
if (domain !== undefined) {
|
||||
await control.lowLevel.clean(control.ctx, domain, result)
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
control.ctx.info('Cannot send push notification to', { user: targetUser, err })
|
||||
|
@ -15,4 +15,8 @@
|
||||
|
||||
import { main } from './main'
|
||||
|
||||
void main()
|
||||
void main().catch((err) => {
|
||||
if (err != null) {
|
||||
console.error(err)
|
||||
}
|
||||
})
|
||||
|
@ -13,6 +13,7 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import type { Ref } from '@hcengineering/core'
|
||||
import { PushSubscription, type PushData } from '@hcengineering/notification'
|
||||
import type { Request, Response } from 'express'
|
||||
import webpush, { WebPushError } from 'web-push'
|
||||
@ -22,25 +23,39 @@ import { SES } from './ses'
|
||||
import { Endpoint } from './types'
|
||||
|
||||
const errorMessages = ['expired', 'Unregistered', 'No such subscription']
|
||||
async function sendPushToSubscription (subscription: PushSubscription, data: PushData): Promise<'ok' | 'clear-push'> {
|
||||
try {
|
||||
await webpush.sendNotification(subscription, JSON.stringify(data))
|
||||
} catch (err: any) {
|
||||
if (err instanceof WebPushError) {
|
||||
if (errorMessages.some((p) => JSON.stringify((err as WebPushError).body).includes(p))) {
|
||||
return 'clear-push'
|
||||
async function sendPushToSubscription (
|
||||
subscriptions: PushSubscription[],
|
||||
data: PushData
|
||||
): Promise<Ref<PushSubscription>[]> {
|
||||
const result: Ref<PushSubscription>[] = []
|
||||
for (const subscription of subscriptions) {
|
||||
try {
|
||||
await webpush.sendNotification(subscription, JSON.stringify(data))
|
||||
} catch (err: any) {
|
||||
if (err instanceof WebPushError) {
|
||||
if (errorMessages.some((p) => JSON.stringify((err as WebPushError).body).includes(p))) {
|
||||
result.push(subscription._id)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 'ok'
|
||||
return result
|
||||
}
|
||||
|
||||
export const main = async (): Promise<void> => {
|
||||
const ses = new SES()
|
||||
console.log('SES service has been started')
|
||||
let webpushInitDone = false
|
||||
|
||||
if (config.PushPublicKey !== undefined && config.PushPrivateKey !== undefined) {
|
||||
webpush.setVapidDetails(config.PushSubject ?? 'mailto:hey@huly.io', config.PushPublicKey, config.PushPublicKey)
|
||||
try {
|
||||
const subj = config.PushSubject ?? 'mailto:hey@huly.io'
|
||||
console.log('Setting VAPID details', subj, config.PushPublicKey.length, config.PushPrivateKey.length)
|
||||
webpush.setVapidDetails(config.PushSubject ?? 'mailto:hey@huly.io', config.PushPublicKey, config.PushPrivateKey)
|
||||
webpushInitDone = true
|
||||
} catch (err: any) {
|
||||
console.error(err)
|
||||
}
|
||||
}
|
||||
|
||||
const checkAuth = (req: Request<any>, res: Response<any>): boolean => {
|
||||
@ -104,14 +119,18 @@ export const main = async (): Promise<void> => {
|
||||
res.status(400).send({ err: "'data' is missing" })
|
||||
return
|
||||
}
|
||||
const subscription: PushSubscription | undefined = req.body?.subscription
|
||||
if (subscription === undefined) {
|
||||
res.status(400).send({ err: "'subscription' is missing" })
|
||||
const subscriptions: PushSubscription[] | undefined = req.body?.subscriptions
|
||||
if (subscriptions === undefined) {
|
||||
res.status(400).send({ err: "'subscriptions' is missing" })
|
||||
return
|
||||
}
|
||||
if (!webpushInitDone) {
|
||||
res.json({ result: [] }).end()
|
||||
return
|
||||
}
|
||||
|
||||
const result = await sendPushToSubscription(subscription, data)
|
||||
res.json({ result })
|
||||
const result = await sendPushToSubscription(subscriptions, data)
|
||||
res.json({ result }).end()
|
||||
}
|
||||
}
|
||||
]
|
||||
|
Loading…
Reference in New Issue
Block a user