🐛 Add subscription handler in api folder
This commit is contained in:
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@@ -15,7 +15,8 @@
|
|||||||
"DATABASE_URL": "postgresql://postgres:typebot@127.0.0.1:5432/typebot",
|
"DATABASE_URL": "postgresql://postgres:typebot@127.0.0.1:5432/typebot",
|
||||||
"NEXT_PUBLIC_VIEWER_URL": "http://localhost:3001",
|
"NEXT_PUBLIC_VIEWER_URL": "http://localhost:3001",
|
||||||
"NEXTAUTH_URL": "http://localhost:3000",
|
"NEXTAUTH_URL": "http://localhost:3000",
|
||||||
"ENCRYPTION_SECRET": "H+KbL/OFrqbEuDy/1zX8bsPG+spXri3S"
|
"ENCRYPTION_SECRET": "H+KbL/OFrqbEuDy/1zX8bsPG+spXri3S",
|
||||||
|
"S3_ENDPOINT": "http://localhost:9000"
|
||||||
},
|
},
|
||||||
"[prisma]": {
|
"[prisma]": {
|
||||||
"editor.defaultFormatter": "Prisma.prisma"
|
"editor.defaultFormatter": "Prisma.prisma"
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { TRPCError } from '@trpc/server'
|
|||||||
import { env } from '@typebot.io/env'
|
import { env } from '@typebot.io/env'
|
||||||
import { z } from 'zod'
|
import { z } from 'zod'
|
||||||
|
|
||||||
|
// TODO: Delete in favor of /api
|
||||||
export const subscribePreviewWebhook = publicProcedure
|
export const subscribePreviewWebhook = publicProcedure
|
||||||
.meta({
|
.meta({
|
||||||
openapi: {
|
openapi: {
|
||||||
|
|||||||
@@ -6,27 +6,40 @@ import { resumeWhatsAppFlow } from '@typebot.io/bot-engine/whatsapp/resumeWhatsA
|
|||||||
import { isNotDefined } from '@typebot.io/lib'
|
import { isNotDefined } from '@typebot.io/lib'
|
||||||
import { env } from '@typebot.io/env'
|
import { env } from '@typebot.io/env'
|
||||||
import { NextApiRequest, NextApiResponse } from 'next'
|
import { NextApiRequest, NextApiResponse } from 'next'
|
||||||
|
import { methodNotAllowed } from '@typebot.io/lib/api'
|
||||||
|
|
||||||
export default async function handler(
|
export default async function handler(
|
||||||
req: NextApiRequest,
|
req: NextApiRequest,
|
||||||
res: NextApiResponse
|
res: NextApiResponse
|
||||||
) {
|
) {
|
||||||
if (!env.WHATSAPP_PREVIEW_FROM_PHONE_NUMBER_ID)
|
if (req.method === 'GET') {
|
||||||
return res
|
const token = req.query['hub.verify_token'] as string | undefined
|
||||||
.status(500)
|
const challenge = req.query['hub.challenge'] as string | undefined
|
||||||
.send('WHATSAPP_PREVIEW_FROM_PHONE_NUMBER_ID is not defined')
|
if (token !== env.ENCRYPTION_SECRET)
|
||||||
const body = typeof req.body === 'string' ? JSON.parse(req.body) : req.body
|
return res.status(401).json({
|
||||||
const { entry } = whatsAppWebhookRequestBodySchema.parse(body)
|
error: 'Unauthorized',
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
})
|
||||||
// @ts-ignore
|
return Number(challenge)
|
||||||
const ctx = globalThis[Symbol.for('@vercel/request-context')]
|
|
||||||
if (ctx?.get?.().waitUntil) {
|
|
||||||
ctx.get().waitUntil(() => processWhatsAppReply(entry))
|
|
||||||
return res.status(200).json({ message: 'Message is being processed.' })
|
|
||||||
}
|
}
|
||||||
console.log('Processing message')
|
if (req.method === 'POST') {
|
||||||
const { message } = await processWhatsAppReply(entry)
|
if (!env.WHATSAPP_PREVIEW_FROM_PHONE_NUMBER_ID)
|
||||||
return res.status(200).json({ message })
|
return res
|
||||||
|
.status(500)
|
||||||
|
.send('WHATSAPP_PREVIEW_FROM_PHONE_NUMBER_ID is not defined')
|
||||||
|
const body = typeof req.body === 'string' ? JSON.parse(req.body) : req.body
|
||||||
|
const { entry } = whatsAppWebhookRequestBodySchema.parse(body)
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore
|
||||||
|
const ctx = globalThis[Symbol.for('@vercel/request-context')]
|
||||||
|
if (ctx?.get?.().waitUntil) {
|
||||||
|
ctx.get().waitUntil(() => processWhatsAppReply(entry))
|
||||||
|
return res.status(200).json({ message: 'Message is being processed.' })
|
||||||
|
}
|
||||||
|
console.log('Processing message')
|
||||||
|
const { message } = await processWhatsAppReply(entry)
|
||||||
|
return res.status(200).json({ message })
|
||||||
|
}
|
||||||
|
return methodNotAllowed(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
const processWhatsAppReply = async (
|
const processWhatsAppReply = async (
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ import prisma from '@typebot.io/lib/prisma'
|
|||||||
import { TRPCError } from '@trpc/server'
|
import { TRPCError } from '@trpc/server'
|
||||||
import { z } from 'zod'
|
import { z } from 'zod'
|
||||||
|
|
||||||
|
// TODO: Delete in favor of /api
|
||||||
|
|
||||||
export const subscribeWebhook = publicProcedure
|
export const subscribeWebhook = publicProcedure
|
||||||
.meta({
|
.meta({
|
||||||
openapi: {
|
openapi: {
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import {
|
|||||||
import { resumeWhatsAppFlow } from '@typebot.io/bot-engine/whatsapp/resumeWhatsAppFlow'
|
import { resumeWhatsAppFlow } from '@typebot.io/bot-engine/whatsapp/resumeWhatsAppFlow'
|
||||||
import { isNotDefined } from '@typebot.io/lib'
|
import { isNotDefined } from '@typebot.io/lib'
|
||||||
import { NextApiRequest, NextApiResponse } from 'next'
|
import { NextApiRequest, NextApiResponse } from 'next'
|
||||||
|
import prisma from '@typebot.io/lib/prisma'
|
||||||
|
import { methodNotAllowed } from '@typebot.io/lib/api/utils'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
entry: WhatsAppWebhookRequestBody['entry']
|
entry: WhatsAppWebhookRequestBody['entry']
|
||||||
@@ -20,27 +22,53 @@ export default async function handler(
|
|||||||
req: NextApiRequest,
|
req: NextApiRequest,
|
||||||
res: NextApiResponse
|
res: NextApiResponse
|
||||||
) {
|
) {
|
||||||
const workspaceId = req.query.workspaceId as string
|
if (req.method === 'GET') {
|
||||||
const credentialsId = req.query.credentialsId as string
|
const token = req.query['hub.verify_token'] as string | undefined
|
||||||
const body = typeof req.body === 'string' ? JSON.parse(req.body) : req.body
|
const challenge = req.query['hub.challenge'] as string | undefined
|
||||||
const { entry } = whatsAppWebhookRequestBodySchema.parse(body)
|
if (!token || !challenge)
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
return res.status(400).json({
|
||||||
// @ts-ignore
|
error: 'hub.verify_token and hub.challenge are required',
|
||||||
const ctx = globalThis[Symbol.for('@vercel/request-context')]
|
})
|
||||||
if (ctx?.get?.().waitUntil) {
|
const verificationToken = await prisma.verificationToken.findUnique({
|
||||||
ctx
|
where: {
|
||||||
.get()
|
token,
|
||||||
.waitUntil(() =>
|
},
|
||||||
processWhatsAppReply({ entry, workspaceId, credentialsId })
|
})
|
||||||
)
|
if (!verificationToken)
|
||||||
return res.status(200).json({ message: 'Message is being processed.' })
|
return res.status(401).json({
|
||||||
|
error: 'Unauthorized',
|
||||||
|
})
|
||||||
|
await prisma.verificationToken.delete({
|
||||||
|
where: {
|
||||||
|
token,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return Number(challenge)
|
||||||
}
|
}
|
||||||
const { message } = await processWhatsAppReply({
|
if (req.method === 'POST') {
|
||||||
entry,
|
const workspaceId = req.query.workspaceId as string
|
||||||
workspaceId,
|
const credentialsId = req.query.credentialsId as string
|
||||||
credentialsId,
|
const body = typeof req.body === 'string' ? JSON.parse(req.body) : req.body
|
||||||
})
|
const { entry } = whatsAppWebhookRequestBodySchema.parse(body)
|
||||||
return res.status(200).json({ message })
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore
|
||||||
|
const ctx = globalThis[Symbol.for('@vercel/request-context')]
|
||||||
|
if (ctx?.get?.().waitUntil) {
|
||||||
|
ctx
|
||||||
|
.get()
|
||||||
|
.waitUntil(() =>
|
||||||
|
processWhatsAppReply({ entry, workspaceId, credentialsId })
|
||||||
|
)
|
||||||
|
return res.status(200).json({ message: 'Message is being processed.' })
|
||||||
|
}
|
||||||
|
const { message } = await processWhatsAppReply({
|
||||||
|
entry,
|
||||||
|
workspaceId,
|
||||||
|
credentialsId,
|
||||||
|
})
|
||||||
|
return res.status(200).json({ message })
|
||||||
|
}
|
||||||
|
return methodNotAllowed(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
const processWhatsAppReply = async ({
|
const processWhatsAppReply = async ({
|
||||||
|
|||||||
Reference in New Issue
Block a user