From fd63f2a22eba7adb1863d7fdee33cfbac6f02c8e Mon Sep 17 00:00:00 2001 From: moonrailgun Date: Wed, 9 Oct 2024 00:21:15 +0800 Subject: [PATCH] feat: add survey webhook --- .../components/survey/SurveyEditForm.tsx | 30 +++++++++++++----- src/server/prisma/schema.prisma | 1 + src/server/trpc/routers/survey.ts | 31 ++++++++++++++++--- 3 files changed, 50 insertions(+), 12 deletions(-) diff --git a/src/client/components/survey/SurveyEditForm.tsx b/src/client/components/survey/SurveyEditForm.tsx index 0f7a3fb..14dc83e 100644 --- a/src/client/components/survey/SurveyEditForm.tsx +++ b/src/client/components/survey/SurveyEditForm.tsx @@ -1,12 +1,7 @@ -import { createFileRoute, useNavigate } from '@tanstack/react-router'; import { useTranslation } from '@i18next-toolkit/react'; import { Button } from '@/components/ui/button'; -import { useEvent, useEventWithLoading } from '@/hooks/useEvent'; -import { useCurrentWorkspaceId } from '@/store/user'; -import { defaultErrorHandler, trpc } from '@/api/trpc'; +import { useEventWithLoading } from '@/hooks/useEvent'; import { Card, CardContent, CardFooter } from '@/components/ui/card'; -import { CommonWrapper } from '@/components/CommonWrapper'; -import { routeAuthBeforeLoad } from '@/utils/route'; import { z } from 'zod'; import { Form, @@ -18,7 +13,7 @@ import { FormMessage, } from '@/components/ui/form'; import { Input } from '@/components/ui/input'; -import { useForm, useFieldArray, useWatch } from 'react-hook-form'; +import { useForm, useFieldArray } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import { generateRandomString } from '@/utils/common'; import { LuArrowDown, LuArrowUp, LuMinus, LuPlus } from 'react-icons/lu'; @@ -49,6 +44,7 @@ const addFormSchema = z.object({ }), feedChannelIds: z.array(z.string()), feedTemplate: z.string(), + webhookUrl: z.string().url(), }); export type SurveyEditFormValues = z.infer; @@ -80,6 +76,7 @@ export const SurveyEditForm: React.FC = React.memo( }, feedChannelIds: [], feedTemplate: '', + webhookUrl: '', }, }); @@ -87,7 +84,7 @@ export const SurveyEditForm: React.FC = React.memo( const [handleSubmit, isLoading] = useEventWithLoading( async (values: SurveyEditFormValues) => { - await props.onSubmit(values); + await props.onSubmit({ ...values }); form.reset(); } ); @@ -297,6 +294,23 @@ export const SurveyEditForm: React.FC = React.memo( )} /> )} + + ( + + {t('Webhook Url')} + + + + + {t('Optional, webhook url to send survey payload')} + + + + )} + /> diff --git a/src/server/prisma/schema.prisma b/src/server/prisma/schema.prisma index 82ab3b6..f5da961 100644 --- a/src/server/prisma/schema.prisma +++ b/src/server/prisma/schema.prisma @@ -495,6 +495,7 @@ model Survey { payload Json @db.Json feedChannelIds String[] @default([]) // send survey result to feed channel feedTemplate String @default("") // send survey result to feed channel + webhookUrl String @default("") createdAt DateTime @default(now()) @db.Timestamptz(6) updatedAt DateTime @updatedAt @db.Timestamptz(6) diff --git a/src/server/trpc/routers/survey.ts b/src/server/trpc/routers/survey.ts index 1716a88..392abaf 100644 --- a/src/server/trpc/routers/survey.ts +++ b/src/server/trpc/routers/survey.ts @@ -22,6 +22,7 @@ import { Prisma } from '@prisma/client'; import { createFeedEvent } from '../../model/feed/event.js'; import { formatString } from '../../utils/template.js'; import { logger } from '../../utils/logger.js'; +import axios from 'axios'; export const surveyRouter = router({ all: workspaceProcedure @@ -154,7 +155,7 @@ export const surveyRouter = router({ const sessionId = hashUuid(workspaceId, surveyId, ip, userAgent!); - await prisma.surveyResult.create({ + const result = await prisma.surveyResult.create({ data: { surveyId, sessionId, @@ -195,7 +196,7 @@ export const surveyRouter = router({ try { const surveyPayload = SurveyPayloadSchema.parse(survey.payload); - createFeedEvent(workspaceId, { + await createFeedEvent(workspaceId, { channelId: channelId, eventName: 'receive', eventContent: formatString(templateStr, { @@ -216,6 +217,17 @@ export const surveyRouter = router({ } }); } + + if (survey && survey.webhookUrl) { + axios + .post(survey.webhookUrl) + .then(() => { + return axios.post(survey.webhookUrl, { + ...result, + }); + }) + .catch((err) => logger.error('[surveySubmitWebhook]', err)); + } }); return 'success'; @@ -233,12 +245,19 @@ export const surveyRouter = router({ payload: SurveyPayloadSchema, feedChannelIds: z.array(z.string()), feedTemplate: z.string(), + webhookUrl: z.string(), }) ) .output(SurveyModelSchema) .mutation(async ({ input }) => { - const { workspaceId, name, payload, feedChannelIds, feedTemplate } = - input; + const { + workspaceId, + name, + payload, + feedChannelIds, + feedTemplate, + webhookUrl, + } = input; const res = await prisma.survey.create({ data: { @@ -247,6 +266,7 @@ export const surveyRouter = router({ payload, feedChannelIds, feedTemplate, + webhookUrl, }, }); @@ -266,6 +286,7 @@ export const surveyRouter = router({ payload: SurveyPayloadSchema.optional(), feedChannelIds: z.array(z.string()).optional(), feedTemplate: z.string().optional(), + webhookUrl: z.string().optional(), }) ) .output(SurveyModelSchema) @@ -277,6 +298,7 @@ export const surveyRouter = router({ payload, feedChannelIds, feedTemplate, + webhookUrl, } = input; const res = await prisma.survey.update({ @@ -289,6 +311,7 @@ export const surveyRouter = router({ payload, feedChannelIds, feedTemplate, + webhookUrl, }, });