From 90861f880939ca4ae2b7a8611908c1e48705ea85 Mon Sep 17 00:00:00 2001 From: Muhsin Keloth Date: Fri, 17 Jul 2026 14:09:36 +0400 Subject: [PATCH] feat(whatsapp): gate embedded signup inbox creation (#15046) WhatsApp inbox creation now shows Embedded Signup for Chatwoot Cloud accounts only when the new `whatsapp_embedded_signup_inbox_creation` feature flag is enabled. Cloud accounts without the flag go directly to manual WhatsApp Cloud API setup, while self-hosted installations with a configured WhatsApp App ID retain their existing Embedded Signup flow. --------- Co-authored-by: Muhsin <12408980+muhsin-k@users.noreply.github.com> --- app/javascript/dashboard/featureFlags.js | 2 + .../dashboard/i18n/locale/en/inboxMgmt.json | 2 - .../inbox-setup/useChannelConfig.js | 5 ++- .../inbox-setup/InboxChannelsDialog.spec.js | 2 +- .../settings/inbox/channels/Whatsapp.vue | 35 +++++++-------- .../inbox/channels/WhatsappEmbeddedSignup.vue | 45 +------------------ config/features.yml | 4 ++ spec/models/account_spec.rb | 10 ++++- 8 files changed, 37 insertions(+), 68 deletions(-) diff --git a/app/javascript/dashboard/featureFlags.js b/app/javascript/dashboard/featureFlags.js index eb8e1b7bd..e707284cb 100644 --- a/app/javascript/dashboard/featureFlags.js +++ b/app/javascript/dashboard/featureFlags.js @@ -7,6 +7,8 @@ export const FEATURE_FLAGS = { AUTOMATIONS: 'automations', CAMPAIGNS: 'campaigns', WHATSAPP_CAMPAIGNS: 'whatsapp_campaign', + WHATSAPP_EMBEDDED_SIGNUP_INBOX_CREATION: + 'whatsapp_embedded_signup_inbox_creation', WHATSAPP_MANUAL_TRANSFER: 'whatsapp_manual_transfer', WHATSAPP_RECONFIGURE: 'whatsapp_reconfigure', CANNED_RESPONSES: 'canned_responses', diff --git a/app/javascript/dashboard/i18n/locale/en/inboxMgmt.json b/app/javascript/dashboard/i18n/locale/en/inboxMgmt.json index 365ddff1d..48f7ab215 100644 --- a/app/javascript/dashboard/i18n/locale/en/inboxMgmt.json +++ b/app/javascript/dashboard/i18n/locale/en/inboxMgmt.json @@ -322,8 +322,6 @@ "SUCCESS_FALLBACK": "WhatsApp Business Account has been successfully configured", "MANUAL_FALLBACK": "If your number is already connected to the WhatsApp Business Platform (API), or if you’re a tech provider onboarding your own number, please use the {link} flow", "MANUAL_LINK_TEXT": "manual setup flow", - "RESTRICTED_WARNING": "WhatsApp embedded signup is temporarily unavailable due to current Meta platform restrictions. We’ll restore support as soon as possible.", - "STATUS_LINK": "View status update", "CALLING_ENABLE_FAILED": "Your WhatsApp inbox is ready, but voice calling couldn't be turned on — this number isn't enrolled in the WhatsApp Business Calling API yet. Reach out to Meta or your WhatsApp Business Solution Provider to onboard it, then turn calling on from the inbox's Calls settings." }, "API": { diff --git a/app/javascript/dashboard/routes/dashboard/onboarding/inbox-setup/useChannelConfig.js b/app/javascript/dashboard/routes/dashboard/onboarding/inbox-setup/useChannelConfig.js index 5d50cad29..36a78dcbe 100644 --- a/app/javascript/dashboard/routes/dashboard/onboarding/inbox-setup/useChannelConfig.js +++ b/app/javascript/dashboard/routes/dashboard/onboarding/inbox-setup/useChannelConfig.js @@ -17,7 +17,10 @@ export function useChannelConfig() { // WhatsApp is onboarded only via Meta embedded signup, which needs both the // app id (not the 'none' sentinel) and the signup configuration id. whatsapp: () => - !isOnChatwootCloud.value && + (!isOnChatwootCloud.value || + isCloudFeatureEnabled( + FEATURE_FLAGS.WHATSAPP_EMBEDDED_SIGNUP_INBOX_CREATION + )) && Boolean(installationConfig.whatsappAppId) && installationConfig.whatsappAppId !== 'none' && Boolean(installationConfig.whatsappConfigurationId), diff --git a/app/javascript/dashboard/routes/dashboard/onboarding/specs/inbox-setup/InboxChannelsDialog.spec.js b/app/javascript/dashboard/routes/dashboard/onboarding/specs/inbox-setup/InboxChannelsDialog.spec.js index af29ba5f4..5331445ff 100644 --- a/app/javascript/dashboard/routes/dashboard/onboarding/specs/inbox-setup/InboxChannelsDialog.spec.js +++ b/app/javascript/dashboard/routes/dashboard/onboarding/specs/inbox-setup/InboxChannelsDialog.spec.js @@ -7,7 +7,7 @@ vi.mock('dashboard/composables/store', () => ({ useMapGetter: () => ({ value: {} }), })); vi.mock('dashboard/composables/useAccount', () => ({ - useAccount: () => ({ isCloudFeatureEnabled: () => false }), + useAccount: () => ({ isCloudFeatureEnabled: () => true }), })); vi.mock('../../inbox-setup/useChannelConnect', () => ({ useChannelConnect: () => ({ diff --git a/app/javascript/dashboard/routes/dashboard/settings/inbox/channels/Whatsapp.vue b/app/javascript/dashboard/routes/dashboard/settings/inbox/channels/Whatsapp.vue index 3e822f796..b4e0c58af 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/inbox/channels/Whatsapp.vue +++ b/app/javascript/dashboard/routes/dashboard/settings/inbox/channels/Whatsapp.vue @@ -8,12 +8,12 @@ import CloudWhatsapp from './CloudWhatsapp.vue'; import WhatsappEmbeddedSignup from './WhatsappEmbeddedSignup.vue'; import ChannelSelector from 'dashboard/components/ChannelSelector.vue'; import { useAccount } from 'dashboard/composables/useAccount'; -import { META_RESTRICTION_STATUS_URL } from 'dashboard/constants/globals'; +import { FEATURE_FLAGS } from 'dashboard/featureFlags'; const route = useRoute(); const router = useRouter(); const { t } = useI18n(); -const { isOnChatwootCloud } = useAccount(); +const { isCloudFeatureEnabled, isOnChatwootCloud } = useAccount(); const PROVIDER_TYPES = { WHATSAPP: 'whatsapp', @@ -24,10 +24,6 @@ const PROVIDER_TYPES = { THREE_SIXTY_DIALOG: '360dialog', }; -const isWhatsappEmbeddedSignupRestricted = computed(() => { - return isOnChatwootCloud.value; -}); - const hasWhatsappAppId = computed(() => { return ( window.chatwootConfig?.whatsappAppId && @@ -41,6 +37,17 @@ const showProviderSelection = computed(() => !selectedProvider.value); const showConfiguration = computed(() => Boolean(selectedProvider.value)); +const shouldShowWhatsappEmbeddedSignup = computed(() => { + return ( + selectedProvider.value === PROVIDER_TYPES.WHATSAPP && + hasWhatsappAppId.value && + (!isOnChatwootCloud.value || + isCloudFeatureEnabled( + FEATURE_FLAGS.WHATSAPP_EMBEDDED_SIGNUP_INBOX_CREATION + )) + ); +}); + const availableProviders = computed(() => [ { key: PROVIDER_TYPES.WHATSAPP, @@ -67,7 +74,8 @@ const selectProvider = providerValue => { const shouldShowCloudWhatsapp = provider => { return ( provider === PROVIDER_TYPES.WHATSAPP_MANUAL || - (provider === PROVIDER_TYPES.WHATSAPP && !hasWhatsappAppId.value) + (provider === PROVIDER_TYPES.WHATSAPP && + !shouldShowWhatsappEmbeddedSignup.value) ); }; @@ -102,17 +110,8 @@ const handleManualLinkClick = () => {
- -
- +
+
diff --git a/app/javascript/dashboard/routes/dashboard/settings/inbox/channels/WhatsappEmbeddedSignup.vue b/app/javascript/dashboard/routes/dashboard/settings/inbox/channels/WhatsappEmbeddedSignup.vue index 0972e4b95..3dda0ad8e 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/inbox/channels/WhatsappEmbeddedSignup.vue +++ b/app/javascript/dashboard/routes/dashboard/settings/inbox/channels/WhatsappEmbeddedSignup.vue @@ -7,7 +7,6 @@ import { useAlert } from 'dashboard/composables'; import { useWhatsappEmbeddedSignup } from 'dashboard/composables/useWhatsappEmbeddedSignup'; import Icon from 'next/icon/Icon.vue'; import NextButton from 'next/button/Button.vue'; -import Banner from 'next/banner/Banner.vue'; import LoadingState from 'dashboard/components/widgets/LoadingState.vue'; import InboxesAPI from 'dashboard/api/inboxes'; import { parseAPIErrorResponse } from 'dashboard/store/utils/api'; @@ -18,22 +17,6 @@ const props = defineProps({ type: Boolean, default: false, }, - isDisabled: { - type: Boolean, - default: false, - }, - showRestrictionAlert: { - type: Boolean, - default: false, - }, - restrictionStatusUrl: { - type: String, - default: '', - }, - restrictionWarningText: { - type: String, - default: '', - }, }); const store = useStore(); @@ -98,8 +81,6 @@ const handleSignupSuccess = async inboxData => { }; const launchEmbeddedSignup = async () => { - if (props.isDisabled) return; - let credentials; try { credentials = await runEmbeddedSignup(); @@ -193,33 +174,9 @@ const launchEmbeddedSignup = async () => {
- -
- - - {{ - restrictionWarningText || - $t('INBOX_MGMT.ADD.WHATSAPP.EMBEDDED_SIGNUP.RESTRICTED_WARNING') - }} - - {{ $t('INBOX_MGMT.ADD.WHATSAPP.EMBEDDED_SIGNUP.STATUS_LINK') }} - - -
-
-