Parse subscription filter in rules

This commit is contained in:
Hongbo Wu
2022-11-22 12:12:12 +08:00
parent 9344fae1b9
commit f7b0981b7d
3 changed files with 63 additions and 21 deletions

View File

@ -25,6 +25,7 @@
"axios": "^0.27.2",
"dotenv": "^16.0.1",
"firebase-admin": "^10.0.2",
"jsonwebtoken": "^8.5.1"
"jsonwebtoken": "^8.5.1",
"search-query-parser": "^1.6.0"
}
}

View File

@ -56,9 +56,9 @@ export const getDeviceTokens = async (
}
export const getBatchMessages = (
title: string,
messages: string[],
tokens: string[],
title?: string,
imageUrl?: string
): Message[] => {
const batchMessages: Message[] = []
@ -93,8 +93,5 @@ export const sendMulticastPushNotifications = async (
export const sendBatchPushNotifications = async (
messages: Message[]
): Promise<BatchResponse | undefined> => {
const res = await getMessaging().sendAll(messages)
console.debug('res', res)
return res
return getMessaging().sendAll(messages)
}

View File

@ -2,9 +2,10 @@ import {
getBatchMessages,
getDeviceTokens,
sendBatchPushNotifications,
} from './sendNotification'
} from './notification'
import { getAuthToken, PubSubData } from './index'
import axios from 'axios'
import { parse, SearchParserKeyWordOffset } from 'search-query-parser'
export enum RuleActionType {
AddLabel = 'ADD_LABEL',
@ -30,6 +31,59 @@ export interface Rule {
updatedAt: Date
}
interface SearchFilter {
subscriptionFilter?: string
}
const parseSearchFilter = (filter: string): SearchFilter => {
const searchFilter = filter ? filter.replace(/\W\s":/g, '') : undefined
const result: SearchFilter = {}
if (!searchFilter || searchFilter === '*') {
return result
}
const parsed = parse(searchFilter, {
keywords: ['subscription'],
tokenize: true,
})
if (parsed.offsets) {
const keywords = parsed.offsets
.filter((offset) => 'keyword' in offset)
.map((offset) => offset as SearchParserKeyWordOffset)
for (const keyword of keywords) {
switch (keyword.keyword) {
case 'subscription':
result.subscriptionFilter = keyword.value
}
}
}
return result
}
const isValidData = (filter: string, data: PubSubData): boolean => {
const searchFilter = parseSearchFilter(filter)
if (searchFilter.subscriptionFilter) {
return isValidSubscription(searchFilter.subscriptionFilter, data)
}
return true
}
const isValidSubscription = (
subscriptionFilter: string,
data: PubSubData
): boolean => {
if (!data.subscription) {
return false
}
return subscriptionFilter === '*' || data.subscription === subscriptionFilter
}
export const getEnabledRules = async (
userId: string,
apiEndpoint: string,
@ -77,9 +131,7 @@ export const triggerActions = async (
jwtSecret: string
) => {
for (const rule of rules) {
// TODO: filter out rules that don't match the trigger
if (!data.subscription) {
console.debug('no subscription')
if (!isValidData(rule.filter, data)) {
continue
}
@ -94,14 +146,7 @@ export const triggerActions = async (
console.log('No notification messages provided')
continue
}
await sendNotification(
userId,
data.subscription,
action.params,
apiEndpoint,
jwtSecret,
data.image
)
await sendNotification(userId, action.params, apiEndpoint, jwtSecret)
}
}
}
@ -109,20 +154,19 @@ export const triggerActions = async (
export const sendNotification = async (
userId: string,
subscription: string,
messages: string[],
apiEndpoint: string,
jwtSecret: string,
title?: string,
image?: string
) => {
const title = `📫 - ${subscription} has published a new article`
// get device tokens by calling api
const tokens = await getDeviceTokens(userId, apiEndpoint, jwtSecret)
const batchMessages = getBatchMessages(
title,
messages,
tokens.map((t) => t.token),
title,
image
)