2
0

fix: 🐛 Webhook duplication

This commit is contained in:
Baptiste Arnaud
2022-05-13 06:46:17 -07:00
parent 936dde2195
commit 7507a1ab1e
2 changed files with 101 additions and 77 deletions

View File

@ -101,96 +101,119 @@ export const createTypebot = async ({
} }
export const importTypebot = async (typebot: Typebot, userPlan: Plan) => { export const importTypebot = async (typebot: Typebot, userPlan: Plan) => {
return sendRequest<Typebot>({ const { typebot: newTypebot, webhookIdsMapping } = duplicateTypebot(
typebot,
userPlan
)
const { data, error } = await sendRequest<Typebot>({
url: `/api/typebots`, url: `/api/typebots`,
method: 'POST', method: 'POST',
body: await duplicateTypebot(typebot, userPlan), body: newTypebot,
}) })
if (!data) return { data, error }
const webhookSteps = typebot.blocks
.flatMap((b) => b.steps)
.filter(isWebhookStep)
await Promise.all(
webhookSteps.map((s) =>
duplicateWebhook(
newTypebot.id,
s.webhookId,
webhookIdsMapping.get(s.webhookId) as string
)
)
)
return { data, error }
} }
const duplicateTypebot = async ( const duplicateTypebot = (
typebot: Typebot, typebot: Typebot,
userPlan: Plan userPlan: Plan
): Promise<Typebot> => { ): { typebot: Typebot; webhookIdsMapping: Map<string, string> } => {
const blockIdsMapping = generateOldNewIdsMapping(typebot.blocks) const blockIdsMapping = generateOldNewIdsMapping(typebot.blocks)
const edgeIdsMapping = generateOldNewIdsMapping(typebot.edges) const edgeIdsMapping = generateOldNewIdsMapping(typebot.edges)
const webhookIdsMapping = generateOldNewIdsMapping(
typebot.blocks
.flatMap((b) => b.steps)
.filter(isWebhookStep)
.map((s) => ({ id: s.webhookId }))
)
const id = cuid()
return { return {
...typebot, typebot: {
id: cuid(), ...typebot,
name: `${typebot.name} copy`, id,
publishedTypebotId: null, name: `${typebot.name} copy`,
publicId: null, publishedTypebotId: null,
customDomain: null, publicId: null,
blocks: await Promise.all( customDomain: null,
typebot.blocks.map(async (b) => ({ blocks: typebot.blocks.map((b) => ({
...b, ...b,
id: blockIdsMapping.get(b.id) as string, id: blockIdsMapping.get(b.id) as string,
steps: await Promise.all( steps: b.steps.map((s) => {
b.steps.map(async (s) => { const newIds = {
const newIds = { blockId: blockIdsMapping.get(s.blockId) as string,
blockId: blockIdsMapping.get(s.blockId) as string, outgoingEdgeId: s.outgoingEdgeId
outgoingEdgeId: s.outgoingEdgeId ? edgeIdsMapping.get(s.outgoingEdgeId)
? edgeIdsMapping.get(s.outgoingEdgeId) : undefined,
: undefined, }
} if (
if ( s.type === LogicStepType.TYPEBOT_LINK &&
s.type === LogicStepType.TYPEBOT_LINK && s.options.typebotId === 'current' &&
s.options.typebotId === 'current' && isDefined(s.options.blockId)
isDefined(s.options.blockId) )
)
return {
...s,
options: {
...s.options,
blockId: blockIdsMapping.get(s.options.blockId as string),
},
}
if (stepHasItems(s))
return {
...s,
items: s.items.map((item) => ({
...item,
outgoingEdgeId: item.outgoingEdgeId
? (edgeIdsMapping.get(item.outgoingEdgeId) as string)
: undefined,
})),
...newIds,
} as ChoiceInputStep | ConditionStep
if (isWebhookStep(s)) {
const newWebhook = await duplicateWebhook(s.webhookId)
return {
...s,
webhookId: newWebhook ? newWebhook.id : cuid(),
...newIds,
}
}
return { return {
...s, ...s,
options: {
...s.options,
blockId: blockIdsMapping.get(s.options.blockId as string),
},
}
if (stepHasItems(s))
return {
...s,
items: s.items.map((item) => ({
...item,
outgoingEdgeId: item.outgoingEdgeId
? (edgeIdsMapping.get(item.outgoingEdgeId) as string)
: undefined,
})),
...newIds,
} as ChoiceInputStep | ConditionStep
if (isWebhookStep(s)) {
return {
...s,
webhookId: webhookIdsMapping.get(s.webhookId) as string,
...newIds, ...newIds,
} }
})
),
}))
),
edges: typebot.edges.map((e) => ({
...e,
id: edgeIdsMapping.get(e.id) as string,
from: {
...e.from,
blockId: blockIdsMapping.get(e.from.blockId) as string,
},
to: { ...e.to, blockId: blockIdsMapping.get(e.to.blockId) as string },
})),
settings:
typebot.settings.general.isBrandingEnabled === false &&
userPlan === Plan.FREE
? {
...typebot.settings,
general: { ...typebot.settings.general, isBrandingEnabled: true },
} }
: typebot.settings, return {
createdAt: new Date().toISOString(), ...s,
updatedAt: new Date().toISOString(), ...newIds,
}
}),
})),
edges: typebot.edges.map((e) => ({
...e,
id: edgeIdsMapping.get(e.id) as string,
from: {
...e.from,
blockId: blockIdsMapping.get(e.from.blockId) as string,
},
to: { ...e.to, blockId: blockIdsMapping.get(e.to.blockId) as string },
})),
settings:
typebot.settings.general.isBrandingEnabled === false &&
userPlan === Plan.FREE
? {
...typebot.settings,
general: { ...typebot.settings.general, isBrandingEnabled: true },
}
: typebot.settings,
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
},
webhookIdsMapping,
} }
} }

View File

@ -1,4 +1,3 @@
import cuid from 'cuid'
import { Webhook } from 'models' import { Webhook } from 'models'
import { sendRequest } from 'utils' import { sendRequest } from 'utils'
@ -10,13 +9,15 @@ export const saveWebhook = (webhookId: string, webhook: Partial<Webhook>) =>
}) })
export const duplicateWebhook = async ( export const duplicateWebhook = async (
webhookId: string typebotId: string,
existingWebhookId: string,
newWebhookId: string
): Promise<Webhook | undefined> => { ): Promise<Webhook | undefined> => {
const { data } = await sendRequest<{ webhook: Webhook }>( const { data } = await sendRequest<{ webhook: Webhook }>(
`/api/webhooks/${webhookId}` `/api/webhooks/${existingWebhookId}`
) )
if (!data) return if (!data) return
const newWebhook = { ...data.webhook, id: cuid() } const newWebhook = { ...data.webhook, id: newWebhookId, typebotId }
await saveWebhook(newWebhook.id, newWebhook) await saveWebhook(newWebhook.id, newWebhook)
return newWebhook return newWebhook
} }