From 9657c5927255a80b077d2986e639d026d441b26e Mon Sep 17 00:00:00 2001 From: nitin <142569587+ehconitin@users.noreply.github.com> Date: Mon, 6 Jul 2026 18:48:07 +0530 Subject: [PATCH] Inject functions URL into logic function env (#22583) Review in cubic --- .../logic-function-executor.module.ts | 10 ++++- .../logic-function-executor.service.ts | 41 +++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/packages/twenty-server/src/engine/core-modules/logic-function/logic-function-executor/logic-function-executor.module.ts b/packages/twenty-server/src/engine/core-modules/logic-function/logic-function-executor/logic-function-executor.module.ts index 68fac6e03e..760e42df13 100644 --- a/packages/twenty-server/src/engine/core-modules/logic-function/logic-function-executor/logic-function-executor.module.ts +++ b/packages/twenty-server/src/engine/core-modules/logic-function/logic-function-executor/logic-function-executor.module.ts @@ -2,14 +2,17 @@ import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; import { ApplicationRegistrationVariableEntity } from 'src/engine/core-modules/application/application-registration-variable/application-registration-variable.entity'; +import { ApplicationModule } from 'src/engine/core-modules/application/application.module'; import { EventLogEmitterModule } from 'src/engine/core-modules/event-logs/emit/event-log-emitter.module'; import { EventLogLiveModule } from 'src/engine/core-modules/event-logs/live/event-log-live.module'; import { TokenModule } from 'src/engine/core-modules/auth/token/token.module'; import { BillingModule } from 'src/engine/core-modules/billing/billing.module'; +import { WorkspaceDomainsModule } from 'src/engine/core-modules/domain/workspace-domains/workspace-domains.module'; import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-flag.module'; import { LogicFunctionExecutorService } from 'src/engine/core-modules/logic-function/logic-function-executor/logic-function-executor.service'; import { SecretEncryptionModule } from 'src/engine/core-modules/secret-encryption/secret-encryption.module'; import { ThrottlerModule } from 'src/engine/core-modules/throttler/throttler.module'; +import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; import { SubscriptionsModule } from 'src/engine/subscriptions/subscriptions.module'; import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache.module'; @@ -24,7 +27,12 @@ import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache WorkspaceCacheModule, BillingModule, FeatureFlagModule, - TypeOrmModule.forFeature([ApplicationRegistrationVariableEntity]), + WorkspaceDomainsModule, + ApplicationModule, + TypeOrmModule.forFeature([ + ApplicationRegistrationVariableEntity, + WorkspaceEntity, + ]), ], providers: [LogicFunctionExecutorService], exports: [LogicFunctionExecutorService], diff --git a/packages/twenty-server/src/engine/core-modules/logic-function/logic-function-executor/logic-function-executor.service.ts b/packages/twenty-server/src/engine/core-modules/logic-function/logic-function-executor/logic-function-executor.service.ts index 523767b2e9..73f3a5aea2 100644 --- a/packages/twenty-server/src/engine/core-modules/logic-function/logic-function-executor/logic-function-executor.service.ts +++ b/packages/twenty-server/src/engine/core-modules/logic-function/logic-function-executor/logic-function-executor.service.ts @@ -5,6 +5,7 @@ import { DEFAULT_API_KEY_NAME, DEFAULT_API_URL_NAME, DEFAULT_APP_ACCESS_TOKEN_NAME, + DEFAULT_FUNCTIONS_URL_NAME, } from 'twenty-shared/application'; import { FeatureFlagKey } from 'twenty-shared/types'; import { isDefined } from 'twenty-shared/utils'; @@ -20,6 +21,7 @@ import { import { buildApplicationLogEnvelopes } from 'src/engine/core-modules/event-logs/producers/application-log/build-application-log-envelopes'; import { parseApplicationLogLines } from 'src/engine/core-modules/event-logs/producers/application-log/parse-application-log-lines'; import { ApplicationRegistrationVariableEntity } from 'src/engine/core-modules/application/application-registration-variable/application-registration-variable.entity'; +import { ApplicationService } from 'src/engine/core-modules/application/application.service'; import type { FlatApplicationVariable } from 'src/engine/metadata-modules/flat-application-variable/types/flat-application-variable.type'; import { FlatApplication } from 'src/engine/core-modules/application/types/flat-application.type'; import { EventLogEmitterService } from 'src/engine/core-modules/event-logs/emit/event-log-emitter.service'; @@ -28,6 +30,7 @@ import { ApplicationTokenService } from 'src/engine/core-modules/auth/token/serv import { NO_BILLING_SUBSCRIPTION } from 'src/engine/core-modules/billing/constants/no-billing-subscription.constant'; import { BillingUsageService } from 'src/engine/core-modules/billing/services/billing-usage.service'; import { BillingService } from 'src/engine/core-modules/billing/services/billing.service'; +import { WorkspaceDomainsService } from 'src/engine/core-modules/domain/workspace-domains/services/workspace-domains.service'; import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service'; import { LogicFunctionDriverFactory } from 'src/engine/core-modules/logic-function/logic-function-drivers/logic-function-driver.factory'; import { buildEnvVar } from 'src/engine/core-modules/logic-function/logic-function-executor/utils/build-env-var'; @@ -49,6 +52,7 @@ import { FlatLogicFunction } from 'src/engine/metadata-modules/logic-function/ty import { SubscriptionChannel } from 'src/engine/subscriptions/enums/subscription-channel.enum'; import { SubscriptionService } from 'src/engine/subscriptions/subscription.service'; import { EventLogLiveService } from 'src/engine/core-modules/event-logs/live/event-log-live.service'; +import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; import { WorkspaceCacheService } from 'src/engine/workspace-cache/services/workspace-cache.service'; import { WorkspaceEventEmitter } from 'src/engine/workspace-event-emitter/workspace-event-emitter'; import { cleanServerUrl } from 'src/utils/clean-server-url'; @@ -86,6 +90,10 @@ export class LogicFunctionExecutorService { private readonly billingService: BillingService, private readonly billingUsageService: BillingUsageService, private readonly featureFlagService: FeatureFlagService, + private readonly workspaceDomainsService: WorkspaceDomainsService, + private readonly applicationService: ApplicationService, + @InjectRepository(WorkspaceEntity) + private readonly workspaceRepository: Repository, @InjectRepository(ApplicationRegistrationVariableEntity) private readonly applicationRegistrationVariableRepository: Repository, ) {} @@ -321,6 +329,10 @@ export class LogicFunctionExecutorService { }); const baseUrl = cleanServerUrl(this.twentyConfigService.get('SERVER_URL')); + const functionsBaseUrl = await this.buildFunctionsBaseUrl({ + workspaceId, + flatApplication, + }); const serverVariables = await this.buildServerVariableEnvMap( flatApplication.applicationRegistrationId, @@ -334,12 +346,41 @@ export class LogicFunctionExecutorService { [DEFAULT_API_URL_NAME]: baseUrl ?? '', [DEFAULT_APP_ACCESS_TOKEN_NAME]: applicationAccessToken.token, [DEFAULT_API_KEY_NAME]: applicationAccessToken.token, + [DEFAULT_FUNCTIONS_URL_NAME]: functionsBaseUrl ?? '', APPLICATION_ID: flatApplication.id, ...serverVariables, ...workspaceVariables, }; } + private async buildFunctionsBaseUrl({ + workspaceId, + flatApplication, + }: { + workspaceId: string; + flatApplication: FlatApplication; + }): Promise { + const workspace = await this.workspaceRepository.findOne({ + where: { id: workspaceId }, + select: { subdomain: true }, + }); + + if (!isDefined(workspace)) { + return undefined; + } + + const primaryPublicDomain = + await this.applicationService.findPrimaryPublicDomainName({ + applicationId: flatApplication.id, + workspaceId, + }); + + return this.workspaceDomainsService.buildPublicFunctionBaseUrl({ + workspace, + primaryPublicDomain, + }); + } + private async buildServerVariableEnvMap( applicationRegistrationId: string | null, ): Promise> {