diff --git a/apps/feature-flags/package.json b/apps/feature-flags/package.json index fec1ba99..c7451460 100644 --- a/apps/feature-flags/package.json +++ b/apps/feature-flags/package.json @@ -34,7 +34,7 @@ "@basestack/ui": "*", "@basestack/utils": "*", "@emotion/is-prop-valid": "^1.3.1", - "@floating-ui/react": "^0.26.24", + "@floating-ui/react": "^0.26.25", "@hookform/resolvers": "^3.9.0", "@monaco-editor/react": "^4.6.0", "@next-auth/prisma-adapter": "^1.0.4", diff --git a/apps/forms/.env.example b/apps/forms/.env.example index a3d1099e..58d31db5 100644 --- a/apps/forms/.env.example +++ b/apps/forms/.env.example @@ -35,9 +35,8 @@ AUTH0_DOMAIN= # V2 - Trigger TRIGGER_PROJECT_ID= -TRIGGER_API_KEY= +TRIGGER_SECRET_KEY= TRIGGER_API_URL= -NEXT_PUBLIC_TRIGGER_PUBLIC_API_KEY= # V3 - Trigger TRIGGER_PROJECT_ID= diff --git a/apps/forms/libs/trigger/index.ts b/apps/forms/libs/trigger/index.ts deleted file mode 100644 index 9bfbf931..00000000 --- a/apps/forms/libs/trigger/index.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { TriggerClient } from "@trigger.dev/sdk"; - -export enum TriggerEventName { - SEND_EMAIL = "send.email.event", - SEND_DATA_TO_EXTERNAL_WEBHOOK = "send.data.to.external.webhook.event", - CHECK_DATA_FOR_SPAM = "check.data.spam.event", -} - -export const triggerClient = new TriggerClient({ - id: process.env.TRIGGER_PROJECT_ID!, - apiKey: process.env.TRIGGER_API_KEY, - apiUrl: process.env.TRIGGER_API_URL, -}); diff --git a/apps/forms/libs/trigger/jobs/ai/spam.tsx b/apps/forms/libs/trigger/jobs/ai/spam.tsx index a5208d13..abd426e2 100644 --- a/apps/forms/libs/trigger/jobs/ai/spam.tsx +++ b/apps/forms/libs/trigger/jobs/ai/spam.tsx @@ -1,62 +1,56 @@ -import { eventTrigger } from "@trigger.dev/sdk"; -import { triggerClient, TriggerEventName } from "libs/trigger"; +import { logger, task } from "@trigger.dev/sdk/v3"; // Prisma import prisma from "libs/prisma"; // AI -import { TextGenerationModel, cfAiClient, instructions } from "libs/cf/ai"; -// Utils -import { z } from "zod"; +import { cfAiClient, instructions, TextGenerationModel } from "libs/cf/ai"; -triggerClient.defineJob({ +export interface CheckForSpamPayload { + submissionId: string; + data: any; +} + +export const checkDataForSpamTask = task({ id: "check-data-for-spam", - name: "Check data for spam", - version: "1.0.0", - trigger: eventTrigger({ - name: TriggerEventName.CHECK_DATA_FOR_SPAM, - schema: z.object({ - submissionId: z.string(), - data: z.any(), - }), - }), - run: async (payload, io, ctx) => { - await io.logger.info( + machine: { + preset: "small-1x", + }, + init: async (payload) => { + logger.info( `Preparing to check data for spam: ${JSON.stringify(payload.data)} with submission ID: ${payload.submissionId}`, ); + }, + run: async (payload: CheckForSpamPayload) => { + const res = await cfAiClient({ + model: TextGenerationModel.LLAMA_3_8B_INSTRUCT, + messages: instructions.checkSpam(JSON.stringify(payload.data)), + }); - await io.runTask( - "check-data-for-spam", - async () => { - const res = await cfAiClient({ - model: TextGenerationModel.LLAMA_3_8B_INSTRUCT, - messages: instructions.checkSpam(JSON.stringify(payload.data)), - }); - - if (res.success) { - await io.logger.info( - `Data successfully checked for: ${res.result.response}`, - ); + if (res.success) { + logger.info(`Data successfully checked for: ${res.result.response}`); - const isSpam = JSON.parse(res.result.response).isSpam ?? false; + const isSpam = JSON.parse(res.result.response).isSpam ?? false; - if (isSpam) { - await io.logger.info( - `The data is spam. Submission ID: ${payload.submissionId}. Preparing to update the form Submission status on the DB.`, - ); + if (isSpam) { + logger.info( + `The data is spam. Submission ID: ${payload.submissionId}. Preparing to update the form Submission status on the DB.`, + ); - await prisma.submission.update({ - where: { - id: payload.submissionId, - }, - data: { - isSpam: true, - }, - }); - } - } - }, - { name: "Check data for Spam" }, - ); + return prisma.submission.update({ + where: { + id: payload.submissionId, + }, + data: { + isSpam: true, + }, + }); + } - await io.logger.info("✨ Data successfully checked ✨"); + return { + isSpam, + }; + } + }, + onSuccess: async () => { + logger.info("✨ Data successfully checked ✨"); }, }); diff --git a/apps/forms/libs/trigger/jobs/index.ts b/apps/forms/libs/trigger/jobs/index.ts index 5a95f334..3778c8fd 100644 --- a/apps/forms/libs/trigger/jobs/index.ts +++ b/apps/forms/libs/trigger/jobs/index.ts @@ -1,9 +1,9 @@ -// Notification Jobs +// AI +export * from "./ai/spam"; +// Notification export * from "./notification/email"; -// Webhook Jobs +// Webhook export * from "./webhook/external"; -// AI Jobs -export * from "./ai/spam"; -// Subscription Jobs -export * from "./subscription/update"; +// Subscriptions export * from "./subscription/check"; +export * from "./subscription/update"; diff --git a/apps/forms/libs/trigger/jobs/notification/email.tsx b/apps/forms/libs/trigger/jobs/notification/email.tsx index 9716080e..bbfdee08 100644 --- a/apps/forms/libs/trigger/jobs/notification/email.tsx +++ b/apps/forms/libs/trigger/jobs/notification/email.tsx @@ -1,62 +1,53 @@ import React from "react"; -import { eventTrigger } from "@trigger.dev/sdk"; -import { triggerClient, TriggerEventName } from "libs/trigger"; +import { task, logger } from "@trigger.dev/sdk/v3"; // Email import { sendEmail, NewSubmissionEmailTemplate } from "@basestack/emails"; import { render } from "@react-email/render"; -// Utils -import { z } from "zod"; + +export interface SendEmailPayload { + to: string[]; + subject: string; + template: string; + props?: any; +} const template: { [key: string]: React.ElementType } = { "new-submission": NewSubmissionEmailTemplate, }; -triggerClient.defineJob({ +export const sendEmailTask = task({ id: "send-email", - name: "Send email", - version: "1.0.0", - trigger: eventTrigger({ - name: TriggerEventName.SEND_EMAIL, - schema: z.object({ - to: z.array(z.string().email()), - subject: z.string(), - template: z.string(), - props: z.any().optional(), - }), - }), - run: async (payload, io) => { - await io.logger.info( + machine: { + preset: "small-1x", + }, + init: async (payload) => { + logger.info( `Preparing to send email to ${payload.to} with subject: ${payload.subject}`, ); - await io.logger.info( + logger.info( `Email with the template ${payload.template} with props: ${payload.props}`, ); - - await io.runTask( - "send-email", - async () => { - const Template = template[payload.template]; - - await Promise.all( - payload.to.map(async (email) => { - const html = await render(