@@ -93,7 +93,8 @@
|
|||||||
"tinycolor2": "1.6.0",
|
"tinycolor2": "1.6.0",
|
||||||
"trpc-openapi": "1.2.0",
|
"trpc-openapi": "1.2.0",
|
||||||
"unsplash-js": "^7.0.18",
|
"unsplash-js": "^7.0.18",
|
||||||
"use-debounce": "9.0.4"
|
"use-debounce": "9.0.4",
|
||||||
|
"@typebot.io/viewer": "workspace:*"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@chakra-ui/styled-system": "2.9.1",
|
"@chakra-ui/styled-system": "2.9.1",
|
||||||
|
|||||||
@@ -1,48 +0,0 @@
|
|||||||
import { authenticatedProcedure } from '@/helpers/server/trpc'
|
|
||||||
import { z } from 'zod'
|
|
||||||
import got, { HTTPError } from 'got'
|
|
||||||
import { getViewerUrl } from '@typebot.io/lib/getViewerUrl'
|
|
||||||
import prisma from '@/lib/prisma'
|
|
||||||
import { TRPCError } from '@trpc/server'
|
|
||||||
|
|
||||||
export const sendWhatsAppInitialMessage = authenticatedProcedure
|
|
||||||
.input(
|
|
||||||
z.object({
|
|
||||||
to: z.string(),
|
|
||||||
typebotId: z.string(),
|
|
||||||
startGroupId: z.string().optional(),
|
|
||||||
})
|
|
||||||
)
|
|
||||||
.mutation(
|
|
||||||
async ({ input: { to, typebotId, startGroupId }, ctx: { user } }) => {
|
|
||||||
const apiToken = await prisma.apiToken.findFirst({
|
|
||||||
where: { ownerId: user.id },
|
|
||||||
select: {
|
|
||||||
token: true,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if (!apiToken)
|
|
||||||
throw new TRPCError({
|
|
||||||
code: 'NOT_FOUND',
|
|
||||||
message: 'Api Token not found',
|
|
||||||
})
|
|
||||||
try {
|
|
||||||
await got.post({
|
|
||||||
method: 'POST',
|
|
||||||
url: `${getViewerUrl()}/api/v1/typebots/${typebotId}/whatsapp/start-preview`,
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${apiToken.token}`,
|
|
||||||
},
|
|
||||||
json: { to, isPreview: true, startGroupId },
|
|
||||||
})
|
|
||||||
} catch (error) {
|
|
||||||
throw new TRPCError({
|
|
||||||
code: 'INTERNAL_SERVER_ERROR',
|
|
||||||
message: 'Request to viewer failed',
|
|
||||||
cause: error instanceof HTTPError ? error.response.body : error,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return { message: 'success' }
|
|
||||||
}
|
|
||||||
)
|
|
||||||
@@ -32,7 +32,7 @@ export const WhatsAppPreviewInstructions = (props: StackProps) => {
|
|||||||
const [hasMessageBeenSent, setHasMessageBeenSent] = useState(false)
|
const [hasMessageBeenSent, setHasMessageBeenSent] = useState(false)
|
||||||
|
|
||||||
const { showToast } = useToast()
|
const { showToast } = useToast()
|
||||||
const { mutate } = trpc.sendWhatsAppInitialMessage.useMutation({
|
const { mutate } = trpc.whatsApp.startWhatsAppPreview.useMutation({
|
||||||
onMutate: () => setIsSendingMessage(true),
|
onMutate: () => setIsSendingMessage(true),
|
||||||
onSettled: () => setIsSendingMessage(false),
|
onSettled: () => setIsSendingMessage(false),
|
||||||
onError: (error) => showToast({ description: error.message }),
|
onError: (error) => showToast({ description: error.message }),
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { Typebot } from '@typebot.io/schemas'
|
|||||||
|
|
||||||
export const isReadTypebotForbidden = async (
|
export const isReadTypebotForbidden = async (
|
||||||
typebot: Pick<Typebot, 'workspaceId'> & {
|
typebot: Pick<Typebot, 'workspaceId'> & {
|
||||||
collaborators: Pick<CollaboratorsOnTypebots, 'userId' | 'type'>[]
|
collaborators: Pick<CollaboratorsOnTypebots, 'userId'>[]
|
||||||
},
|
},
|
||||||
user: Pick<User, 'email' | 'id'>
|
user: Pick<User, 'email' | 'id'>
|
||||||
) => {
|
) => {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { publicProcedure } from '@/helpers/server/trpc'
|
import { publicProcedure } from '@/helpers/server/trpc'
|
||||||
import { whatsAppWebhookRequestBodySchema } from '@typebot.io/schemas/features/whatsapp'
|
import { whatsAppWebhookRequestBodySchema } from '@typebot.io/schemas/features/whatsapp'
|
||||||
import { z } from 'zod'
|
import { z } from 'zod'
|
||||||
import { resumeWhatsAppFlow } from '../helpers/resumeWhatsAppFlow'
|
import { resumeWhatsAppFlow } from '@typebot.io/viewer/src/features/whatsApp/helpers/resumeWhatsAppFlow'
|
||||||
import { isNotDefined } from '@typebot.io/lib'
|
import { isNotDefined } from '@typebot.io/lib'
|
||||||
import { TRPCError } from '@trpc/server'
|
import { TRPCError } from '@trpc/server'
|
||||||
import { env } from '@typebot.io/env'
|
import { env } from '@typebot.io/env'
|
||||||
@@ -11,7 +11,8 @@ export const receiveMessagePreview = publicProcedure
|
|||||||
openapi: {
|
openapi: {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
path: '/whatsapp/preview/webhook',
|
path: '/whatsapp/preview/webhook',
|
||||||
summary: 'WhatsApp',
|
summary: 'Message webhook',
|
||||||
|
tags: ['WhatsApp'],
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.input(whatsAppWebhookRequestBodySchema)
|
.input(whatsAppWebhookRequestBodySchema)
|
||||||
@@ -30,8 +31,7 @@ export const receiveMessagePreview = publicProcedure
|
|||||||
if (isNotDefined(receivedMessage)) return { message: 'No message found' }
|
if (isNotDefined(receivedMessage)) return { message: 'No message found' }
|
||||||
const contactName =
|
const contactName =
|
||||||
entry.at(0)?.changes.at(0)?.value?.contacts?.at(0)?.profile?.name ?? ''
|
entry.at(0)?.changes.at(0)?.value?.contacts?.at(0)?.profile?.name ?? ''
|
||||||
const contactPhoneNumber =
|
const contactPhoneNumber = '+' + receivedMessage.from
|
||||||
entry.at(0)?.changes.at(0)?.value?.metadata.display_phone_number ?? ''
|
|
||||||
return resumeWhatsAppFlow({
|
return resumeWhatsAppFlow({
|
||||||
receivedMessage,
|
receivedMessage,
|
||||||
sessionId: `wa-${receivedMessage.from}-preview`,
|
sessionId: `wa-${receivedMessage.from}-preview`,
|
||||||
@@ -3,10 +3,16 @@ import { getPhoneNumber } from './getPhoneNumber'
|
|||||||
import { getSystemTokenInfo } from './getSystemTokenInfo'
|
import { getSystemTokenInfo } from './getSystemTokenInfo'
|
||||||
import { verifyIfPhoneNumberAvailable } from './verifyIfPhoneNumberAvailable'
|
import { verifyIfPhoneNumberAvailable } from './verifyIfPhoneNumberAvailable'
|
||||||
import { generateVerificationToken } from './generateVerificationToken'
|
import { generateVerificationToken } from './generateVerificationToken'
|
||||||
|
import { startWhatsAppPreview } from './startWhatsAppPreview'
|
||||||
|
import { subscribePreviewWebhook } from './subscribePreviewWebhook'
|
||||||
|
import { receiveMessagePreview } from './receiveMessagePreview'
|
||||||
|
|
||||||
export const whatsAppRouter = router({
|
export const whatsAppRouter = router({
|
||||||
getPhoneNumber,
|
getPhoneNumber,
|
||||||
getSystemTokenInfo,
|
getSystemTokenInfo,
|
||||||
verifyIfPhoneNumberAvailable,
|
verifyIfPhoneNumberAvailable,
|
||||||
generateVerificationToken,
|
generateVerificationToken,
|
||||||
|
startWhatsAppPreview,
|
||||||
|
subscribePreviewWebhook,
|
||||||
|
receiveMessagePreview,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,21 +1,24 @@
|
|||||||
import { publicProcedure } from '@/helpers/server/trpc'
|
import { authenticatedProcedure } from '@/helpers/server/trpc'
|
||||||
import { z } from 'zod'
|
import { z } from 'zod'
|
||||||
import { TRPCError } from '@trpc/server'
|
import { TRPCError } from '@trpc/server'
|
||||||
import { sendWhatsAppMessage } from '../helpers/sendWhatsAppMessage'
|
import { sendWhatsAppMessage } from '@typebot.io/lib/whatsApp/sendWhatsAppMessage'
|
||||||
import { startSession } from '@/features/chat/helpers/startSession'
|
import { startSession } from '@typebot.io/viewer/src/features/chat/helpers/startSession'
|
||||||
import { restartSession } from '@/features/chat/queries/restartSession'
|
|
||||||
import { env } from '@typebot.io/env'
|
import { env } from '@typebot.io/env'
|
||||||
import { HTTPError } from 'got'
|
import { HTTPError } from 'got'
|
||||||
import prisma from '@/lib/prisma'
|
import prisma from '@/lib/prisma'
|
||||||
import { sendChatReplyToWhatsApp } from '../helpers/sendChatReplyToWhatsApp'
|
import { sendChatReplyToWhatsApp } from '@typebot.io/lib/whatsApp/sendChatReplyToWhatsApp'
|
||||||
import { saveStateToDatabase } from '@/features/chat/helpers/saveStateToDatabase'
|
import { saveStateToDatabase } from '@typebot.io/viewer/src/features/chat/helpers/saveStateToDatabase'
|
||||||
|
import { restartSession } from '@typebot.io/viewer/src/features/chat/queries/restartSession'
|
||||||
|
import { isReadTypebotForbidden } from '../typebot/helpers/isReadTypebotForbidden'
|
||||||
|
import { SessionState } from '@typebot.io/schemas'
|
||||||
|
|
||||||
export const startWhatsAppPreview = publicProcedure
|
export const startWhatsAppPreview = authenticatedProcedure
|
||||||
.meta({
|
.meta({
|
||||||
openapi: {
|
openapi: {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
path: '/typebots/{typebotId}/whatsapp/start-preview',
|
path: '/typebots/{typebotId}/whatsapp/start-preview',
|
||||||
summary: 'Start WhatsApp Preview',
|
summary: 'Start preview',
|
||||||
|
tags: ['WhatsApp'],
|
||||||
protect: true,
|
protect: true,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@@ -38,20 +41,35 @@ export const startWhatsAppPreview = publicProcedure
|
|||||||
async ({ input: { to, typebotId, startGroupId }, ctx: { user } }) => {
|
async ({ input: { to, typebotId, startGroupId }, ctx: { user } }) => {
|
||||||
if (
|
if (
|
||||||
!env.WHATSAPP_PREVIEW_FROM_PHONE_NUMBER_ID ||
|
!env.WHATSAPP_PREVIEW_FROM_PHONE_NUMBER_ID ||
|
||||||
!env.META_SYSTEM_USER_TOKEN
|
!env.META_SYSTEM_USER_TOKEN ||
|
||||||
|
!env.WHATSAPP_PREVIEW_TEMPLATE_NAME
|
||||||
)
|
)
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: 'BAD_REQUEST',
|
code: 'BAD_REQUEST',
|
||||||
message:
|
message:
|
||||||
'Missing WHATSAPP_PREVIEW_FROM_PHONE_NUMBER_ID and/or META_SYSTEM_USER_TOKEN env variables',
|
'Missing WHATSAPP_PREVIEW_FROM_PHONE_NUMBER_ID or META_SYSTEM_USER_TOKEN or WHATSAPP_PREVIEW_TEMPLATE_NAME env variables',
|
||||||
})
|
|
||||||
if (!user)
|
|
||||||
throw new TRPCError({
|
|
||||||
code: 'UNAUTHORIZED',
|
|
||||||
message:
|
|
||||||
'You need to authenticate your request in order to start a preview',
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const existingTypebot = await prisma.typebot.findFirst({
|
||||||
|
where: {
|
||||||
|
id: typebotId,
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
workspaceId: true,
|
||||||
|
collaborators: {
|
||||||
|
select: {
|
||||||
|
userId: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if (
|
||||||
|
!existingTypebot?.id ||
|
||||||
|
(await isReadTypebotForbidden(existingTypebot, user))
|
||||||
|
)
|
||||||
|
throw new TRPCError({ code: 'NOT_FOUND', message: 'Typebot not found' })
|
||||||
|
|
||||||
const sessionId = `wa-${to}-preview`
|
const sessionId = `wa-${to}-preview`
|
||||||
|
|
||||||
const existingSession = await prisma.chatSession.findFirst({
|
const existingSession = await prisma.chatSession.findFirst({
|
||||||
@@ -60,6 +78,7 @@ export const startWhatsAppPreview = publicProcedure
|
|||||||
},
|
},
|
||||||
select: {
|
select: {
|
||||||
updatedAt: true,
|
updatedAt: true,
|
||||||
|
state: true,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -105,7 +124,11 @@ export const startWhatsAppPreview = publicProcedure
|
|||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
await restartSession({
|
await restartSession({
|
||||||
state: newSessionState,
|
state: {
|
||||||
|
...newSessionState,
|
||||||
|
whatsApp: (existingSession?.state as SessionState | undefined)
|
||||||
|
?.whatsApp,
|
||||||
|
},
|
||||||
id: `wa-${to}-preview`,
|
id: `wa-${to}-preview`,
|
||||||
})
|
})
|
||||||
try {
|
try {
|
||||||
@@ -115,9 +138,9 @@ export const startWhatsAppPreview = publicProcedure
|
|||||||
type: 'template',
|
type: 'template',
|
||||||
template: {
|
template: {
|
||||||
language: {
|
language: {
|
||||||
code: 'en',
|
code: env.WHATSAPP_PREVIEW_TEMPLATE_LANG,
|
||||||
},
|
},
|
||||||
name: 'preview_initial_message',
|
name: env.WHATSAPP_PREVIEW_TEMPLATE_NAME,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
credentials: {
|
credentials: {
|
||||||
@@ -8,7 +8,8 @@ export const subscribePreviewWebhook = publicProcedure
|
|||||||
openapi: {
|
openapi: {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
path: '/whatsapp/preview/webhook',
|
path: '/whatsapp/preview/webhook',
|
||||||
summary: 'WhatsApp',
|
summary: 'Subscribe webhook',
|
||||||
|
tags: ['WhatsApp'],
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.input(
|
.input(
|
||||||
@@ -3,7 +3,6 @@ import { webhookRouter } from '@/features/blocks/integrations/webhook/api/router
|
|||||||
import { getLinkedTypebots } from '@/features/blocks/logic/typebotLink/api/getLinkedTypebots'
|
import { getLinkedTypebots } from '@/features/blocks/logic/typebotLink/api/getLinkedTypebots'
|
||||||
import { credentialsRouter } from '@/features/credentials/api/router'
|
import { credentialsRouter } from '@/features/credentials/api/router'
|
||||||
import { getAppVersionProcedure } from '@/features/dashboard/api/getAppVersionProcedure'
|
import { getAppVersionProcedure } from '@/features/dashboard/api/getAppVersionProcedure'
|
||||||
import { sendWhatsAppInitialMessage } from '@/features/preview/api/sendWhatsAppInitialMessage'
|
|
||||||
import { resultsRouter } from '@/features/results/api/router'
|
import { resultsRouter } from '@/features/results/api/router'
|
||||||
import { processTelemetryEvent } from '@/features/telemetry/api/processTelemetryEvent'
|
import { processTelemetryEvent } from '@/features/telemetry/api/processTelemetryEvent'
|
||||||
import { themeRouter } from '@/features/theme/api/router'
|
import { themeRouter } from '@/features/theme/api/router'
|
||||||
@@ -23,7 +22,6 @@ export const trpcRouter = router({
|
|||||||
processTelemetryEvent,
|
processTelemetryEvent,
|
||||||
getLinkedTypebots,
|
getLinkedTypebots,
|
||||||
analytics: analyticsRouter,
|
analytics: analyticsRouter,
|
||||||
sendWhatsAppInitialMessage,
|
|
||||||
workspace: workspaceRouter,
|
workspace: workspaceRouter,
|
||||||
typebot: typebotRouter,
|
typebot: typebotRouter,
|
||||||
webhook: webhookRouter,
|
webhook: webhookRouter,
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"baseUrl": ".",
|
"baseUrl": ".",
|
||||||
"paths": {
|
"paths": {
|
||||||
"@/*": ["src/*"]
|
"@/*": ["src/*", "../viewer/src/*"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"]
|
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"]
|
||||||
|
|||||||
@@ -200,22 +200,54 @@ In order to be able to test your bot on WhatsApp from the Preview drawer, you ne
|
|||||||
<details><summary><h4>Requirements</h4></summary>
|
<details><summary><h4>Requirements</h4></summary>
|
||||||
<p>
|
<p>
|
||||||
|
|
||||||
1. Make sure you have [created a WhatsApp Business Account](https://developers.facebook.com/docs/whatsapp/cloud-api/get-started#set-up-developer-assets).
|
### Create a Facebook Business account
|
||||||
2. Go to your [System users page](https://business.facebook.com/settings/system-users) and create a new system user that has access to the related.
|
|
||||||
|
1. Head over to https://business.facebook.com and log in
|
||||||
|
2. Create a new business account on the left side bar
|
||||||
|
|
||||||
|
:::note
|
||||||
|
It is possible that Meta directly restricts your newly created Business account. In that case, make sure to verify your identity to proceed.
|
||||||
|
:::
|
||||||
|
|
||||||
|
### Create a Meta app
|
||||||
|
|
||||||
|
1. Head over to https://developers.facebook.com/apps
|
||||||
|
2. Click on Create App
|
||||||
|
3. Give it any name and select `Business` type
|
||||||
|
4. Select your newly created Business Account
|
||||||
|
5. On the app page, set up the `WhatsApp` product
|
||||||
|
|
||||||
|
### Get the System User token
|
||||||
|
|
||||||
|
1. Go to your [System users page](https://business.facebook.com/settings/system-users) and create a new system user that has access to the related.
|
||||||
|
|
||||||
- Token expiration: `Never`
|
- Token expiration: `Never`
|
||||||
- Available Permissions: `whatsapp_business_messaging`, `whatsapp_business_management`
|
- Available Permissions: `whatsapp_business_messaging`, `whatsapp_business_management`
|
||||||
|
|
||||||
3. The generated token will be used as `META_SYSTEM_USER_TOKEN` in your viewer configuration.
|
2. The generated token will be used as `META_SYSTEM_USER_TOKEN` in your viewer configuration.
|
||||||
4. Click on `Add assets`. Under `Apps`, look for your app, select it and check `Manage app`
|
3. Click on `Add assets`. Under `Apps`, look for your app, select it and check `Manage app`
|
||||||
5. Go to your WhatsApp Dev Console
|
|
||||||
|
### Get the phone number ID
|
||||||
|
|
||||||
|
1. Go to your WhatsApp Dev Console
|
||||||
|
|
||||||
<img src="/img/whatsapp/dev-console.png" alt="WhatsApp dev console" />
|
<img src="/img/whatsapp/dev-console.png" alt="WhatsApp dev console" />
|
||||||
|
|
||||||
6. Add your phone number by clicking on the `Add phone number` button.
|
2. Add your phone number by clicking on the `Add phone number` button.
|
||||||
7. Select the newly created phone number in the `From` dropdown list. This will be used as `WHATSAPP_PREVIEW_FROM_PHONE_NUMBER_ID` in your viewer configuration.
|
3. Select the newly created phone number in the `From` dropdown list and you will see right below the associated `Phone number ID` This will be used as `WHATSAPP_PREVIEW_FROM_PHONE_NUMBER_ID` in your viewer configuration.
|
||||||
8. Head over to `Quickstart > Configuration`. Edit the webhook URL to `$NEXT_PUBLIC_VIEWER_URL/api/v1/whatsapp/preview/webhook`. Set the Verify token to `$ENCRYPTION_SECRET` and click on `Verify and save`.
|
|
||||||
9. Add the `messages` webhook field.
|
### Set up the webhook
|
||||||
|
|
||||||
|
1. Head over to `Quickstart > Configuration`. Edit the webhook URL to `$NEXTAUTH_URL/api/v1/whatsapp/preview/webhook`. Set the Verify token to `$ENCRYPTION_SECRET` and click on `Verify and save`.
|
||||||
|
2. Add the `messages` webhook field.
|
||||||
|
|
||||||
|
### Set up the message template
|
||||||
|
|
||||||
|
1. Head over to `Messaging > Message Templates` and click on `Create Template`
|
||||||
|
2. Select the `Utility` category
|
||||||
|
3. Give it a name that corresponds to your `WHATSAPP_PREVIEW_TEMPLATE_NAME` configuration.
|
||||||
|
4. Select the language that corresponds to your `WHATSAPP_PREVIEW_TEMPLATE_LANG` configuration.
|
||||||
|
5. You can format it as you'd like. The user will just have to send a message to start the preview.
|
||||||
|
|
||||||
</p></details>
|
</p></details>
|
||||||
|
|
||||||
@@ -223,6 +255,8 @@ In order to be able to test your bot on WhatsApp from the Preview drawer, you ne
|
|||||||
| ------------------------------------- | ------- | ------------------------------------------------------- |
|
| ------------------------------------- | ------- | ------------------------------------------------------- |
|
||||||
| META_SYSTEM_USER_TOKEN | | The system user token used to send WhatsApp messages |
|
| META_SYSTEM_USER_TOKEN | | The system user token used to send WhatsApp messages |
|
||||||
| WHATSAPP_PREVIEW_FROM_PHONE_NUMBER_ID | | The phone number ID from which the message will be sent |
|
| WHATSAPP_PREVIEW_FROM_PHONE_NUMBER_ID | | The phone number ID from which the message will be sent |
|
||||||
|
| WHATSAPP_PREVIEW_TEMPLATE_NAME | | The preview start template message name |
|
||||||
|
| WHATSAPP_PREVIEW_TEMPLATE_LANG | en | The preview start template message name |
|
||||||
|
|
||||||
## Others
|
## Others
|
||||||
|
|
||||||
|
|||||||
@@ -32433,63 +32433,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"delete": {
|
|
||||||
"operationId": "customDomains-deleteCustomDomain",
|
|
||||||
"summary": "Delete custom domain",
|
|
||||||
"tags": [
|
|
||||||
"Custom domains"
|
|
||||||
],
|
|
||||||
"security": [
|
|
||||||
{
|
|
||||||
"Authorization": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"name": "workspaceId",
|
|
||||||
"in": "query",
|
|
||||||
"required": true,
|
|
||||||
"schema": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "name",
|
|
||||||
"in": "query",
|
|
||||||
"required": true,
|
|
||||||
"schema": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": "Successful response",
|
|
||||||
"content": {
|
|
||||||
"application/json": {
|
|
||||||
"schema": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"message": {
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"success"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"message"
|
|
||||||
],
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"default": {
|
|
||||||
"$ref": "#/components/responses/error"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"get": {
|
"get": {
|
||||||
"operationId": "customDomains-listCustomDomains",
|
"operationId": "customDomains-listCustomDomains",
|
||||||
"summary": "List custom domains",
|
"summary": "List custom domains",
|
||||||
@@ -32554,6 +32497,205 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/custom-domains/{name}": {
|
||||||
|
"delete": {
|
||||||
|
"operationId": "customDomains-deleteCustomDomain",
|
||||||
|
"summary": "Delete custom domain",
|
||||||
|
"tags": [
|
||||||
|
"Custom domains"
|
||||||
|
],
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"Authorization": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "workspaceId",
|
||||||
|
"in": "query",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "name",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Successful response",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"success"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"message"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"$ref": "#/components/responses/error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/custom-domains/{name}/verify": {
|
||||||
|
"get": {
|
||||||
|
"operationId": "customDomains-verifyCustomDomain",
|
||||||
|
"summary": "Verify domain config",
|
||||||
|
"tags": [
|
||||||
|
"Custom domains"
|
||||||
|
],
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"Authorization": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "workspaceId",
|
||||||
|
"in": "query",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "name",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Successful response",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"status": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Valid Configuration",
|
||||||
|
"Invalid Configuration",
|
||||||
|
"Domain Not Found",
|
||||||
|
"Pending Verification",
|
||||||
|
"Unknown Error"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"domainJson": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"apexName": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"projectId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"redirect": {
|
||||||
|
"type": "string",
|
||||||
|
"nullable": true
|
||||||
|
},
|
||||||
|
"redirectStatusCode": {
|
||||||
|
"type": "number",
|
||||||
|
"nullable": true
|
||||||
|
},
|
||||||
|
"gitBranch": {
|
||||||
|
"type": "string",
|
||||||
|
"nullable": true
|
||||||
|
},
|
||||||
|
"updatedAt": {
|
||||||
|
"type": "number",
|
||||||
|
"nullable": true
|
||||||
|
},
|
||||||
|
"createdAt": {
|
||||||
|
"type": "number",
|
||||||
|
"nullable": true
|
||||||
|
},
|
||||||
|
"verified": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"verification": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"domain": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"reason": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"type",
|
||||||
|
"domain",
|
||||||
|
"value",
|
||||||
|
"reason"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"name",
|
||||||
|
"apexName",
|
||||||
|
"projectId",
|
||||||
|
"redirect",
|
||||||
|
"redirectStatusCode",
|
||||||
|
"gitBranch",
|
||||||
|
"updatedAt",
|
||||||
|
"createdAt",
|
||||||
|
"verified"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"status",
|
||||||
|
"domainJson"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"$ref": "#/components/responses/error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/whatsapp/phoneNumber": {
|
"/whatsapp/phoneNumber": {
|
||||||
"get": {
|
"get": {
|
||||||
"operationId": "whatsApp-getPhoneNumber",
|
"operationId": "whatsApp-getPhoneNumber",
|
||||||
@@ -32768,6 +32910,497 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/typebots/{typebotId}/whatsapp/start-preview": {
|
||||||
|
"post": {
|
||||||
|
"operationId": "whatsApp-startWhatsAppPreview",
|
||||||
|
"summary": "Start preview",
|
||||||
|
"tags": [
|
||||||
|
"WhatsApp"
|
||||||
|
],
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"Authorization": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"requestBody": {
|
||||||
|
"required": true,
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"to": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1
|
||||||
|
},
|
||||||
|
"startGroupId": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"to"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "typebotId",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Successful response",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"message": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"message"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"$ref": "#/components/responses/error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/whatsapp/preview/webhook": {
|
||||||
|
"get": {
|
||||||
|
"operationId": "whatsApp-subscribePreviewWebhook",
|
||||||
|
"summary": "Subscribe webhook",
|
||||||
|
"tags": [
|
||||||
|
"WhatsApp"
|
||||||
|
],
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "hub.challenge",
|
||||||
|
"in": "query",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "hub.verify_token",
|
||||||
|
"in": "query",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Successful response",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "number"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"$ref": "#/components/responses/error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"post": {
|
||||||
|
"operationId": "whatsApp-receiveMessagePreview",
|
||||||
|
"summary": "Message webhook",
|
||||||
|
"tags": [
|
||||||
|
"WhatsApp"
|
||||||
|
],
|
||||||
|
"requestBody": {
|
||||||
|
"required": true,
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"entry": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"changes": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"value": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"contacts": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"profile": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"name"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"profile"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"messages": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"from": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"text"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"text": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"body": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"body"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
},
|
||||||
|
"timestamp": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"from",
|
||||||
|
"type",
|
||||||
|
"text",
|
||||||
|
"timestamp"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"from": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"button"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"button": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"text": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"payload": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"text",
|
||||||
|
"payload"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
},
|
||||||
|
"timestamp": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"from",
|
||||||
|
"type",
|
||||||
|
"button",
|
||||||
|
"timestamp"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"from": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"interactive"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"interactive": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"button_reply": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"id",
|
||||||
|
"title"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"button_reply"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
},
|
||||||
|
"timestamp": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"from",
|
||||||
|
"type",
|
||||||
|
"interactive",
|
||||||
|
"timestamp"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"from": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"image"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"image": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
},
|
||||||
|
"timestamp": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"from",
|
||||||
|
"type",
|
||||||
|
"image",
|
||||||
|
"timestamp"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"from": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"video"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"video": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
},
|
||||||
|
"timestamp": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"from",
|
||||||
|
"type",
|
||||||
|
"video",
|
||||||
|
"timestamp"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"from": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"audio"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"audio": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
},
|
||||||
|
"timestamp": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"from",
|
||||||
|
"type",
|
||||||
|
"audio",
|
||||||
|
"timestamp"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"from": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"document"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"document": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
},
|
||||||
|
"timestamp": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"from",
|
||||||
|
"type",
|
||||||
|
"document",
|
||||||
|
"timestamp"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"value"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"changes"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"entry"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"parameters": [],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Successful response",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"message": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"message"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"$ref": "#/components/responses/error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/openai/models": {
|
"/openai/models": {
|
||||||
"get": {
|
"get": {
|
||||||
"operationId": "openAI-listModels",
|
"operationId": "openAI-listModels",
|
||||||
|
|||||||
@@ -6496,435 +6496,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/whatsapp/preview/webhook": {
|
|
||||||
"get": {
|
|
||||||
"operationId": "whatsAppRouter-subscribePreviewWebhook",
|
|
||||||
"summary": "WhatsApp",
|
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"name": "hub.challenge",
|
|
||||||
"in": "query",
|
|
||||||
"required": true,
|
|
||||||
"schema": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "hub.verify_token",
|
|
||||||
"in": "query",
|
|
||||||
"required": true,
|
|
||||||
"schema": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": "Successful response",
|
|
||||||
"content": {
|
|
||||||
"application/json": {
|
|
||||||
"schema": {
|
|
||||||
"type": "number"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"default": {
|
|
||||||
"$ref": "#/components/responses/error"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"post": {
|
|
||||||
"operationId": "whatsAppRouter-receiveMessagePreview",
|
|
||||||
"summary": "WhatsApp",
|
|
||||||
"requestBody": {
|
|
||||||
"required": true,
|
|
||||||
"content": {
|
|
||||||
"application/json": {
|
|
||||||
"schema": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"entry": {
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"changes": {
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"value": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"contacts": {
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"profile": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"name": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"name"
|
|
||||||
],
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"profile"
|
|
||||||
],
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"metadata": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"display_phone_number": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"display_phone_number"
|
|
||||||
],
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
"messages": {
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"anyOf": [
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"from": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"type": {
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"text"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"text": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"body": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"body"
|
|
||||||
],
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
"timestamp": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"from",
|
|
||||||
"type",
|
|
||||||
"text",
|
|
||||||
"timestamp"
|
|
||||||
],
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"from": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"type": {
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"button"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"button": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"text": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"payload": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"text",
|
|
||||||
"payload"
|
|
||||||
],
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
"timestamp": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"from",
|
|
||||||
"type",
|
|
||||||
"button",
|
|
||||||
"timestamp"
|
|
||||||
],
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"from": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"type": {
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"interactive"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"interactive": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"button_reply": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"id": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"title": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"id",
|
|
||||||
"title"
|
|
||||||
],
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"button_reply"
|
|
||||||
],
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
"timestamp": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"from",
|
|
||||||
"type",
|
|
||||||
"interactive",
|
|
||||||
"timestamp"
|
|
||||||
],
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"from": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"type": {
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"image"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"image": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"id": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"id"
|
|
||||||
],
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
"timestamp": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"from",
|
|
||||||
"type",
|
|
||||||
"image",
|
|
||||||
"timestamp"
|
|
||||||
],
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"from": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"type": {
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"video"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"video": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"id": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"id"
|
|
||||||
],
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
"timestamp": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"from",
|
|
||||||
"type",
|
|
||||||
"video",
|
|
||||||
"timestamp"
|
|
||||||
],
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"from": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"type": {
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"audio"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"audio": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"id": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"id"
|
|
||||||
],
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
"timestamp": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"from",
|
|
||||||
"type",
|
|
||||||
"audio",
|
|
||||||
"timestamp"
|
|
||||||
],
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"from": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"type": {
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"document"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"document": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"id": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"id"
|
|
||||||
],
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
"timestamp": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"from",
|
|
||||||
"type",
|
|
||||||
"document",
|
|
||||||
"timestamp"
|
|
||||||
],
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"metadata"
|
|
||||||
],
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"value"
|
|
||||||
],
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"changes"
|
|
||||||
],
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"entry"
|
|
||||||
],
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"parameters": [],
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": "Successful response",
|
|
||||||
"content": {
|
|
||||||
"application/json": {
|
|
||||||
"schema": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"message": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"message"
|
|
||||||
],
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"default": {
|
|
||||||
"$ref": "#/components/responses/error"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/workspaces/{workspaceId}/whatsapp/phoneNumbers/{phoneNumberId}/webhook": {
|
"/workspaces/{workspaceId}/whatsapp/phoneNumbers/{phoneNumberId}/webhook": {
|
||||||
"get": {
|
"get": {
|
||||||
"operationId": "whatsAppRouter-subscribeWebhook",
|
"operationId": "whatsAppRouter-subscribeWebhook",
|
||||||
@@ -7031,18 +6602,6 @@
|
|||||||
"additionalProperties": false
|
"additionalProperties": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"metadata": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"display_phone_number": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"display_phone_number"
|
|
||||||
],
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
"messages": {
|
"messages": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
@@ -7320,9 +6879,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": [
|
|
||||||
"metadata"
|
|
||||||
],
|
|
||||||
"additionalProperties": false
|
"additionalProperties": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -7391,74 +6947,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"/typebots/{typebotId}/whatsapp/start-preview": {
|
|
||||||
"post": {
|
|
||||||
"operationId": "whatsAppRouter-startWhatsAppPreview",
|
|
||||||
"summary": "Start WhatsApp Preview",
|
|
||||||
"security": [
|
|
||||||
{
|
|
||||||
"Authorization": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"requestBody": {
|
|
||||||
"required": true,
|
|
||||||
"content": {
|
|
||||||
"application/json": {
|
|
||||||
"schema": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"to": {
|
|
||||||
"type": "string",
|
|
||||||
"minLength": 1
|
|
||||||
},
|
|
||||||
"startGroupId": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"to"
|
|
||||||
],
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"name": "typebotId",
|
|
||||||
"in": "path",
|
|
||||||
"required": true,
|
|
||||||
"schema": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": "Successful response",
|
|
||||||
"content": {
|
|
||||||
"application/json": {
|
|
||||||
"schema": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"message": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"message"
|
|
||||||
],
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"default": {
|
|
||||||
"$ref": "#/components/responses/error"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"components": {
|
"components": {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "viewer",
|
"name": "@typebot.io/viewer",
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ const getExpressionToEvaluate =
|
|||||||
case 'Contact name':
|
case 'Contact name':
|
||||||
return state.whatsApp?.contact.name ?? ''
|
return state.whatsApp?.contact.name ?? ''
|
||||||
case 'Phone number':
|
case 'Phone number':
|
||||||
return state.whatsApp?.contact.phoneNumber ?? ''
|
return `"${state.whatsApp?.contact.phoneNumber}"` ?? ''
|
||||||
case 'Now':
|
case 'Now':
|
||||||
case 'Today':
|
case 'Today':
|
||||||
return 'new Date().toISOString()'
|
return 'new Date().toISOString()'
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ export const receiveMessage = publicProcedure
|
|||||||
openapi: {
|
openapi: {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
path: '/workspaces/{workspaceId}/whatsapp/phoneNumbers/{phoneNumberId}/webhook',
|
path: '/workspaces/{workspaceId}/whatsapp/phoneNumbers/{phoneNumberId}/webhook',
|
||||||
summary: 'Receive WhatsApp Message',
|
summary: 'Message webhook',
|
||||||
|
tags: ['WhatsApp'],
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.input(
|
.input(
|
||||||
@@ -28,7 +29,7 @@ export const receiveMessage = publicProcedure
|
|||||||
const contactName =
|
const contactName =
|
||||||
entry.at(0)?.changes.at(0)?.value?.contacts?.at(0)?.profile?.name ?? ''
|
entry.at(0)?.changes.at(0)?.value?.contacts?.at(0)?.profile?.name ?? ''
|
||||||
const contactPhoneNumber =
|
const contactPhoneNumber =
|
||||||
entry.at(0)?.changes.at(0)?.value?.metadata.display_phone_number ?? ''
|
entry.at(0)?.changes.at(0)?.value?.messages?.at(0)?.from ?? ''
|
||||||
return resumeWhatsAppFlow({
|
return resumeWhatsAppFlow({
|
||||||
receivedMessage,
|
receivedMessage,
|
||||||
sessionId: `wa-${phoneNumberId}-${receivedMessage.from}`,
|
sessionId: `wa-${phoneNumberId}-${receivedMessage.from}`,
|
||||||
|
|||||||
@@ -1,14 +1,8 @@
|
|||||||
import { router } from '@/helpers/server/trpc'
|
import { router } from '@/helpers/server/trpc'
|
||||||
import { receiveMessagePreview } from './receiveMessagePreview'
|
|
||||||
import { startWhatsAppPreview } from './startWhatsAppPreview'
|
|
||||||
import { subscribePreviewWebhook } from './subscribePreviewWebhook'
|
|
||||||
import { subscribeWebhook } from './subscribeWebhook'
|
import { subscribeWebhook } from './subscribeWebhook'
|
||||||
import { receiveMessage } from './receiveMessage'
|
import { receiveMessage } from './receiveMessage'
|
||||||
|
|
||||||
export const whatsAppRouter = router({
|
export const whatsAppRouter = router({
|
||||||
subscribePreviewWebhook,
|
|
||||||
subscribeWebhook,
|
subscribeWebhook,
|
||||||
receiveMessagePreview,
|
|
||||||
receiveMessage,
|
receiveMessage,
|
||||||
startWhatsAppPreview,
|
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ export const subscribeWebhook = publicProcedure
|
|||||||
openapi: {
|
openapi: {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
path: '/workspaces/{workspaceId}/whatsapp/phoneNumbers/{phoneNumberId}/webhook',
|
path: '/workspaces/{workspaceId}/whatsapp/phoneNumbers/{phoneNumberId}/webhook',
|
||||||
summary: 'Subscribe WhatsApp webhook',
|
summary: 'Subscribe webhook',
|
||||||
|
tags: ['WhatsApp'],
|
||||||
protect: true,
|
protect: true,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import prisma from '@/lib/prisma'
|
|||||||
import { decrypt } from '@typebot.io/lib/api'
|
import { decrypt } from '@typebot.io/lib/api'
|
||||||
import { downloadMedia } from './downloadMedia'
|
import { downloadMedia } from './downloadMedia'
|
||||||
import { env } from '@typebot.io/env'
|
import { env } from '@typebot.io/env'
|
||||||
import { sendChatReplyToWhatsApp } from './sendChatReplyToWhatsApp'
|
import { sendChatReplyToWhatsApp } from '@typebot.io/lib/whatsApp/sendChatReplyToWhatsApp'
|
||||||
|
|
||||||
export const resumeWhatsAppFlow = async ({
|
export const resumeWhatsAppFlow = async ({
|
||||||
receivedMessage,
|
receivedMessage,
|
||||||
|
|||||||
2
packages/env/env.ts
vendored
2
packages/env/env.ts
vendored
@@ -230,6 +230,8 @@ const whatsAppEnv = {
|
|||||||
server: {
|
server: {
|
||||||
META_SYSTEM_USER_TOKEN: z.string().min(1).optional(),
|
META_SYSTEM_USER_TOKEN: z.string().min(1).optional(),
|
||||||
WHATSAPP_PREVIEW_FROM_PHONE_NUMBER_ID: z.string().min(1).optional(),
|
WHATSAPP_PREVIEW_FROM_PHONE_NUMBER_ID: z.string().min(1).optional(),
|
||||||
|
WHATSAPP_PREVIEW_TEMPLATE_NAME: z.string().min(1).optional(),
|
||||||
|
WHATSAPP_PREVIEW_TEMPLATE_LANG: z.string().min(1).optional().default('en'),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,21 +8,24 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@paralleldrive/cuid2": "2.2.1",
|
"@paralleldrive/cuid2": "2.2.1",
|
||||||
"@playwright/test": "1.36.0",
|
"@playwright/test": "1.36.0",
|
||||||
|
"@typebot.io/env": "workspace:*",
|
||||||
"@typebot.io/prisma": "workspace:*",
|
"@typebot.io/prisma": "workspace:*",
|
||||||
"@typebot.io/schemas": "workspace:*",
|
"@typebot.io/schemas": "workspace:*",
|
||||||
"@typebot.io/tsconfig": "workspace:*",
|
"@typebot.io/tsconfig": "workspace:*",
|
||||||
"@types/nodemailer": "6.4.8",
|
"@types/nodemailer": "6.4.8",
|
||||||
"next": "13.4.3",
|
"next": "13.4.3",
|
||||||
"nodemailer": "6.9.3",
|
"nodemailer": "6.9.3",
|
||||||
"typescript": "5.1.6",
|
"typescript": "5.1.6"
|
||||||
"@typebot.io/env": "workspace:*"
|
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"next": "13.0.0",
|
"next": "13.0.0",
|
||||||
"nodemailer": "6.7.8"
|
"nodemailer": "6.7.8"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@sentry/nextjs": "7.66.0",
|
||||||
|
"@udecode/plate-common": "^21.1.5",
|
||||||
"got": "12.6.0",
|
"got": "12.6.0",
|
||||||
"minio": "7.1.3"
|
"minio": "7.1.3",
|
||||||
|
"remark-slate": "^1.8.6"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
{
|
{
|
||||||
"extends": "@typebot.io/tsconfig/base.json",
|
"extends": "@typebot.io/tsconfig/base.json",
|
||||||
"include": ["**/*.ts"],
|
"include": ["**/*.ts"],
|
||||||
"exclude": ["node_modules"]
|
"exclude": ["node_modules"],
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ES2021"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { isDefined, isEmpty } from '@typebot.io/lib'
|
|
||||||
import {
|
import {
|
||||||
BubbleBlockType,
|
BubbleBlockType,
|
||||||
ButtonItem,
|
ButtonItem,
|
||||||
@@ -7,6 +6,7 @@ import {
|
|||||||
} from '@typebot.io/schemas'
|
} from '@typebot.io/schemas'
|
||||||
import { WhatsAppSendingMessage } from '@typebot.io/schemas/features/whatsapp'
|
import { WhatsAppSendingMessage } from '@typebot.io/schemas/features/whatsapp'
|
||||||
import { convertRichTextToWhatsAppText } from './convertRichTextToWhatsAppText'
|
import { convertRichTextToWhatsAppText } from './convertRichTextToWhatsAppText'
|
||||||
|
import { isDefined, isEmpty } from '../utils'
|
||||||
|
|
||||||
export const convertInputToWhatsAppMessages = (
|
export const convertInputToWhatsAppMessages = (
|
||||||
input: NonNullable<ChatReply['input']>,
|
input: NonNullable<ChatReply['input']>,
|
||||||
@@ -5,7 +5,7 @@ import {
|
|||||||
} from '@typebot.io/schemas'
|
} from '@typebot.io/schemas'
|
||||||
import { WhatsAppSendingMessage } from '@typebot.io/schemas/features/whatsapp'
|
import { WhatsAppSendingMessage } from '@typebot.io/schemas/features/whatsapp'
|
||||||
import { convertRichTextToWhatsAppText } from './convertRichTextToWhatsAppText'
|
import { convertRichTextToWhatsAppText } from './convertRichTextToWhatsAppText'
|
||||||
import { isSvgSrc } from '@typebot.io/lib'
|
import { isSvgSrc } from '../utils'
|
||||||
|
|
||||||
const mp4HttpsUrlRegex = /^https:\/\/.*\.mp4$/
|
const mp4HttpsUrlRegex = /^https:\/\/.*\.mp4$/
|
||||||
|
|
||||||
@@ -11,10 +11,10 @@ import {
|
|||||||
import { convertMessageToWhatsAppMessage } from './convertMessageToWhatsAppMessage'
|
import { convertMessageToWhatsAppMessage } from './convertMessageToWhatsAppMessage'
|
||||||
import { sendWhatsAppMessage } from './sendWhatsAppMessage'
|
import { sendWhatsAppMessage } from './sendWhatsAppMessage'
|
||||||
import { captureException } from '@sentry/nextjs'
|
import { captureException } from '@sentry/nextjs'
|
||||||
import { isNotDefined } from '@typebot.io/lib/utils'
|
|
||||||
import { HTTPError } from 'got'
|
import { HTTPError } from 'got'
|
||||||
import { computeTypingDuration } from '@typebot.io/lib/computeTypingDuration'
|
|
||||||
import { convertInputToWhatsAppMessages } from './convertInputToWhatsAppMessage'
|
import { convertInputToWhatsAppMessages } from './convertInputToWhatsAppMessage'
|
||||||
|
import { isNotDefined } from '../utils'
|
||||||
|
import { computeTypingDuration } from '../computeTypingDuration'
|
||||||
|
|
||||||
// Media can take some time to be delivered. This make sure we don't send a message before the media is delivered.
|
// Media can take some time to be delivered. This make sure we don't send a message before the media is delivered.
|
||||||
const messageAfterMediaTimeout = 5000
|
const messageAfterMediaTimeout = 5000
|
||||||
@@ -36,9 +36,9 @@ const actionSchema = z.object({
|
|||||||
})
|
})
|
||||||
|
|
||||||
const templateSchema = z.object({
|
const templateSchema = z.object({
|
||||||
name: z.literal('preview_initial_message'),
|
name: z.string(),
|
||||||
language: z.object({
|
language: z.object({
|
||||||
code: z.literal('en'),
|
code: z.string(),
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -151,9 +151,6 @@ export const whatsAppWebhookRequestBodySchema = z.object({
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
.optional(),
|
.optional(),
|
||||||
metadata: z.object({
|
|
||||||
display_phone_number: z.string(),
|
|
||||||
}),
|
|
||||||
messages: z.array(incomingMessageSchema).optional(),
|
messages: z.array(incomingMessageSchema).optional(),
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
|
|||||||
12
pnpm-lock.yaml
generated
12
pnpm-lock.yaml
generated
@@ -107,6 +107,9 @@ importers:
|
|||||||
'@typebot.io/nextjs':
|
'@typebot.io/nextjs':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../../packages/embeds/nextjs
|
version: link:../../packages/embeds/nextjs
|
||||||
|
'@typebot.io/viewer':
|
||||||
|
specifier: workspace:*
|
||||||
|
version: link:../viewer
|
||||||
'@udecode/plate-basic-marks':
|
'@udecode/plate-basic-marks':
|
||||||
specifier: 21.1.5
|
specifier: 21.1.5
|
||||||
version: 21.1.5(@babel/core@7.22.9)(@types/react@18.2.15)(react-dom@18.2.0)(react@18.2.0)(scheduler@0.23.0)(slate-history@0.93.0)(slate-react@0.94.2)(slate@0.94.1)
|
version: 21.1.5(@babel/core@7.22.9)(@types/react@18.2.15)(react-dom@18.2.0)(react@18.2.0)(scheduler@0.23.0)(slate-history@0.93.0)(slate-react@0.94.2)(slate@0.94.1)
|
||||||
@@ -1118,12 +1121,21 @@ importers:
|
|||||||
|
|
||||||
packages/lib:
|
packages/lib:
|
||||||
dependencies:
|
dependencies:
|
||||||
|
'@sentry/nextjs':
|
||||||
|
specifier: 7.66.0
|
||||||
|
version: 7.66.0(next@13.4.3)(react@18.2.0)
|
||||||
|
'@udecode/plate-common':
|
||||||
|
specifier: ^21.1.5
|
||||||
|
version: 21.1.5(@babel/core@7.22.9)(@types/react@18.2.15)(react-dom@18.2.0)(react@18.2.0)(scheduler@0.23.0)(slate-history@0.93.0)(slate-react@0.94.2)(slate@0.94.1)
|
||||||
got:
|
got:
|
||||||
specifier: 12.6.0
|
specifier: 12.6.0
|
||||||
version: 12.6.0
|
version: 12.6.0
|
||||||
minio:
|
minio:
|
||||||
specifier: 7.1.3
|
specifier: 7.1.3
|
||||||
version: 7.1.3
|
version: 7.1.3
|
||||||
|
remark-slate:
|
||||||
|
specifier: ^1.8.6
|
||||||
|
version: 1.8.6
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@paralleldrive/cuid2':
|
'@paralleldrive/cuid2':
|
||||||
specifier: 2.2.1
|
specifier: 2.2.1
|
||||||
|
|||||||
Reference in New Issue
Block a user