From 608f789fbd26a6f9ba356e5c0080b4c29233737e Mon Sep 17 00:00:00 2001 From: Aubin Date: Wed, 30 Oct 2024 09:27:32 +0100 Subject: [PATCH 1/7] feat: add a worker and start it --- .../src/connectors/zendesk/temporal/worker.ts | 39 +++++++++++++++++++ connectors/src/start.ts | 4 ++ connectors/src/start_worker.ts | 5 +-- .../components/ConnectorPermissionsModal.tsx | 6 ++- 4 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 connectors/src/connectors/zendesk/temporal/worker.ts diff --git a/connectors/src/connectors/zendesk/temporal/worker.ts b/connectors/src/connectors/zendesk/temporal/worker.ts new file mode 100644 index 000000000000..b814cae42d22 --- /dev/null +++ b/connectors/src/connectors/zendesk/temporal/worker.ts @@ -0,0 +1,39 @@ +import type { Context } from "@temporalio/activity"; +import { Worker } from "@temporalio/worker"; +import TsconfigPathsPlugin from "tsconfig-paths-webpack-plugin"; + +import { getTemporalWorkerConnection } from "@connectors/lib/temporal"; +import { ActivityInboundLogInterceptor } from "@connectors/lib/temporal_monitoring"; +import logger from "@connectors/logger/logger"; + +import * as activities from "./activities"; +import { QUEUE_NAME } from "./config"; + +export async function runZendeskWorker() { + const { connection, namespace } = await getTemporalWorkerConnection(); + const worker = await Worker.create({ + workflowsPath: require.resolve("./workflows"), + activities, + taskQueue: QUEUE_NAME, + connection, + reuseV8Context: true, + namespace, + maxConcurrentActivityTaskExecutions: 16, + interceptors: { + activityInbound: [ + (ctx: Context) => { + return new ActivityInboundLogInterceptor(ctx, logger); + }, + ], + }, + bundlerOptions: { + webpackConfigHook: (config) => { + const plugins = config.resolve?.plugins ?? []; + config.resolve!.plugins = [...plugins, new TsconfigPathsPlugin({})]; + return config; + }, + }, + }); + + await worker.run(); +} diff --git a/connectors/src/start.ts b/connectors/src/start.ts index 6295292bf07c..af0c94e71b9e 100644 --- a/connectors/src/start.ts +++ b/connectors/src/start.ts @@ -11,6 +11,7 @@ import { runIntercomWorker } from "./connectors/intercom/temporal/worker"; import { runNotionWorker } from "./connectors/notion/temporal/worker"; import { runSlackWorker } from "./connectors/slack/temporal/worker"; import { runWebCrawlerWorker } from "./connectors/webcrawler/temporal/worker"; +import { runZendeskWorker } from "./connectors/zendesk/temporal/worker"; import { errorFromAny } from "./lib/error"; import logger from "./logger/logger"; @@ -44,6 +45,9 @@ runGoogleWorkers().catch((err) => runIntercomWorker().catch((err) => logger.error(errorFromAny(err), "Error running intercom worker") ); +runZendeskWorker().catch((err) => + logger.error(errorFromAny(err), "Error running zendesk worker") +); runWebCrawlerWorker().catch((err) => logger.error(errorFromAny(err), "Error running webcrawler worker") ); diff --git a/connectors/src/start_worker.ts b/connectors/src/start_worker.ts index ad7da4682316..944cb4075d54 100644 --- a/connectors/src/start_worker.ts +++ b/connectors/src/start_worker.ts @@ -16,6 +16,7 @@ import { runNotionWorker, } from "./connectors/notion/temporal/worker"; import { runSlackWorker } from "./connectors/slack/temporal/worker"; +import { runZendeskWorker } from "./connectors/zendesk/temporal/worker"; import { errorFromAny } from "./lib/error"; import logger from "./logger/logger"; @@ -34,9 +35,7 @@ const workerFunctions: Record Promise> = { slack: runSlackWorker, webcrawler: runWebCrawlerWorker, snowflake: runSnowflakeWorker, - zendesk: async () => { - logger.info("Zendesk worker not implemented yet."); - }, + zendesk: runZendeskWorker, }; const ALL_WORKERS = Object.keys(workerFunctions) as WorkerType[]; diff --git a/front/components/ConnectorPermissionsModal.tsx b/front/components/ConnectorPermissionsModal.tsx index 2965a57ee0cb..3fc3ad8b24d6 100644 --- a/front/components/ConnectorPermissionsModal.tsx +++ b/front/components/ConnectorPermissionsModal.tsx @@ -51,6 +51,7 @@ const PERMISSIONS_EDITABLE_CONNECTOR_TYPES: Set = new Set([ "microsoft", "intercom", "snowflake", + "zendesk", ]); const CONNECTOR_TYPE_TO_PERMISSIONS: Record< @@ -75,7 +76,10 @@ const CONNECTOR_TYPE_TO_PERMISSIONS: Record< }, notion: undefined, github: undefined, - zendesk: undefined, + zendesk: { + selected: "read", + unselected: "none", + }, intercom: { selected: "read", unselected: "none", From 63f351fcde7182c1295b7f4836edbef083bf8842 Mon Sep 17 00:00:00 2001 From: Aubin Date: Wed, 30 Oct 2024 09:53:35 +0100 Subject: [PATCH 2/7] set the workflow version to 0 --- connectors/src/connectors/zendesk/temporal/config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectors/src/connectors/zendesk/temporal/config.ts b/connectors/src/connectors/zendesk/temporal/config.ts index f007f77eb582..51ed3cccdf89 100644 --- a/connectors/src/connectors/zendesk/temporal/config.ts +++ b/connectors/src/connectors/zendesk/temporal/config.ts @@ -1,3 +1,3 @@ -export const WORKFLOW_VERSION = 3; +export const WORKFLOW_VERSION = 0; export const QUEUE_NAME = `zendesk-queue-v${WORKFLOW_VERSION}`; export const INTERVAL_BETWEEN_SYNCS_MS = 60_000; // 1 minute From 4df56d51676df945180a996d66a169f37aa949bd Mon Sep 17 00:00:00 2001 From: Aubin Date: Wed, 30 Oct 2024 10:06:50 +0100 Subject: [PATCH 3/7] fix: fix imports in the workflow (activities were imported) --- connectors/src/connectors/zendesk/temporal/workflows.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/connectors/src/connectors/zendesk/temporal/workflows.ts b/connectors/src/connectors/zendesk/temporal/workflows.ts index af619ecaaed0..ead8eda9eb1a 100644 --- a/connectors/src/connectors/zendesk/temporal/workflows.ts +++ b/connectors/src/connectors/zendesk/temporal/workflows.ts @@ -9,17 +9,16 @@ import { } from "@temporalio/workflow"; import type * as activities from "@connectors/connectors/zendesk/temporal/activities"; -import { syncZendeskTicketsActivity } from "@connectors/connectors/zendesk/temporal/activities"; import { INTERVAL_BETWEEN_SYNCS_MS } from "@connectors/connectors/zendesk/temporal/config"; import type { ZendeskUpdateSignal } from "@connectors/connectors/zendesk/temporal/signals"; - -import { zendeskUpdatesSignal } from "./signals"; +import { zendeskUpdatesSignal } from "@connectors/connectors/zendesk/temporal/signals"; const { getZendeskCategoriesActivity, syncZendeskBrandActivity, syncZendeskCategoryActivity, syncZendeskArticlesActivity, + syncZendeskTicketsActivity, } = proxyActivities({ startToCloseTimeout: "5 minutes", }); From eb91641a82516df130d8bfd8f8097e2ca3907239 Mon Sep 17 00:00:00 2001 From: Aubin Date: Wed, 30 Oct 2024 13:51:13 +0100 Subject: [PATCH 4/7] feat: remove the sleep as this workflow is a cron one --- connectors/src/connectors/zendesk/temporal/workflows.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/connectors/src/connectors/zendesk/temporal/workflows.ts b/connectors/src/connectors/zendesk/temporal/workflows.ts index ead8eda9eb1a..d207c84e81cd 100644 --- a/connectors/src/connectors/zendesk/temporal/workflows.ts +++ b/connectors/src/connectors/zendesk/temporal/workflows.ts @@ -4,12 +4,10 @@ import { executeChild, proxyActivities, setHandler, - sleep, workflowInfo, } from "@temporalio/workflow"; import type * as activities from "@connectors/connectors/zendesk/temporal/activities"; -import { INTERVAL_BETWEEN_SYNCS_MS } from "@connectors/connectors/zendesk/temporal/config"; import type { ZendeskUpdateSignal } from "@connectors/connectors/zendesk/temporal/signals"; import { zendeskUpdatesSignal } from "@connectors/connectors/zendesk/temporal/signals"; @@ -181,8 +179,6 @@ export async function zendeskSyncWorkflow({ // run cleanup here if needed await saveZendeskConnectorSuccessSync({ connectorId }); - - await sleep(INTERVAL_BETWEEN_SYNCS_MS); } /** From 1c5ab9fbe899d0a65b9642c095ec48020745d4d7 Mon Sep 17 00:00:00 2001 From: Aubin Date: Wed, 30 Oct 2024 13:57:50 +0100 Subject: [PATCH 5/7] fix: copy paste the assertNever function since the types module cannot be imported in a workflow --- connectors/src/connectors/zendesk/temporal/workflows.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/connectors/src/connectors/zendesk/temporal/workflows.ts b/connectors/src/connectors/zendesk/temporal/workflows.ts index d207c84e81cd..1bff48e8f920 100644 --- a/connectors/src/connectors/zendesk/temporal/workflows.ts +++ b/connectors/src/connectors/zendesk/temporal/workflows.ts @@ -1,5 +1,4 @@ import type { ModelId } from "@dust-tt/types"; -import { assertNever } from "@dust-tt/types"; import { executeChild, proxyActivities, @@ -30,6 +29,14 @@ const { startToCloseTimeout: "1 minute", }); +function assertNever(x: never): never { + throw new Error( + `${ + typeof x === "object" ? JSON.stringify(x) : x + } is not of type never. This should never happen.` + ); +} + /** * Sync Workflow for Zendesk. * This workflow is responsible for syncing all the help centers and tickets for a given connector. From 8cc5ab7f422c7e1ff382cc729baf9ce11fe0e5e6 Mon Sep 17 00:00:00 2001 From: Aubin Date: Wed, 30 Oct 2024 15:57:46 +0100 Subject: [PATCH 6/7] chore: remove an unused config parameter --- connectors/src/connectors/zendesk/temporal/config.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/connectors/src/connectors/zendesk/temporal/config.ts b/connectors/src/connectors/zendesk/temporal/config.ts index 51ed3cccdf89..04dab6d2eca6 100644 --- a/connectors/src/connectors/zendesk/temporal/config.ts +++ b/connectors/src/connectors/zendesk/temporal/config.ts @@ -1,3 +1,2 @@ export const WORKFLOW_VERSION = 0; export const QUEUE_NAME = `zendesk-queue-v${WORKFLOW_VERSION}`; -export const INTERVAL_BETWEEN_SYNCS_MS = 60_000; // 1 minute From a94b1382aa1ffcbce33c177183808cef2432d9ab Mon Sep 17 00:00:00 2001 From: Aubin Date: Wed, 30 Oct 2024 17:48:08 +0100 Subject: [PATCH 7/7] fix: use temporal's assertNever instead of a custom one --- .../src/connectors/zendesk/temporal/workflows.ts | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/connectors/src/connectors/zendesk/temporal/workflows.ts b/connectors/src/connectors/zendesk/temporal/workflows.ts index 1bff48e8f920..55a24b7ac90c 100644 --- a/connectors/src/connectors/zendesk/temporal/workflows.ts +++ b/connectors/src/connectors/zendesk/temporal/workflows.ts @@ -1,4 +1,5 @@ import type { ModelId } from "@dust-tt/types"; +import { assertNever } from "@temporalio/common/lib/type-helpers"; import { executeChild, proxyActivities, @@ -29,14 +30,6 @@ const { startToCloseTimeout: "1 minute", }); -function assertNever(x: never): never { - throw new Error( - `${ - typeof x === "object" ? JSON.stringify(x) : x - } is not of type never. This should never happen.` - ); -} - /** * Sync Workflow for Zendesk. * This workflow is responsible for syncing all the help centers and tickets for a given connector. @@ -85,7 +78,10 @@ export async function zendeskSyncWorkflow({ break; } default: - assertNever(signal.type); + assertNever( + `Unexpected signal type ${signal.type} received within Zendesk sync workflow.`, + signal.type + ); } }); });