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)
---
.../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> {