mirror of
https://github.com/omnivore-app/omnivore.git
synced 2026-03-11 08:54:26 +00:00
Add pubsub subscription to trigger webhook
This commit is contained in:
parent
c84668e6b0
commit
7b0ebb9dbf
2 changed files with 88 additions and 0 deletions
86
packages/api/src/routers/svc/webhooks.ts
Normal file
86
packages/api/src/routers/svc/webhooks.ts
Normal file
|
|
@ -0,0 +1,86 @@
|
||||||
|
/* eslint-disable @typescript-eslint/no-misused-promises */
|
||||||
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||||
|
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
||||||
|
import express from 'express'
|
||||||
|
import { readPushSubscription } from '../../datalayer/pubsub'
|
||||||
|
import { getRepository } from '../../entity/utils'
|
||||||
|
import { Webhook } from '../../entity/webhook'
|
||||||
|
import axios, { Method } from 'axios'
|
||||||
|
|
||||||
|
export function webhooksServiceRouter() {
|
||||||
|
const router = express.Router()
|
||||||
|
|
||||||
|
router.post('/:action', async (req, res) => {
|
||||||
|
console.log('trigger webhook of action', req.params.action)
|
||||||
|
const { message: msgStr, expired } = readPushSubscription(req)
|
||||||
|
|
||||||
|
if (!msgStr) {
|
||||||
|
res.status(400).send('Bad Request')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expired) {
|
||||||
|
console.log('discarding expired message')
|
||||||
|
res.status(200).send('Expired')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const data = JSON.parse(msgStr)
|
||||||
|
const { userId, type } = data
|
||||||
|
if (!userId || !type) {
|
||||||
|
console.log('No userId or type found in message')
|
||||||
|
res.status(400).send('Bad Request')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// example: PAGE_CREATED
|
||||||
|
const eventType = `${type as string}_${req.params.action}`.toUpperCase()
|
||||||
|
const webhooks = await getRepository(Webhook)
|
||||||
|
.createQueryBuilder()
|
||||||
|
.where('userId = :userId', { userId })
|
||||||
|
.andWhere(':eventType = ANY(eventTypes)', { eventType })
|
||||||
|
.andWhere('enabled = true')
|
||||||
|
.getMany()
|
||||||
|
|
||||||
|
if (webhooks.length <= 0) {
|
||||||
|
console.log(
|
||||||
|
'No active webhook found for user',
|
||||||
|
userId,
|
||||||
|
'and eventType',
|
||||||
|
eventType
|
||||||
|
)
|
||||||
|
res.status(200).send('No webhook found')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// trigger webhooks
|
||||||
|
for (const webhook of webhooks) {
|
||||||
|
const url = webhook.url
|
||||||
|
const method = webhook.method as Method
|
||||||
|
const body = JSON.stringify({
|
||||||
|
action: req.params.action,
|
||||||
|
userId,
|
||||||
|
[type]: data,
|
||||||
|
})
|
||||||
|
|
||||||
|
console.log('triggering webhook', url, method, body)
|
||||||
|
await axios.request({
|
||||||
|
url,
|
||||||
|
method,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': webhook.contentType,
|
||||||
|
},
|
||||||
|
data: body,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
res.status(200).send('OK')
|
||||||
|
} catch (err) {
|
||||||
|
console.log('trigger webhook failed', err)
|
||||||
|
res.status(500).send(err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return router
|
||||||
|
}
|
||||||
|
|
@ -42,6 +42,7 @@ import { corsConfig } from './utils/corsConfig'
|
||||||
import { initElasticsearch } from './elastic'
|
import { initElasticsearch } from './elastic'
|
||||||
import { uploadServiceRouter } from './routers/svc/upload'
|
import { uploadServiceRouter } from './routers/svc/upload'
|
||||||
import rateLimit from 'express-rate-limit'
|
import rateLimit from 'express-rate-limit'
|
||||||
|
import { webhooksServiceRouter } from './routers/svc/webhooks'
|
||||||
|
|
||||||
const PORT = process.env.PORT || 4000
|
const PORT = process.env.PORT || 4000
|
||||||
|
|
||||||
|
|
@ -111,6 +112,7 @@ export const createApp = (): {
|
||||||
app.use('/svc/pubsub/newsletters', newsletterServiceRouter())
|
app.use('/svc/pubsub/newsletters', newsletterServiceRouter())
|
||||||
app.use('/svc/pubsub/emails', emailsServiceRouter())
|
app.use('/svc/pubsub/emails', emailsServiceRouter())
|
||||||
app.use('/svc/pubsub/upload', uploadServiceRouter())
|
app.use('/svc/pubsub/upload', uploadServiceRouter())
|
||||||
|
app.use('/svc/pubsub/webhooks', webhooksServiceRouter())
|
||||||
app.use('/svc/reminders', remindersServiceRouter())
|
app.use('/svc/reminders', remindersServiceRouter())
|
||||||
app.use('/svc/pdf-attachments', pdfAttachmentsRouter())
|
app.use('/svc/pdf-attachments', pdfAttachmentsRouter())
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue