From 2a9b34104d3ae7d80a82e1b48b4ec6cec014002e Mon Sep 17 00:00:00 2001 From: Matti Nannt Date: Tue, 30 Jan 2024 12:08:40 +0100 Subject: [PATCH] feat: add support for customer-io formbricks users sync (#1976) --- .env.example | 4 ++++ packages/lib/customerio.ts | 27 +++++++++++++++++++++++++++ packages/lib/env.mjs | 7 ++++++- packages/lib/user/service.ts | 4 ++++ turbo.json | 2 ++ 5 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 packages/lib/customerio.ts diff --git a/.env.example b/.env.example index cde8a0225d..161b9bd9bc 100644 --- a/.env.example +++ b/.env.example @@ -137,3 +137,7 @@ ENTERPRISE_LICENSE_KEY= # set to 1 to skip onboarding for new users # ONBOARDING_DISABLED=1 + +# Send new users to customer.io +# CUSTOMER_IO_API_KEY= +# CUSTOMER_IO_SITE_ID= diff --git a/packages/lib/customerio.ts b/packages/lib/customerio.ts new file mode 100644 index 0000000000..74f0f8bed6 --- /dev/null +++ b/packages/lib/customerio.ts @@ -0,0 +1,27 @@ +import { TUser } from "@formbricks/types/user"; + +import { env } from "./env.mjs"; + +export const createCustomerIoCustomer = async (user: TUser) => { + if (!env.CUSTOMER_IO_SITE_ID || !env.CUSTOMER_IO_API_KEY) { + return; + } + try { + const auth = Buffer.from(`${env.CUSTOMER_IO_SITE_ID}:${env.CUSTOMER_IO_API_KEY}`).toString("base64"); + const res = await fetch(`https://track-eu.customer.io/api/v1/customers/${user.id}`, { + method: "PUT", + headers: { + Authorization: `Basic ${auth}`, + }, + body: JSON.stringify({ + id: user.id, + email: user.email, + }), + }); + if (res.status !== 200) { + console.log("Error sending user to CustomerIO:", await res.text()); + } + } catch (error) { + console.log("error sending user to CustomerIO:", error); + } +}; diff --git a/packages/lib/env.mjs b/packages/lib/env.mjs index 8e18b90199..7a7560a492 100644 --- a/packages/lib/env.mjs +++ b/packages/lib/env.mjs @@ -7,6 +7,9 @@ export const env = createEnv({ * Will throw if you access these variables on the client. */ server: { + CUSTOMER_IO_API_KEY: z.string().optional(), + CUSTOMER_IO_SITE_ID: z.string().optional(), + NEXT_PUBLIC_POSTHOG_API_HOST: z.string().optional(), WEBAPP_URL: z.string().url().optional(), DATABASE_URL: z.string().url(), ENCRYPTION_KEY: z.string().length(64).or(z.string().length(32)), @@ -96,6 +99,8 @@ export const env = createEnv({ * 💡 You'll get type errors if not all variables from `server` & `client` are included here. */ runtimeEnv: { + CUSTOMER_IO_API_KEY: process.env.CUSTOMER_IO_API_KEY, + CUSTOMER_IO_SITE_ID: process.env.CUSTOMER_IO_SITE_ID, WEBAPP_URL: process.env.WEBAPP_URL, DATABASE_URL: process.env.DATABASE_URL, ENCRYPTION_KEY: process.env.ENCRYPTION_KEY, @@ -146,7 +151,7 @@ export const env = createEnv({ AZUREAD_CLIENT_ID: process.env.AZUREAD_CLIENT_ID, AZUREAD_CLIENT_SECRET: process.env.AZUREAD_CLIENT_SECRET, AZUREAD_TENANT_ID: process.env.AZUREAD_TENANT_ID, - AIR_TABLE_CLIENT_ID: process.env.AIR_TABLE_CLIENT_ID, + AIRTABLE_CLIENT_ID: process.env.AIRTABLE_CLIENT_ID, DEFAULT_TEAM_ID: process.env.DEFAULT_TEAM_ID, DEFAULT_TEAM_ROLE: process.env.DEFAULT_TEAM_ROLE, ONBOARDING_DISABLED: process.env.ONBOARDING_DISABLED, diff --git a/packages/lib/user/service.ts b/packages/lib/user/service.ts index 082111dda2..077d59fa60 100644 --- a/packages/lib/user/service.ts +++ b/packages/lib/user/service.ts @@ -11,6 +11,7 @@ import { TMembership } from "@formbricks/types/memberships"; import { TUser, TUserCreateInput, TUserUpdateInput, ZUser, ZUserUpdateInput } from "@formbricks/types/user"; import { SERVICES_REVALIDATION_INTERVAL } from "../constants"; +import { createCustomerIoCustomer } from "../customerio"; import { updateMembership } from "../membership/service"; import { deleteTeam } from "../team/service"; import { formatDateFields } from "../utils/datetime"; @@ -171,6 +172,9 @@ export const createUser = async (data: TUserCreateInput): Promise => { id: user.id, }); + // send new user customer.io to customer.io + createCustomerIoCustomer(user); + return user; }; diff --git a/turbo.json b/turbo.json index 552332af2c..fb39a16abc 100644 --- a/turbo.json +++ b/turbo.json @@ -66,6 +66,8 @@ "DEFAULT_TEAM_ROLE", "ONBOARDING_DISABLED", "CRON_SECRET", + "CUSTOMER_IO_API_KEY", + "CUSTOMER_IO_SITE_ID", "DEBUG", "EMAIL_VERIFICATION_DISABLED", "ENCRYPTION_KEY",