🧐 Add exportResults script
This commit is contained in:
119
packages/scripts/exportResults.ts
Normal file
119
packages/scripts/exportResults.ts
Normal file
@ -0,0 +1,119 @@
|
||||
import { PrismaClient } from '@typebot.io/prisma'
|
||||
import * as p from '@clack/prompts'
|
||||
import { promptAndSetEnvironment } from './utils'
|
||||
import cliProgress from 'cli-progress'
|
||||
import { writeFileSync } from 'fs'
|
||||
import {
|
||||
ResultWithAnswers,
|
||||
Typebot,
|
||||
resultWithAnswersSchema,
|
||||
} from '@typebot.io/schemas'
|
||||
import { byId } from '@typebot.io/lib'
|
||||
import { parseResultHeader } from '@typebot.io/lib/results/parseResultHeader'
|
||||
import { convertResultsToTableData } from '@typebot.io/lib/results/convertResultsToTableData'
|
||||
import { parseColumnsOrder } from '@typebot.io/lib/results/parseColumnsOrder'
|
||||
import { parseUniqueKey } from '@typebot.io/lib/parseUniqueKey'
|
||||
import { unparse } from 'papaparse'
|
||||
import { z } from 'zod'
|
||||
|
||||
const exportResults = async () => {
|
||||
await promptAndSetEnvironment('production')
|
||||
|
||||
const prisma = new PrismaClient()
|
||||
|
||||
const typebotId = (await p.text({
|
||||
message: 'Typebot ID?',
|
||||
})) as string
|
||||
|
||||
if (!typebotId || typeof typebotId !== 'string') {
|
||||
console.log('No id provided')
|
||||
return
|
||||
}
|
||||
|
||||
const progressBar = new cliProgress.SingleBar(
|
||||
{},
|
||||
cliProgress.Presets.shades_classic
|
||||
)
|
||||
|
||||
const typebot = (await prisma.typebot.findUnique({
|
||||
where: {
|
||||
id: typebotId,
|
||||
},
|
||||
})) as Typebot | null
|
||||
|
||||
if (!typebot) {
|
||||
console.log('No typebot found')
|
||||
return
|
||||
}
|
||||
|
||||
const totalResultsToExport = await prisma.result.count({
|
||||
where: {
|
||||
typebotId,
|
||||
hasStarted: true,
|
||||
isArchived: false,
|
||||
},
|
||||
})
|
||||
|
||||
progressBar.start(totalResultsToExport, 0)
|
||||
|
||||
const results: ResultWithAnswers[] = []
|
||||
|
||||
for (let skip = 0; skip < totalResultsToExport; skip += 50) {
|
||||
results.push(
|
||||
...z.array(resultWithAnswersSchema).parse(
|
||||
await prisma.result.findMany({
|
||||
take: 50,
|
||||
skip,
|
||||
where: {
|
||||
typebotId,
|
||||
hasStarted: true,
|
||||
isArchived: false,
|
||||
},
|
||||
orderBy: {
|
||||
createdAt: 'desc',
|
||||
},
|
||||
include: { answers: true },
|
||||
})
|
||||
)
|
||||
)
|
||||
progressBar.increment(50)
|
||||
}
|
||||
|
||||
progressBar.stop()
|
||||
|
||||
writeFileSync('logs/results.json', JSON.stringify(results))
|
||||
|
||||
const resultHeader = parseResultHeader(typebot, [])
|
||||
|
||||
const dataToUnparse = convertResultsToTableData(results, resultHeader)
|
||||
|
||||
const headerIds = parseColumnsOrder(
|
||||
typebot?.resultsTablePreferences?.columnsOrder,
|
||||
resultHeader
|
||||
).reduce<string[]>((currentHeaderIds, columnId) => {
|
||||
if (typebot?.resultsTablePreferences?.columnsVisibility[columnId] === false)
|
||||
return currentHeaderIds
|
||||
const columnLabel = resultHeader.find(
|
||||
(headerCell) => headerCell.id === columnId
|
||||
)?.id
|
||||
if (!columnLabel) return currentHeaderIds
|
||||
return [...currentHeaderIds, columnLabel]
|
||||
}, [])
|
||||
|
||||
const data = dataToUnparse.map<{ [key: string]: string }>((data) => {
|
||||
const newObject: { [key: string]: string } = {}
|
||||
headerIds?.forEach((headerId) => {
|
||||
const headerLabel = resultHeader.find(byId(headerId))?.label
|
||||
if (!headerLabel) return
|
||||
const newKey = parseUniqueKey(headerLabel, Object.keys(newObject))
|
||||
newObject[newKey] = data[headerId]?.plainText
|
||||
})
|
||||
return newObject
|
||||
})
|
||||
|
||||
const csv = unparse(data)
|
||||
|
||||
writeFileSync('logs/results.csv', csv)
|
||||
}
|
||||
|
||||
exportResults()
|
Reference in New Issue
Block a user